FFmpegでWebカメラのビデオ入力前にオーディオ入力を指定すると同期が中断されるのはなぜですか?

FFmpegでWebカメラのビデオ入力前にオーディオ入力を指定すると同期が中断されるのはなぜですか?

私はFFmpegを使ってWebカメラとパルスオーディオソースからRTMPサーバーにストリーミングしています。

パラメータの順序がFFmpegで違いを生むことがわかります。

しかし、ビデオ入力ストリームの前にオーディオ入力ストリームを指定すると、次のようになりました。音声が遅れる、動画より約0.5秒遅れます。

これは結合された2つの入力ストリームの出力にすぎないので、順序が重要なのはなぜですか?

この記事を簡単にするために、次のコマンドを削除してテストしましたが、実際にはハードウェアアクセラレーション、AAC、およびその他のさまざまなコーデックオプションを使用しており、入力整列効果は常に同じです。

FFmpeg コマンドはまずビデオ入力を指定します。(遅滞なく):

ffmpeg -f v4l2 -input_format mjpeg -framerate 30 -video_size 1280x720 -i /dev/video1 -f pulse -i default -c:v libx264 -preset veryfast -f flv rtmp://a.rtmp.youtube.com/live2/${STREAM_KEY}

FFmpegコマンドは、まずオーディオ入力を指定します。(オーディオがビデオより0.5秒遅い):

ffmpeg -f pulse -i default -f v4l2 -input_format mjpeg -framerate 30 -video_size 1280x720 -i /dev/video1 -c:v libx264 -preset veryfast -f flv rtmp://a.rtmp.youtube.com/live2/${STREAM_KEY}

FFmpegの標準出力メッセージは、ストリームの順序を除いて同じように見えます。

ビデオ入力が最初のときに出力:

Input #0, video4linux2,v4l2, from '/dev/video1':
  Duration: N/A, start: 331644.817465, bitrate: N/A
    Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, pulse, from 'default':
  Duration: N/A, start: 1596371796.728130, bitrate: 1536 kb/s
    Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
  Stream #1:0 -> #0:1 (pcm_s16le (native) -> mp3 (libmp3lame))

オーディオが最初に入力されたときに出力:

Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, pulse, from 'default':
  Duration: N/A, start: 1596371788.496242, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, video4linux2,v4l2, from '/dev/video1':
  Duration: N/A, start: 331637.326454, bitrate: N/A
    Stream #1:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #1:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
  Stream #0:0 -> #0:1 (pcm_s16le (native) -> mp3 (libmp3lame))

ご覧のとおり、ストリームマッピングはすべてのケースで正確です。

どうなりますか?どんな洞察力でも感謝します。

FFmpegはUbuntu 20.04のgitでコンパイルされたバージョンn4.3.1です。

答え1

今この問題に遭遇しました。どのオプションを使用しても、ビデオが常に3秒遅れている理由はわかりません。それからstart時間に気づきました。

Input #0, x11grab, from ':10.0':
  Duration: N/A, start: 1627448930.994615, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 25 fps, 25.08 tbr, 1000k tbn, 1000k tbc
Input #1, pulse, from 'grab.monitor':
  Duration: N/A, start: 1627448933.416430, bitrate: 1536 kb/s
    Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s

一度切り替えたら:

Input #0, pulse, from 'grab.monitor':
  Duration: N/A, start: 1627449055.508778, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, x11grab, from ':10.0':
  Duration: N/A, start: 1627449055.550277, bitrate: N/A
    Stream #1:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 25 fps, 24.92 tbr, 1000k tbn, 1000k tbc

もう質問はありません。私考えるタイムスタンプなしでストリームを取得する場合、ffmpegは入力0の開始時間を取得し、入力0を初期化し、入力1の開始時間を取得し、入力1を初期化してから、私の場合はビデオを3秒遅らせてソートを試してください。それらを。どちらのブーツも最初に早く保ちます。

関連情報