Changes between Version 37 and Version 38 of Concatenate


Ignore:
Timestamp:
Nov 14, 2017, 10:19:27 PM (10 days ago)
Author:
slhck
Comment:

formatting, grammar, more explanations and caveats, add example image to concat filter

Legend:

Unmodified
Added
Removed
Modified
  • Concatenate

    v37 v38  
    88== Concatenation of files with same codecs ==#samecodec 
    99 
    10 There are two methods within ffmpeg that can be used to concatenate files of the same type: [#demuxer the concat ''demuxer''] and [#protocol 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 protocol only works with a select few containers. However, the concat protocol is available in older versions of ffmpeg, where the demuxer isn't. 
     10There are two methods within ffmpeg that can be used to concatenate files of the same type: 
     11 
     121. [#demuxer the concat ''demuxer''] 
     132. [#protocol the concat ''protocol''] 
     14 
     15The 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 protocol only works with a select few containers. 
    1116 
    1217=== Concat demuxer ===#demuxer 
    1318 
    14 The concat demuxer was added to FFmpeg 1.1. You can read about it in the [https://ffmpeg.org/ffmpeg-formats.html#concat documentation]. 
     19You can read about the concat demuxer in the [https://ffmpeg.org/ffmpeg-formats.html#concat documentation]. This demuxer reads a list of files and other directives from a text file and demuxes them one after the other, as if all their packets had been muxed together. All files must have the same streams (same codecs, same time base, etc.) but can be wrapped in different container formats. 
    1520 
    1621==== Instructions ==== 
     
    3136The `-safe 0` above is not required if the paths are relative. 
    3237 
     38==== Automatically generating the input file ==== 
     39 
    3340It is possible to generate this list file with a bash for loop, or using `printf`. '''Either''' of the following would generate a list file containing every *.wav in the working directory: 
    3441 
     
    6774}}} 
    6875 
    69 Concatenation becomes troublesome, if next clip for concatenation does not exist at the moment, because decoding won't start until the whole list is read. However, it is possible to refer another list at the end of the current list: 
     76==== Automatically appending to the list file ==== 
     77 
     78Concatenation does not work if the next clip for does not exist at the moment, because decoding won't start until the whole list is read. However, it is possible to refer to another list at the end of the current list. The following script provides an example for this mechanism: 
    7079 
    7180{{{ 
     
    112121ffplaypid=$! 
    113122 
    114  
    115123echo "generating some test data..." 
    116124i=0; for c in red yellow green blue; do 
     
    131139=== Concat protocol ===#protocol 
    132140 
    133 While the demuxer works at the stream level, the concat protocol works at the file level. Certain files (mpg and mpeg transport streams, possibly others) can be concatenated. This is analogous to using cat on UNIX-like systems or copy on Windows. 
     141While the demuxer works at the stream level, the concat protocol works at the file level. Certain files (MPEG-2 transport streams, possibly others) can be concatenated. This is analogous to using `cat` on UNIX-like systems or `copy` on Windows. 
    134142 
    135143==== Instructions ==== 
    136144 
    137 {{{ 
    138 ffmpeg -i "concat:input1.mpg|input2.mpg|input3.mpg" -c copy output.mpg 
    139 }}} 
    140  
    141 If you have MP4 files, these could be losslessly concatenated by first transcoding them to mpeg transport streams. With h.264 video and AAC audio, the following can be used: 
     145The following command concatenates three MPEG-2 TS files and concatenates them without re-encoding: 
     146 
     147{{{ 
     148ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy output.ts 
     149}}} 
     150 
     151==== Using intermediate files ==== 
     152 
     153If you have MP4 files, these could be losslessly concatenated by first transcoding them to MPEG-2 transport streams. With H.264 video and AAC audio, the following can be used: 
    142154 
    143155{{{ 
     
    147159}}} 
    148160 
    149 If you're using a system that supports named pipes, you can use those to avoid creating intermediate files - this sends stderr (which ffmpeg sends all the written data to) to /dev/null, to avoid cluttering up the command-line: 
     161==== Using named pipes to avoid intermediate files ==== 
     162 
     163If you're using a system that supports named pipes, you can use those to avoid creating intermediate files. This sends stderr (to which ffmpeg sends all the written data) to `/dev/null`, to avoid cluttering up the command-line: 
    150164 
    151165{{{ 
     
    156170}}} 
    157171 
    158 All MPEG codecs (H.264, MPEG4/divx/xvid, MPEG2; MP2, MP3, AAC) are supported in the mpegts container format, though the commands above would require some alteration (the `-bsf` bitstream filters will have to be changed). 
     172All MPEG codecs (MPEG-4 Part 10 / AVC, MPEG-4 Part 2, MPEG-2 Video, MPEG-1 Audio Layer II, MPEG-2 Audio Layer III (MP3), MPEG-4 Part III (AAC)) are supported in the MPEG-TS container format, although the commands above would require some alteration (e.g., the `-bsf` bitstream filters will have to be changed). 
    159173 
    160174== Concatenation of files with different codecs ==#differentcodec 
    161175 
     176In many cases, input files will have different codecs or different codec properties, which makes it impossible to use any of the above methods. 
     177 
    162178=== Concat filter ===#filter 
    163179 
    164 The concat filter is available in recent versions of ffmpeg. See the [https://ffmpeg.org/ffmpeg-filters.html#concat concat filter documentation] for more info. 
     180See the [https://ffmpeg.org/ffmpeg-filters.html#concat concat filter documentation] for more info. The filter works on segments of synchronized video and audio streams. All segments must have the same number of streams of each type, and that will also be the number of streams at output. 
     181 
     182{{{ 
     183#!div style="border: 1px solid #e5e5c7; margin: 1em; background-color: #ffd;" 
     184'''Note:''' Filters are incompatible with [https://ffmpeg.org/ffmpeg.html#Stream-copy stream copying]; you can't use `-c copy` with this method. Since you have to re-encode the video and audio stream(s), and since re-encoding may introduce compression artifacts, make sure to add proper target bitrate or quality settings. See the [[Encode|encoding guides]] for more info. 
     185}}} 
     186 
     187For the concat filter to work, the inputs have to be of the same frame dimensions (e.g., 1920⨉1080 pixels) and should have the same framerate. Therefore, you may at least have to add a [http://ffmpeg.org/ffmpeg-filters.html#scale-1 scale] or [http://ffmpeg.org/ffmpeg-filters.html#scale2ref scale2ref] filter before concatenating videos. A handful of other attributes have to match as well, like the stream aspect ratio. Refer to the documentation of the filter for more info. 
    165188 
    166189==== Instructions ==== 
    167190 
    168 This is easiest to explain using an example: 
    169  
    170 {{{ 
    171 ffmpeg -i input1.mp4 -i input2.webm \ 
    172 -filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \ 
    173 -map "[v]" -map "[a]" <encoding options> output.mkv 
    174 }}} 
    175  
    176 On the `-filter_complex` line, the following: 
    177  
    178 {{{ 
    179 [0:v:0] [0:a:0] [1:v:0] [1:a:0] 
    180 }}} 
    181  
    182 tells ffmpeg what streams to send to the concat filter; in this case, video stream 0 [0:v:0] and audio stream 0 [0:a:0] from input 0 (`input1.mp4` in this example), and video stream 0 [1:v:0] and audio stream 0 [1:v:0] from input 1 (`input2.webm`). 
    183  
    184 {{{ 
    185 concat=n=2:v=1:a=1 [v] [a]' 
    186 }}} 
    187  
    188 This is the concat filter itself. `n=2` is telling the filter that there are two input files; `v=1` is telling it that there will be one video stream; `a=1` is telling it that there will be one audio stream. `[v]` and `[a]` are names for the output streams to allow the rest of the ffmpeg line to use the output of the concat filter. 
    189  
    190 Note that the single quotes around the whole filter section are required. 
    191  
    192 {{{ 
    193 -map '[v]' -map '[a]' 
     191Let's say we have three files that we want to concatenate – each of them with one video and audio stream. The concat filter command would look like this: 
     192 
     193{{{ 
     194ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \ 
     195-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \ 
     196-map "[outv]" -map "[outa]" output.mkv 
     197}}} 
     198 
     199Now, let's dissect that command. We first specify all the input files, then instantiate a `-filter_complex` filtergraph – this is needed instead of `-filter:v` because it has multiple inputs and outputs. 
     200 
     201The following line: 
     202 
     203{{{ 
     204[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0] 
     205}}} 
     206 
     207tells ffmpeg which streams to take from the input files and send as input to the concat filter. In this case, video stream 0 [0:v:0] and audio stream 0 [0:a:0] from input 0 (`input1.mp4` in this example), and video stream 0 [1:v:0] and audio stream 0 [1:v:0] from input 1 (`input2.webm`), etc. 
     208 
     209{{{ 
     210concat=n=3:v=1:a=1[outv][outa]' 
     211}}} 
     212 
     213This is the concat filter itself. `n=3` is telling the filter that there are three input segments; `v=1` is telling it that there will be one video stream per segment; `a=1` is telling it that there will be one audio stream per segment. The filter then concatenates these segments and produces two output streams. `[outv]` and `[outa]` are names for these output streams. Note that the quotes around the filter section are required. 
     214 
     215The following image shows the stream mapping to and from the filter in the above example: 
     216 
     217[[Image(concat_filter.png)]] 
     218 
     219You can then either re-use these streams in other filters, or [[Map|map them to the output file]]: 
     220 
     221{{{ 
     222-map "[outv]" -map "[outa]" output.mkv 
    194223}}} 
    195224 
    196225This tells ffmpeg to use the results of the concat filter rather than the streams directly from the input files. 
    197226 
    198 Note that filters are incompatible with [https://ffmpeg.org/ffmpeg.html#Stream-copy stream copying]; you can't use `-c copy` with this method. Also, I'm not sure whether softsubs are supported. 
    199  
    200 As you can infer from this example, multiple types of input are supported, and anything readable by ffmpeg should work. The inputs have to be of the same frame size, and a handful of other attributes have to match. 
    201  
    202227=== Using an external script ===#extscript 
    203228