Changes between Version 36 and Version 37 of Concatenate


Ignore:
Timestamp:
Nov 14, 2017, 9:36:29 PM (22 months ago)
Author:
slhck
Comment:

move mmcat script to separate page, since it's not strictly required anymore

Legend:

Unmodified
Added
Removed
Modified
  • Concatenate

    v36 v37  
    202202=== Using an external script ===#extscript
    203203
    204 With any vaguely-modern version of ffmpeg, the following script is made redundant by the advent the concat filter, which achieves the same result in a way that works across platforms. It is a clever workaround of ffmpeg's then-limitations, but most people (i.e. anyone not stuck using an ancient version of ffmpeg for whatever reason) should probably use one of the methods listed above.
    205 
    206 The following script can be used to concatenate multiple input media files (containing audio/video streams) into one output file (just like as if all the inputs were played in a playlist, one after another). It is based on this FAQ item: [https://ffmpeg.org/faq.html#How-can-I-concatenate-video-files_003f How can I join video files], which also contains other useful information.
    207 
    208 If you find any bugs, feel free to correct the script, add yourself to the list of contributors and change the version string to reflect your change(s) or email the author with your patch, whatever you find more convenient.
    209 
    210 ==== Instructions ====
    211 
    212 Save the script in a file named `mmcat` (or some other name), make it executable (`chmod +x mmcat`) and run it, using the syntax:
    213 {{{
    214 ./mmcat <input1> <input2> <input3> ... <output>
    215 }}}
    216 
    217 If you get an error like this:
    218 {{{
    219 #/tmp/mcs_v_all: Operation not permitted
    220 }}}
    221 that could mean that you don't have correct permissions set on `/tmp` directory (or whatever you set in TMP variable) or that decoding of your input media has failed for some reason. In this case it would be the best to turn on the logging (as described in the script's comments)
    222 
    223 ==== Script ====
    224 
    225 {{{
    226 #!/bin/bash
    227 
    228 ################################################################################
    229 #
    230 # Script name: MultiMedia Concat Script (mmcat)
    231 # Author: burek (burek021@gmail.com)
    232 # License: GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
    233 # Date: 2012-07-14
    234 #
    235 # This script concatenates (joins, merges) several audio/video inputs into one
    236 # final output (just like as if all the inputs were played in a playlist, one
    237 # after another).
    238 #
    239 # All input files must have at least one audio and at least one video stream.
    240 # If not, you can easily add audio silence, using FFmpeg. Just search the
    241 # internet for "ffmpeg add silence".
    242 #
    243 # The script makes use of FFmpeg tool (www.ffmpeg.org) and is free for use under
    244 # the GPL license. The inspiration for this script came from this FAQ item:
    245 # http://ffmpeg.org/faq.html#How-can-I-join-video-files_003f
    246 #
    247 # If you find any bugs, please send me an e-mail so I can fix it.
    248 #
    249 ################################################################################
    250 #
    251 # General syntax: mmcat <input1> <input2> <input3> ... <output>
    252 #
    253 # For example: mmcat file1.flv file2.flv output.flv
    254 # would create "output.flv" out of "file1.flv" and "file2.flv".
    255 #
    256 ################################################################################
    257 
    258 # change this to what you need !!!
    259 EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k'
    260 
    261 ################################################################################
    262 #
    263 # NO NEED TO TOUCH ANYTHING AFTER THIS LINE!
    264 #
    265 ################################################################################
    266 
    267 # the version of the script
    268 VERSION=1.3
    269 
    270 # location of temp folder
    271 TMP=/tmp
    272 
    273 ################################################################################
    274 
    275 echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files."
    276 echo "Based on FFmpeg - www.ffmpeg.org"
    277 echo "Don't forget to edit this script and change EXTRA_OPTIONS"
    278 echo ""
    279 
    280 ################################################################################
    281 # syntax check (has to have at least 3 params: infile1, infile2, outfile
    282 ################################################################################
    283 if [ -z $3 ]; then
    284         echo "Syntax: $0 <input1> <input2> <input3> ... <output>"
    285         exit 1
    286 fi
    287 
    288 ################################################################################
    289 # get all the command line parameters, except for the last one, which is output
    290 ################################################################################
    291 # $first  - first parameter
    292 # $last   - last parameter (output file)
    293 # $inputs - all the inputs, except the first input, because 1st input is
    294 #           handled separately
    295 ################################################################################
    296 first=${@:1:1}
    297 last=${@:$#:1}
    298 len=$(($#-2))
    299 inputs=${@:2:$len}
    300 
    301 # remove all previous tmp fifos (if exist)
    302 rm -f $TMP/mcs_*
    303 
    304 ################################################################################
    305 # decode first input differently, because the video header does not have to be
    306 # kept for each video input, only the header from the first video is needed
    307 ################################################################################
    308 mkfifo $TMP/mcs_a1 $TMP/mcs_v1
    309 
    310 ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null &
    311 ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null &
    312 
    313 # if you need to log the output of decoding processes (usually not necessary)
    314 # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
    315 #ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null &
    316 #ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null &
    317 
    318 ################################################################################
    319 # decode all the other inputs, remove first line of video (header) with tail
    320 # $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on
    321 ################################################################################
    322 all_a=$TMP/mcs_a1
    323 all_v=$TMP/mcs_v1
    324 i=2
    325 for f in $inputs
    326 do
    327         mkfifo $TMP/mcs_a$i $TMP/mcs_v$i
    328 
    329         ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null &
    330         { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
    331 
    332         # if you need to log the output of decoding processes (usually not necessary)
    333         # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
    334         #ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>$TMP/log.a.$i </dev/null &
    335         #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
    336 
    337         all_a="$all_a $TMP/mcs_a$i"
    338         all_v="$all_v $TMP/mcs_v$i"
    339         let i++
    340 done
    341 
    342 ################################################################################
    343 # concatenate all raw audio/video inputs into one audio/video
    344 ################################################################################
    345 mkfifo $TMP/mcs_a_all
    346 mkfifo $TMP/mcs_v_all
    347 cat $all_a > $TMP/mcs_a_all &
    348 cat $all_v > $TMP/mcs_v_all &
    349 
    350 ################################################################################
    351 # finally, encode the raw concatenated audio/video into something useful
    352 ################################################################################
    353 ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \
    354        -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \
    355         $EXTRA_OPTIONS \
    356         $last
    357 
    358 ################################################################################
    359 # remove all fifos
    360 ################################################################################
    361 rm -f $TMP/mcs_*
    362 }}}
    363 
    364 The script above can be modified to use the '-f avi' insted of '-f yuv4mpegpipe'. Benefits:
    365 - unlike yuv4mpegpipe, just one pipe for both video and audio
    366 - unlike yuv4mpegpipe, matroska and flv, no need to skip header in second file using tail, because avi demuxer will skip it automatically
    367 - unlike mpegts, avi supports rawvideo and pcm
    368 
    369 === Pipe-friendly formats ===#binconcat
    370 [[Image(pipe-friendly-formats.png)]]
     204There is a Bash script called [[mmcat]] which was useful for older versions of ffmpeg that did not include the `concat` filter.