Concat Workflow Operation
ID: concat
The concat operation has been created to concatenate multiple video tracks into one video track.
For a concatenation of two video files to work, both files need to have the same format (timebase, resolution, codecs, frame rate, etc.). This workflow operation has two modes to deal with this restriction:
- A general mode which re-encodes all input files, hence ensuring that this restriction is always met.
- A same codec mode which assumes the restriction is already met and can hence concatenate the files much faster while also being a lossless process. But it will fail or produce a weird output if if the restrictions are not met.
General Mode
No restriction on source tracks codecs
This will re-encode the videos first to the same format (framerate/timebase/codec, etc) before concatenation.
The internal FFmpeg command for re-encoding is using the following filters: fps, scale, pad and setdar for scaling all videos to a similar size including letterboxing, aevalsrc for creating silent audio streams and of course the concat for the actual concatenation step.
This requires an output-resolution and an optional output-framerate for the pre-concatenation encode.
The automatically generated FFmpeg filter for this process does look like this:
-filter_complex '
[0:v]fps=fps=25.0,scale=iw*min(640/iw\,480/ih):ih*min(640/iw\,480/ih),pad=640:480:(ow-iw)/2:(oh-ih)/2,setdar=4:3[b];
[1:v]fps=fps=25.0,scale=iw*min(640/iw\,480/ih):ih*min(640/iw\,480/ih),pad=640:480:(ow-iw)/2:(oh-ih)/2,setdar=4:3[c];
[2:v]fps=fps=25.0,scale=iw*min(640/iw\,480/ih):ih*min(640/iw\,480/ih),pad=640:480:(ow-iw)/2:(oh-ih)/2,setdar=4:3[d];
aevalsrc=0::d=1[silent];
[b][0:a][c][silent][d][2:a]concat=n=3:v=1:a=1[v][a]' -map '[v]' -map '[a]'
Same Codec Mode
Requires the source tracks having the same format (same timebase/resolution/encoding, etc.)
If the same-codec
option is specified to use this mode, the sources files can be arranged into one container
losslessly without re-encoding first. This is often the case if the tracks came from the same camera/recorder for
example.
This mode uses FFmpeg's concat demuxer, which puts all the video
content into a single container without any re-encoding. The encoding profile then operates on the source in this
container. If -c copy
is used in the encoding profile, the complete concatenation is lossless.
The FFmpeg command for this is is:
-f concat -i videolist.txt
…where videolist.txt
contains a line in the form file <path to video>
for each source track.
Usage
This operation is quite similar to the compose operation. The only difference is that the input properties are not only
limited to one source-flavor
and source-tag
. The operation supports multiple flavor and tags as input. To add
multiple sources, add different keys with the prefix source-flavor-
/source-tag-
and an incremental number starting
with 0. For example:
source-flavor-part-0
source-flavor-part-1
source-flavor-part-..
Alternatively, using the source-flavor-numbered-files
option, the operation supports an undetermined number of
ordered input files.
This is useful when the number of input files cannot be known in advance, such as chunked output files from some camera/recorders, and the names are ordered by number or timestamps and to be sorted lexicographically.
For example, the configuration could be source-flavor-numbered-files: multipart/part+source
and the ordered input
files:
video-201711201020.mp4
video-201711201030.mp4
video-201711201040.mp4
Note that both methods of defining input files are mutually exclusive.
Configuration Keys
Key | Required | Description | Default | Example |
---|---|---|---|---|
source-flavor-part-X |
false | An iterative list of part/flavor to use as input track. | NULL |
presenter/trimmed |
source-tag-part-X |
false | An iterative list of part/tag to use as input track. | NULL |
source-to-concate |
source-flavor-part-X-mandatory |
false | Define the flavor part-X as optional for concatenation. | false |
true |
source-tag-part-X-mandatory |
false | Define the tag part-X as optional for concatenation. | false |
true |
encoding-profile |
true | Encoding profile to use for the concatenation. | NULL |
concat |
target-flavor |
true | Flavor(s) to add to the output track. | NULL |
presenter/concat |
target-tags |
false | Tag(s) to add to the output track | NULL |
engage-download |
output-resolution |
true | Output resolution in width, height or a source part | NULL |
1900x1080 , part-1 |
output-framerate |
false | Output frame rate in frames per second or a source part | -1.0 |
25 , 23.976 , part-1 |
source-flavor-numbered-files |
false | Files of this flavor are ordered lexicographically to use as input track. | NULL |
multipart/sections |
same-codec |
false | All source files have identical formats. | false |
true |
Example
Example of a concat operation in a workflow definition.
<!-- Add intro and outro part to the presenter track -->
<operation
id="concat"
description="Concatenate the presenter track and the intro/outro videos.">
<configurations>
<configuration key="source-flavor-part-0">intro/source</configuration>
<configuration key="source-flavor-part-1">presenter/trimmed</configuration>
<configuration key="source-flavor-part-1-mandatory">true</configuration>
<configuration key="source-flavor-part-2">outro/source</configuration>
<configuration key="target-flavor">presenter/concat</configuration>
<configuration key="target-tags">engage-download,engage-streaming</configuration>
<configuration key="encoding-profile">concat</configuration>
<configuration key="output-resolution">1920x1080</configuration>
<configuration key="output-framerate">part-1</configuration>
</configurations>
</operation>
Encoding Profile
The encoding profile command must contain the #{concatCommand} parameter which will set all input and possibly filter commands required for this operation:
profile.concat.ffmpeg.command = #{concatCommand} \
… #{out.dir}/#{out.name}#{out.suffix}