FFmpeg concat video and audio out of sync

前端 未结 5 1407
死守一世寂寞
死守一世寂寞 2020-12-13 14:37

Joining multiple files using ffmpeg concat seems to result in a mismatch of the timestamps or offsets for the audio. I\'ve tried with several videos and noticed the same pro

相关标签:
5条回答
  • 2020-12-13 14:52

    you can use filter_complex to concat different options in one go

    ffmpeg -i input1.mp4 -i input2.webm \
    -filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
    -map "[v]" -map "[a]" <encoding options> output.mkv
    
    0 讨论(0)
  • 2020-12-13 15:01

    If the input videos have been encoded with the same settings, you may be able to use mkvmerge from mkvtoolnix instead:

    mkvmerge -o output.mkv file1.mkv + file2.mkv + file3.mkv
    

    I needed to concatenate videos from different sources that were encoded with different settings, so I used a command like this to resize and re-encode the input videos first:

    for f in *.mp4; do
      width=1280;
      height=720;
      ffmpeg -i $f \
        -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih),
                 pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:
                                    ($height-ih*min($width/iw\,$height/ih))/2" \
        -c:v libx264 -crf 22 -preset slow -pix_fmt yuv420p \
        -c:a libfdk_aac -vbr 3 -ac 2 -ar 44100 ${f%mp4}mkv;
    done
    

    Some of the videos did not have an audio channel, so I had to use a command like this to add a silent audio channel to them:

    for f in *.mkv; do
      ffprobe $f |& grep -q '1: Audio' || {
        ffmpeg -i $f -f lavfi -i anullsrc -c:a libfdk_aac -shortest -c:v copy tmp-$f;
        mv tmp-$f $f;
      };
    done
    

    I then concatenated the videos using a command like this:

    mkvmerge -o output.mkv $(printf %s\\n *.mkv|sed '1!s/^/+/')
    

    This section was added on 14 Jun 2020 for the error "Unknown encoder 'libfdk_aac'"

    libfdk_aac isnt compatible with the GPL, and therefore not often made available by distributors

    Encoder aac can be used instead of encoder libfdk_aac as in the code below

    for f in *.mp4; do
      width=1280;
      height=720;
      ffmpeg -i $f \
        -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih),
                   pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:
                                      ($height-ih*min($width/iw\,$height/ih))/2" \
        -c:v libx264 -crf 22 -preset slow -pix_fmt yuv420p \
        -c:a aac -vbr 3 -ac 2 -ar 44100 ${f%mp4}mkv;
    done
    
    for f in *.mkv; do
      ffprobe $f |& grep -q '1: Audio' || {
        ffmpeg -i $f -f lavfi -i anullsrc -c:a aac -shortest -c:v copy tmp-$f;
        mv tmp-$f $f;
      };
    done
    
    0 讨论(0)
  • 2020-12-13 15:03

    I have been struggling with this one for quite some time as well. Particularly when working with Panasonic AVCHD-generated MTS files. My current solution is to concatenate them on the OS level not ffmpeg. I do this on windows and it looks something like this:

    COPY /b input_1.mts + input_2.mts + input_3.mts output.mts
    

    On linux it should be something like:

    $ cat input_1.mts input_2.mts input_3.mts > output.mts
    

    You can look up documentation for the windows and linux binary concatenation.

    This method of concatenation as apposed to transcoding is the way to go if the original format will work for you. This method practically uses no CPU processing and preserves the original quality. A win-win when dealing with bulk media of high quality.

    0 讨论(0)
  • 2020-12-13 15:03

    I encountered a similar problem and found a solution that worked, at least for me. In my case, I was also concatenating files, and found audio/video sync problems with iOs, but not with Windows (e.g., VLC media player showed no synchronization problems using the same mp4 file). The symptom for iOs playing this concatenated mp4 was initially good synchronization followed by an increasing loss of synchronization as the movie played, with audio going faster than video. Interestingly, the sync could be restored temporarily by advancing the movie progress slider to any point in the movie, but then the sync would be lost again as the movie continued to play in iOs. By playing the same movie simultaneously in both iOs and Windows VLC, and initially synchronized with each other as well as I could, by observing the evolution of the "echo" between them, I concluded that the iOs audio was going too fast (assuming the Windows player is correct).

    For me, the solution was to add the audio filter option -af aresample=async=1000 to the ffmpeg command, which I found as an example in the ffmpeg online documentation and used verbatim. I don't know if this setting is optimal, but the result was a mp4 with audio and video remaining synchronized when played by both iOs and VLC. This ffmpeg option yielded proper iOs synchronization both during concatenation and afterwards when re-encoding the already concatenated file.

    0 讨论(0)
  • 2020-12-13 15:11

    This two step process should work

    Step 1 Pad out the audio in each segment

    ffmpeg -i segment1.mov -af apad -c:v copy <audio encoding params> -shortest -avoid_negative_ts make_zero -fflags +genpts padded1.mov
    

    Or

    Generate segments with synced streams

    ffmpeg -y -ss 00:00:02.750 -i input.MOV -c copy -t 00:00:05.880 -avoid_negative_ts make_zero -fflags +genpts segment.MOV
    

    Step 2 Concat

    ffmpeg -f concat -i segments.txt -c copy test.mov
    

    where segments.txt consists of the names of the padded files.

    0 讨论(0)
提交回复
热议问题