How to Merge two videos without re-encoding [dupli

2020-06-03 05:00发布

问题:

I am trying to Merge two video without re-encoding them.

Currently i use a approach which is too much time consuming and resource as well. I just want to merge without re-encoding them. Currently i am using

        exec ( "cpulimit -l 90 ffmpeg -i $filename1 -qscale 0  $intermediate1 &> stream1.log" );
        exec ( "cpulimit -l 90 ffmpeg -i $filename2 -qscale 0  $intermediate2 &> stream2.log" );
        $output = '/var/www/html/myserver/merg/'.uniqid().'_merge.'.$ext;
        exec ( "cpulimit -l 90 cat $intermediate1 $intermediate2 | ffmpeg -i - -qscale 0 $output &> stream3.log" );

Above takes a lot of time.. I want a quick way to do it.

回答1:

Concatenation of files with same codecs:

There are two methods within ffmpeg that can be used to concatenate files of the same type: the concat demuxer & the concat protocol

The demuxer is more flexible – it requires the same codecs, but different container formats can be used; and it can be used with any container formats, while the concat protocol only works with a select few containers.

The concat demuxer instructions:

create a text file named vidlist.txt in the following format:

file '/path/to/clip1'
file '/path/to/clip2'
file '/path/to/clip3'

Note that these can be either relative or absolute paths.

Then issue the command:

ffmpeg -f concat -safe 0 -i vidlist.txt -c copy output

In case it's not abundantly clear, replace output with the video filename you wish to produce (whether that be output.mp4, output.mkv, output.avi) ffmpeg will utilize the container indicated by the extension.

The files will be stream copied in the order they appear in the vidlist.txt into the output container. the "copy codec" is blazing fast.

Edit: Note that although the docs say you don't need -safe 0 if the paths are relative, my testing indicates it's a requirement. It's possible that this may vary with your version of ffmpeg.

There are tips for auto generating the file available in the docs.

Note: All the clips must already exist or the command will fail because decoding won't start until the whole list is read.

The concat protocol instructions:

ffmpeg -i "concat:video1.ts|video2.ts|video3.ts" -c copy output.ts

Note: as mentioned above the concat protocol is severely limited in what streams and containers it supports so I never use it. The above is only included in an attempt to create a thorough answer. The concat demuxer is a far better choice for most projects.

An alternative suggestion: Personally I prefer using the Matroska container due to it's flexibility and low overhead and join videos with the same encoding using mkvmerge -o output.mkv input1.mkv + input2.mkv

Concatenation of files with different codecs:

If your clips don't use the same codecs for audio and video and/or have different rates, your stuck re-encoding to intermediate files prior to joining which as we all know is both time and resource consuming.

Note that special characters can break things so if you have these in your filenames you'll need to deal with them.

Sources: Experience

https://ffmpeg.org/ffmpeg-formats.html