FFmpeg: Audio-Startzeit weit weg
Audio und Video in Echtzeit werden von einer Audioquelle und zwei Videoquellen aufgezeichnet:
ffmpeg -y -copyts \
-f pulse -thread_queue_size 1024 -i alsa_input.usb-Focusrite_Scarlett_2i2_USB_Y8CAJW2063E5BD-00.analog-stereo \
-f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video0 \
-f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video6 \
-map 0:a -map 1:v -map 2:v -c:v libx264 -preset ultrafast test.mp4
Dies -copytsbewirkt eine Synchronisation der beiden Videostreams (siehe auch FFmpeg: Synchronisieren von Streams von zwei Webcams ). Auf der Aufnahme ist jedoch kein Audio zu hören. Ein Blick auf die Startzeiten in der Ausgabe erklärt, warum:
Input #0, pulse, from 'alsa_input.usb-Focusrite_Scarlett_2i2_USB_Y8CAJW2063E5BD-00.analog-stereo':
Duration: N/A, start: 1599927759.812456, bitrate: 1536 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 54432.851793, bitrate: N/A
Stream #1:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 1920x1080, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Input #2, video4linux2,v4l2, from '/dev/video6':
Duration: N/A, start: 54433.882342, bitrate: N/A
Stream #2:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 1920x1080, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Die beiden Zeiten der Videogeräte liegen erwartungsgemäß nahe beieinander: 54432.851793 und 54433.882342. Aber das vom Audiogerät ist weit weg: 1599927759.812456.
Irgendwelche Ideen, wie man das behebt?
Antworten
Die vom Audiogerät bereitgestellte Zeit ist tatsächlich die vernünftigere: Es scheint die Zeit seit der Epoche zu sein. Weitere Informationen hierzu finden Sie unter https://stackoverflow.com/questions/10266451/where-does-v4l2-buffer-timestamp-value-starts-counting . Dies zeigt auch eine Möglichkeit, dies zu beheben: -af "asetpts=PTS-x/TB"Hier xist die Zeit in Sekunden, zu der das System gestartet wurde ( nicht die Betriebszeit, sondern der Zeitpunkt, zu dem das System gestartet wurde). Sie können es von /proc/statsder Zeile bekommen , die mit beginnt btime. Es scheint, dass dies durcheinander gebracht werden kann, wenn das System angehalten wird oder ähnliches. Achten Sie also darauf.
Die Verwendung von asetptsund setptskann auch den zweiten Durchgang mit loswerden -start_at_zero, der in FFmpeg vorgeschlagen wurde : Synchronisieren von Streams von zwei Webcams . Hier ist eine vollständige Beispiellösung:
btime_=`grep btime /proc/stat | awk '{print $2}'`
utime_=`awk '{print $1}' /proc/uptime`
btime_utime_=`echo "${btime_?} + ${utime_?}" | bc -l`
ffmpeg -y -copyts \
-f pulse -thread_queue_size 1024 -i alsa_input.usb-Focusrite_Scarlett_2i2_USB_Y8CAJW2063E5BD-00.analog-stereo \
-f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video0 \
-f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video6 \
-map 0:a -map 1:v -map 2:v -c:v libx264 -preset ultrafast \
-af "asetpts=PTS-${btime_utime_?}/TB" \
-vf "setpts=PTS-${utime_?}/TB" \
test.mp4
Beachten Sie, dass die Verschiebung um die Betriebszeit (um den zweiten Durchgang mit zu vermeiden -start_at_zero) nicht ganz genau ist, da der erste PTS etwas größer als Null ist. Aber es ist gut genug für meine bisherigen Zwecke.