FFmpeg에서 웹캠 비디오 입력 전에 오디오 입력을 지정하면 동기화가 중단되는 이유는 무엇입니까?

FFmpeg에서 웹캠 비디오 입력 전에 오디오 입력을 지정하면 동기화가 중단되는 이유는 무엇입니까?

저는 FFmpeg를 사용하여 웹캠 및 펄스 오디오 소스에서 RTMP 서버로 스트리밍하고 있습니다.

매개변수 순서가 FFmpeg에서 차이를 만든다는 것을 알고 있습니다.

하지만 비디오 입력 스트림보다 먼저 오디오 입력 스트림을 지정하면 다음을 발견했습니다.오디오가 지연됩니다, 동영상보다 약 0.5초 늦습니다.

이는 결합된 두 입력 스트림의 출력일 뿐이므로 순서가 중요한 이유는 무엇입니까?

이 게시물을 단순화하기 위해 다음 명령을 제거하고 테스트했으며 실제로 하드웨어 가속, 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초 지연하여 정렬을 시도합니다. 그들을. 어느 부츠든 먼저 더 빠르게 유지하겠습니다.

관련 정보