Changes between Initial Version and Version 1 of mmcat


Ignore:
Timestamp:
Nov 14, 2017, 9:36:49 PM (13 months 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)]]