Changes between Version 37 and Version 38 of Concatenate


Ignore:
Timestamp:
Nov 14, 2017, 10:19:27 PM (22 months 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