Jump to content

[solved] Problems recording from a webcam


maxlinux2000

Recommended Posts

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

 

Link to comment
Share on other sites

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 ?

 

Link to comment
Share on other sites

Hi Tido, the temperature is not the problem (64º without fan, only a little heatsink, but I will put a fan in the production)

692204116_Capturadepantallade2019-08-2718-16-56.png.1cf45cde9cdbecf9880fa6437775acc9.png

 

 

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...

 

 

Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines