What Encoding Needs to Match for Ffmpeg Concat
Contents
- Concatenation of files with aforementioned codecs
- Concat demuxer
- Concat protocol
- Chain of files with unlike codecs
- Concat filter
- Using an external script
If y'all have media files with exactly the aforementioned codec and codec parameters you can concatenate them as described in "Concatenation of files with same codecs". If you lot have media with different codecs you tin concatenate them as described in "Concatenation of files with different codecs" below.
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 aforementioned codecs, merely different container formats tin be used; and it tin can exist used with any container formats, while the protocol only works with a select few containers.
Concat demuxer
You can read virtually the concat demuxer in the 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 aforementioned streams (same codecs, aforementioned time base, etc.) but tin can be wrapped in dissimilar container formats.
Instructions
Create a file mylist.txt with all the files you want to have concatenated in the post-obit form (lines starting with a # are ignored):
# this is a comment file '/path/to/file1.wav' file '/path/to/file2.wav' file '/path/to/file3.wav'
Note that these can be either relative or absolute paths. So you tin can stream copy or re-encode your files:
ffmpeg -f concat -safe 0 -i mylist.txt -c re-create output.wav
The -prophylactic 0 above is non required if the paths are relative.
Automatically generating the input file
It 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:
# with a bash for loop for f in *.wav; do echo "file '$f'" >> mylist.txt; washed # or with printf printf "file '%s'\n" *.wav > mylist.txt
On Windows Control-line:
(for %i in (*.wav) do @repeat file '%i') > mylist.txt
Or for Windows Powershell:
foreach ($i in Get-ChildItem .\*.wav) {echo "file '$i'" >> mylist.txt} Or for Windows bat-file:
(for %%i in (*.wav) do @echo file '%%i') > mylist.txt
If your shell supports process substitution (like Bash and Zsh), you tin avoid explicitly creating a list file and do the whole thing in a single line. This would be impossible with the concat protocol (see beneath). Brand sure to generate accented paths here, since ffmpeg volition resolve paths relative to the list file your shell may create in a directory such every bit "/proc/cocky/fd/".
ffmpeg -f concat -safe 0 -i <(for f in ./*.wav; do echo "file '$PWD/$f'"; washed) -c re-create output.wav ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\due north" ./*.wav) -c copy output.wav ffmpeg -f concat -prophylactic 0 -i <(discover . -proper noun '*.wav' -printf "file '$PWD/%p'\northward") -c copy output.wav
You can as well loop a video. This example will loop input.mkv 10 times:
for i in {ane..10}; do printf "file '%s'\n" input.mkv >> mylist.txt; done ffmpeg -f concat -i mylist.txt -c copy output.mkv Irresolute playlist files on the fly
The concat demuxer opens the referenced files merely when they are needed. This allows us to bandy the referenced files atomically behind the demuxers back to be able to use the concat demuxer equally a changeable live source. Check out the following example file listing.txt:
ffconcat version 1.0 file dummy.mxf file dummy.mxf
dummy.mxf is referenced twice to make sure the concat demuxer reopens the file when it reaches it. Combine this with infinite looping and you are done:
ffmpeg -re -stream_loop -1 -i listing.txt -flush_packets 0 -f mpegts udp://127.0.0.one:5000?pkt_size=1316
Now you can alter the looping prune by a simple move command:
mv next_clip.mxf dummy.mxf
Automatically appending to the listing file
Concatenation does not work if the next clip for does not exist at the moment, considering decoding won't get-go until the whole list is read. Withal, it is possible to refer to some other list at the end of the current listing. The post-obit script provides an example for this machinery:
#!/bin/bash fn_concat_init() { echo "fn_concat_init" concat_pls=`mktemp -u -p . concat.XXXXXXXXXX.txt` concat_pls="${concat_pls#./}" echo "concat_pls=${concat_pls:?}" mkfifo "${concat_pls:?}" echo } fn_concat_feed() { echo "fn_concat_feed ${1:?}" { >&2 echo "removing ${concat_pls:?}" rm "${concat_pls:?}" concat_pls= >&two fn_concat_init repeat 'ffconcat version 1.0' echo "file '${i:?}'" echo "file '${concat_pls:?}'" } >"${concat_pls:?}" echo } fn_concat_end() { echo "fn_concat_end" { >&2 repeat "removing ${concat_pls:?}" rm "${concat_pls:?}" # non writing header. } >"${concat_pls:?}" echo } fn_concat_init echo "launching ffmpeg ... all.mkv" timeout 60s ffmpeg -y -re -loglevel warning -i "${concat_pls:?}" -pix_fmt yuv422p all.mkv & ffplaypid=$! echo "generating some test data..." i=0; for c in blood-red yellow light-green blue; practice ffmpeg -loglevel alert -y -f lavfi -i testsrc=s=720x576:r=12:d=4 -pix_fmt yuv422p -vf "drawbox=due west=l:h=westward:t=due west:c=${c:?}" test$i.mkv fn_concat_feed test$i.mkv ((i++)); repeat done echo "done" fn_concat_end await "${ffplaypid:?}" echo "washed encoding all.mkv" Note that recursively referencing playlist files volition cause ffmpeg to somewhen run out of file descriptors (or other resource) because ffmpeg just closes the playlist file when the playlist has finished, only in the example above because of the recursive chaining none of the playlist files actually end.
Concat protocol
While 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.
Instructions
The following command concatenates three MPEG-2 TS files and concatenates them without re-encoding:
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy output.ts
Using intermediate files
If you lot have MP4 files, these could be losslessly concatenated by first transcoding them to MPEG-two transport streams. With H.264 video and AAC audio, the following can be used:
ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
Using named pipes to avert intermediate files
If you're using a organization that supports named pipes, you tin can use those to avoid creating intermediate files. This sends stderr (to which ffmpeg sends all the written information) to /dev/nothing, to avert cluttering up the command-line:
mkfifo temp1 temp2 ffmpeg -y -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1 2> /dev/null & \ ffmpeg -y -i input2.mp4 -c copy -bsf:five h264_mp4toannexb -f mpegts temp2 2> /dev/null & \ ffmpeg -f mpegts -i "concat:temp1|temp2" -c copy -bsf:a aac_adtstoasc output.mp4
The additional -y switch is needed to forcefulness ffmpeg to write to existing files temp1 and temp2, which are the named pipes. Without the switch, the first two ffmpeg programs running in the groundwork will not produce whatever output because they wait for interactive yeah/no answers to the questions whether to overwrite existing files.
All MPEG codecs (MPEG-4 Part ten / AVC, MPEG-iv Office two, MPEG-2 Video, MPEG-1 Audio Layer Two, MPEG-ii Sound Layer Three (MP3), MPEG-4 Part Iii (AAC)) are supported in the MPEG-TS container format, although the commands to a higher place would require some alteration (e.1000., the -bsf bitstream filters will accept to be changed).
Concatenation of files with unlike codecs
In many cases, input files will take unlike codecs or unlike codec properties, which makes information technology impossible to use any of the in a higher place methods.
Concat filter
See the concat filter documentation for more info. The filter works on segments of synchronized video and audio streams. All segments must have the aforementioned number of streams of each blazon, and that will also exist the number of streams at output.
Notation: Filters are incompatible with stream copying; you tin't apply -c copy with this method. Since y'all take to re-encode the video and audio stream(s), and since re-encoding may introduce compression artifacts, make certain to add together proper target bitrate or quality settings. See the encoding guides for more info.
For 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, yous may at least have to add together a scale or scale2ref filter earlier concatenating videos. A handful of other attributes have to match likewise, like the stream aspect ratio. Refer to the documentation of the filter for more than info.
Instructions
Allow's say we have three files that nosotros want to concatenate – each of them with one video and audio stream. The concat filter command would look like this:
ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \ -filter_complex "[0:v:0][0:a:0][i:v:0][1:a:0][2:5:0][two:a:0]concat=due north=3:five=ane:a=1[outv][outa]" \ -map "[outv]" -map "[outa]" output.mkv
Now, let'due south dissect that control. We outset specify all the input files, then instantiate a -filter_complex filtergraph – this is needed instead of -filter:5 because information technology has multiple inputs and outputs.
The following line:
[0:v:0][0:a:0][ane:v:0][1:a:0][2:5:0][2:a:0]
tells ffmpeg which streams to take from the input files and ship every bit input to the concat filter. In this case, video stream 0 [0:v:0] and sound stream 0 [0:a:0] from input 0 (input1.mp4 in this example), and video stream 0 [one:v:0] and audio stream 0 [1:v:0] from input 1 (input2.webm), etc.
concat=n=3:v=1:a=1[outv][outa]'
This is the concat filter itself. n=3 is telling the filter that there are 3 input segments; v=1 is telling it that there will be one video stream per segment; a=1 is telling it that in that location will be ane 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 department are required.
The following image shows the stream mapping to and from the filter in the above instance:
You can so either re-apply these streams in other filters, or map them to the output file:
-map "[outv]" -map "[outa]" output.mkv
This tells ffmpeg to use the results of the concat filter rather than the streams directly from the input files.
Using an external script
At that place is a Bash script called mmcat which was useful for older versions of ffmpeg that did not include the concat filter.
Source: https://trac.ffmpeg.org/wiki/Concatenate
0 Response to "What Encoding Needs to Match for Ffmpeg Concat"
Post a Comment