maxlinux2000 Posted August 26, 2019 Posted August 26, 2019 Hello everyone I need to record events using a webcam from the console via ssh connection. So I bought an orangepipc2 and a logitech c310 webcam and I started experimenting with ffmpeg and also cvlc. I need to record in HD (1280x720) with audio and minimum 10 frames per second for a duration of an hour or so and if possible in mp4 format with video in libx264 and audio in acc. Disk space is not a problem because I installed armbian (ubuntu 18.04) on an external ssd by usb. The problem is that audio and video are out of sync in cvlc and, in the case of ffmpeg, it gives me several errors and the audio is cut. I have also tried to record audio and video separately, but audio / video sync errors increase. Has anyone turned out the problem? I put you under the example commands I am using ... and they give me errors #!/bin/bash # Detect Logictec c310 device DEVICE=$(v4l2-ctl --list-devices | grep -A1 "UVC" | tail -n1 | tr -d '\t') vid="vid.mp4" ffmpeg -f alsa -r 16000 -i default:CARD=U0x46d0x81b -f v4l2 -video_size 1280x720 -i $DEVICE -pix_fmt nv12 -c:v libx264 -b:v 4M -maxrate 4M -bufsize 1M -preset ultrafast -f mp4 -strict -2 -acodec mp2 $vid -y & vidPID=$! echo "Press 'Enter' to exit" read out #stop audio and video with pids kill -n 2 $vidPID exit #!/bin/bash aud="aud.wav" vid="vid.mp4" DATE=$(date +"%Y-%m-%d_%H-%M") DATE2=$(date +"%d/%b/%Y") echo DATE=$DATE echo DATE2=$DATE2 # Detect Logictec c310 device DEVICE=$(v4l2-ctl --list-devices | grep -A1 "UVC" | tail -n1 | tr -d '\t') ffmpeg -hide_banner -f v4l2 -video_size 1280x720 -i $DEVICE -pix_fmt nv12 -c:v libx264 -b:v 4M -maxrate 4M -bufsize 1M -preset ultrafast -vsync 0 -f mp4 $vid -y & vidPID=$! #grab audio & pid ffmpeg -hide_banner -f alsa -ac 1 -i hw:CARD=U0x46d0x81b,DEV=0 $aud -y & audPID=$! #wait, till name given (that means stop) read out #stop audio and video with pids kill -n 2 $audPID kill -n 2 $vidPID echo "Saving to test.mp4" sleep 2 #combine to the target output file ffmpeg \ -i vid.mp4 \ -i aud.wav \ -c:v copy \ -c:a aac \ -ac 2 \ video_$DATE.mp4 -y #!/bin/bash cvlc -v v4l2:///dev/video0:width=640:height=480 :input-slave=alsa:/sysdefault:CARD=U0x46d0x81b --sout="#transcode{vcodec=h264,vb=2000,fps=10,scale=1.0,acodec=aac,ab=90,channels=1,samplerate=24000,audio-sync}:standard{access=file,mux=mp4,dst=output.mp4}" & PID=$! read stop kill -2 $PID
Tido Posted August 26, 2019 Posted August 26, 2019 1 hour ago, maxlinux2000 said: I need to record in HD (1280x720) with audio and minimum 10 frames per second for a duration of an hour did you look at htop or armbianmonitor -m could you show some screenshots while it is recording for 5min so the device is warm and working ?
maxlinux2000 Posted August 27, 2019 Author Posted August 27, 2019 Hi Tido, the temperature is not the problem (64º without fan, only a little heatsink, but I will put a fan in the production) I have done several tests and it turns out that the problem is in the audio recording. Sometimes it is correct and other times it is X3 faster. So if I record an audio of 10 seconds, it actually lasts 3 seconds increasing the frequency. Clearly in these conditions ffmpeg can't do much .... well, something could be done ... you could see how many seconds the video takes and stretch the audio until it is the same and can be coupled. But this means recording audio and video separately and then putting them together. I put here a 10 second wav file for you to understand the problem. out1x3.wav Something similar had never happened to me. The strange thing is that if I execute the same command several times, it gives me different results. Sometimes the speed is normal and sometimes it is X3 I do not know if it is the fault of the Logitech c310 webcam or OrangePi pc2 or the set of these two pieces of hardware. Anyone have a solution for this problem? I put here the simple examples I am using for this. #!/bin/bash # arecord -L #ffmpeg -f alsa -ar 48000 -i plughw:CARD=U0x46d0x81b,DEV=0 -ac 2 -c:a aac -r 48000 -b:a 128k -y out.aac ffmpeg -f alsa -i default:CARD=U0x46d0x81b -t 10 out1.wav ffmpeg -f alsa -ac 1 -i default:CARD=U0x46d0x81b -t 10 out2.wav ffmpeg -f alsa -ac 1 -ar 16000 -i default:CARD=U0x46d0x81b -t 10 out3.wav ffmpeg -f alsa -ac 1 -ar 16000 -i default:CARD=U0x46d0x81b -t 10 -r 16000 out4.wav Sometime the first is X3, the second is X1 and so on... strange. I will try with another webcam microphone...
maxlinux2000 Posted August 28, 2019 Author Posted August 28, 2019 Ok, I have a workaround! I have created a simple script that analize, compare and corrects the length of audio file in order to match the video length. This script can create a video files with audio in HD (720p) using a Logitech C310 webcam on a OrangePi PC or OrangePi Pc2. (tested on both) As optional feature this script can automatically upload the video to youtube Fell free tu use and adapt to your hardware. Note for the programmers: FFMPEF and ARECORD have a bug that random caputure from mic (via usb2) at wrong frequency... so the file will be reproduced x 3 fastest. I don't know if is an hardware problem o software... but this occurs on both H3 and H5 processors, so I propend for a software problem. In order to reproduce, please do this simple command varios times: # ffmpeg -f alsa -i default:CARD=U0x46d0x81b -t 10 out1.wav and hear they. below the script #!/bin/bash # Simple audio/video capture from Logitech C310 Webcam # tested on OrangePi PC and OrangePi Pc2. # Ubuntu Bionic with Armbian Linux 4.19.62-sunxi # 2019/08/28 by Massimo Biffi # Fell free to use and edit this script. # save this script on lc310-capture.sh # change the path as you needs #################################################################### # set audio/video filenames, video size aud="aud.wav" vid="vid.mp4" Vsize="1280x720" #################################################################### #Optional. auto submit video to youtube using this script: # https://www.atareao.es/como/subir-videos-a-youtube-con-un-script/ # https://github.com/tokland/youtube-upload # Put youtube=1 in order to activate it youtube=0 #################################################################### # check id ffmpeg and rubberband are present if [ -f /usr/bin/ffmpeg ]; then echo "Ok, rubberband installed" else echo "FFMPEG missing. Please install with sudo apt install ffmpeg" exit 1 fi if [ -f /usr/bin/rubberband ]; then echo "Ok, rubberband installed" else echo " Rubberband missing. Please install with sudo apt install rubberband-cli" exit 1 fi DATE=$(date +"%Y-%m-%d_%H-%M") DATE2=$(date +"%d/%b/%Y") echo DATE=$DATE #echo DATE2=$DATE2 # Detect Logictec c310 device DEVICE=$(v4l2-ctl --list-devices | grep -A1 "UVC" | tail -n1 | tr -d '\t') echo "capturing video" ffmpeg \ -hide_banner \ -loglevel panic \ -f v4l2 \ -video_size $Vsize \ -i $DEVICE \ -pix_fmt nv12 \ -c:v libx264 \ -b:v 4M \ -maxrate 4M \ -bufsize 1M \ -preset ultrafast \ -vsync 0 \ -f mp4 $vid -y & vidPID=$! echo "capturing audio, ...press Enter to stop..." #grab audio ffmpeg \ -hide_banner \ -loglevel panic \ -f alsa \ -ar 48000 \ -ac 1 \ -i hw:CARD=U0x46d0x81b,DEV=0 $aud -y & audPID=$! # Enter to Stop read stop #stop audio and video with pids echo "Stop recording" kill -n 2 $audPID kill -n 2 $vidPID # check audio and video Length echo "checking audio and video Length" Vtime=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 vid.mp4) Atime=$(ffprobe -v error -select_streams a:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 aud.wav) echo Vtime=$Vtime - Atime=$Atime # compare audio/video Length tVtime=$(echo $Vtime | tr -d '.') tAtime=$(echo $Atime | tr -d '.') if [ "$tAtime" -lt "$tVtime" ]; then echo "Lengths differents!" # if not equal calculate new frequency Freq=$( echo "scale=1; 48000*$Atime/$Vtime " | bc) echo "New Freq=$Freq" # change frequency and resample ar 48k echo "change the freq at $Freq and resample to 48k" ffmpeg \ -hide_banner \ -loglevel panic \ -i aud.wav \ -af asetrate=$Freq,aresample=48000 aud2.wav -y echo "checking audio and video Length again" Atime2=$(ffprobe -v error -select_streams a:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 aud2.wav) echo Vtime=$Vtime - Atime2=$Atime2 # fine tune Length of audio file echo "fine tune Length of audio file with rubberband" rubberband -q -D $Vtime aud2.wav aud3.wav Atime3=$(ffprobe -v error -select_streams a:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 aud3.wav) echo Vtime=$Vtime - Atime3=$Atime3 # clean and replace audio mv aud3.wav $aud rm aud2.wav else echo "calculate time difference" Diff=$(echo "scale=1; $Atime-$Vtime " | bc) echo Diff=$Diff echo "cutting last $Diff seconds" ffmpeg -hide_banner -loglevel panic -ss 00:00:00.0 -i $aud -t $Vtime aud2.wav echo "checking audio and video Length again..." Atime2=$(ffprobe -v error -select_streams a:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 aud2.wav) echo Vtime=$Vtime - Atime2=$Atime2 mv aud2.wav $aud fi # merge audio/video in mp4 and aac audio codec echo "merging audio and video..." ffmpeg \ -hide_banner \ -loglevel panic \ -i $vid \ -i $aud \ -c:v copy \ -c:a aac \ -ac 2 \ video_$DATE.mp4 -y # clean rm $aud $vid if [ youtube = 1 ]; then youtube-upload video_$DATE.mp4 --title "Vídeo del $DATE2" \ && rm video_$DATE.mp4 fi
Recommended Posts