Changes between Initial Version and Version 1 of mmcat


Ignore:
Timestamp:
Nov 14, 2017, 9:36:49 PM (2 years ago)
Author:
slhck
Comment:

create separate page for mmcat script

Legend:

Unmodified
Added
Removed
Modified
  • mmcat

    v1 v1  
     1= mmcat =
     2
     3{{{
     4#!div style="border: 1px solid #e5e5c7; margin: 1em; background-color: #ffd;"
     5'''Note:''' With any vaguely-modern version of ffmpeg, the following script is made redundant by the [[Concatenate#filter|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 in the other article.
     6}}}
     7
     8The 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.
     9
     10If 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.
     11
     12== Instructions ==
     13
     14Save the script in a file named `mmcat` (or some other name), make it executable (`chmod +x mmcat`) and run it, using the syntax:
     15{{{
     16./mmcat <input1> <input2> <input3> ... <output>
     17}}}
     18
     19If you get an error like this:
     20{{{
     21#/tmp/mcs_v_all: Operation not permitted
     22}}}
     23that 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)
     24
     25== Script ==
     26
     27{{{
     28#!/bin/bash
     29
     30################################################################################
     31#
     32# Script name: MultiMedia Concat Script (mmcat)
     33# Author: burek (burek021@gmail.com)
     34# License: GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
     35# Date: 2012-07-14
     36#
     37# This script concatenates (joins, merges) several audio/video inputs into one
     38# final output (just like as if all the inputs were played in a playlist, one
     39# after another).
     40#
     41# All input files must have at least one audio and at least one video stream.
     42# If not, you can easily add audio silence, using FFmpeg. Just search the
     43# internet for "ffmpeg add silence".
     44#
     45# The script makes use of FFmpeg tool (www.ffmpeg.org) and is free for use under
     46# the GPL license. The inspiration for this script came from this FAQ item:
     47# http://ffmpeg.org/faq.html#How-can-I-join-video-files_003f
     48#
     49# If you find any bugs, please send me an e-mail so I can fix it.
     50#
     51################################################################################
     52#
     53# General syntax: mmcat <input1> <input2> <input3> ... <output>
     54#
     55# For example: mmcat file1.flv file2.flv output.flv
     56# would create "output.flv" out of "file1.flv" and "file2.flv".
     57#
     58################################################################################
     59
     60# change this to what you need !!!
     61EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k'
     62
     63################################################################################
     64#
     65# NO NEED TO TOUCH ANYTHING AFTER THIS LINE!
     66#
     67################################################################################
     68
     69# the version of the script
     70VERSION=1.3
     71
     72# location of temp folder
     73TMP=/tmp
     74
     75################################################################################
     76
     77echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files."
     78echo "Based on FFmpeg - www.ffmpeg.org"
     79echo "Don't forget to edit this script and change EXTRA_OPTIONS"
     80echo ""
     81
     82################################################################################
     83# syntax check (has to have at least 3 params: infile1, infile2, outfile
     84################################################################################
     85if [ -z $3 ]; then
     86    echo "Syntax: $0 <input1> <input2> <input3> ... <output>"
     87    exit 1
     88fi
     89
     90################################################################################
     91# get all the command line parameters, except for the last one, which is output
     92################################################################################
     93# $first  - first parameter
     94# $last   - last parameter (output file)
     95# $inputs - all the inputs, except the first input, because 1st input is
     96#           handled separately
     97################################################################################
     98first=${@:1:1}
     99last=${@:$#:1}
     100len=$(($#-2))
     101inputs=${@:2:$len}
     102
     103# remove all previous tmp fifos (if exist)
     104rm -f $TMP/mcs_*
     105
     106################################################################################
     107# decode first input differently, because the video header does not have to be
     108# kept for each video input, only the header from the first video is needed
     109################################################################################
     110mkfifo $TMP/mcs_a1 $TMP/mcs_v1
     111
     112ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null &
     113ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null &
     114
     115# if you need to log the output of decoding processes (usually not necessary)
     116# then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
     117#ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null &
     118#ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null &
     119
     120################################################################################
     121# decode all the other inputs, remove first line of video (header) with tail
     122# $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on
     123################################################################################
     124all_a=$TMP/mcs_a1
     125all_v=$TMP/mcs_v1
     126i=2
     127for f in $inputs
     128do
     129    mkfifo $TMP/mcs_a$i $TMP/mcs_v$i
     130
     131    ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null &
     132    { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
     133
     134    # if you need to log the output of decoding processes (usually not necessary)
     135    # then replace the "2>/dev/null" in 2 lines above with your log file names, like this:
     136    #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 &
     137    #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } &
     138
     139    all_a="$all_a $TMP/mcs_a$i"
     140    all_v="$all_v $TMP/mcs_v$i"
     141    let i++
     142done
     143
     144################################################################################
     145# concatenate all raw audio/video inputs into one audio/video
     146################################################################################
     147mkfifo $TMP/mcs_a_all
     148mkfifo $TMP/mcs_v_all
     149cat $all_a > $TMP/mcs_a_all &
     150cat $all_v > $TMP/mcs_v_all &
     151
     152################################################################################
     153# finally, encode the raw concatenated audio/video into something useful
     154################################################################################
     155ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \
     156       -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \
     157    $EXTRA_OPTIONS \
     158    $last
     159
     160################################################################################
     161# remove all fifos
     162################################################################################
     163rm -f $TMP/mcs_*
     164}}}
     165
     166The script above can be modified to use the '-f avi' insted of '-f yuv4mpegpipe'. Benefits:
     167- unlike yuv4mpegpipe, just one pipe for both video and audio
     168- unlike yuv4mpegpipe, matroska and flv, no need to skip header in second file using tail, because avi demuxer will skip it automatically
     169- unlike mpegts, avi supports rawvideo and pcm
     170
     171== Pipe-friendly formats ==#binconcat
     172[[Image(pipe-friendly-formats.png)]]