ffmpeg:合并/合并多个MP4video不工作,输出只包含第一个video
以下是我用来组合多个video的命令:
ffmpeg -i 75_540_38HQ2.mp4 -i 76_70_20.mp4 -i 76_173_80.mp4 -i 81_186_35.mp4 -vcodec copy -acodec copy Mux1.mp4
生成的Mux1.mp4
不包含所有video。 只有第一个video( 75_540_38HQ2.mp4
)。 源和结果video的文件大小在下面(如您所见,生成的video比第一个vid略大):
$ ls -lh -rw-r - r-- 1 dbaker dbaker 42M 2011-03-24 11:59 75_540_38HQ2.mp4 -rw-r - r-- 1 dbaker dbaker 236M 2011-03-24 12:09 76_173_80.mp4 -rw-r - r-- 1 dbaker dbaker 26M 2011-03-24 12:05 76_70_20.mp4 -rw -r - r-- 1 dbaker dbaker 54M 2011-03-24 12:15 81_186_35.mp4 -rw-r - r-- 1 dbaker dbaker 44M 2011-03-24 14:48 Mux1.mp4
这是ffmpeg
命令的输出。 对我来说,它看起来不错,显示多个源input和单个输出。
FFmpeg版本SVN-r26402,FFmpeg开发者版权所有(c)2000-2011 build于2011年3月21日18:05:32与海湾合作委员会4.4.5 configuration:--enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable- libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxvid --enable-x11grab libavutil 50.36。 0 / 50.36。 0 libavcore 0.16。 1 / 0.16。 1 libavcodec 52.108。 0 / 52.108。 0 libavformat 52.93。 0 / 52.93。 0 libavdevice 52. 2. 3 / 52. 2. 3 libavfilter 1.74。 0 / 1.74。 0 libswscale 0.12。 0 / 0.12。 0 libpostproc 51. 2.0 / 51. 2. 0 来自'75_540_38HQ2.mp4'的input#0,mov,mp4,m4a,3gp,3g2,mj2: 元数据: major_brand:isom minor_version:512 compatible_brands:isomiso2avc1mp41 creation_time:1970-01-01 00:00:00 编码器:Lavf52.93.0 时间:00:00:29.99,开始:0.000000,比特率:11517 kb / s stream#0.0(eng):video:h264,yuv420p,1280x960 [PAR1:1 DAR4:3],11575kb / s,29.94fps,29.97tbr,30ktbn,59.94tbc 元数据: creation_time:1970-01-01 00:00:00 stream#0.1(eng):audio:aac,48000Hz,立体声,s16,127kb / s 元数据: creation_time:1970-01-01 00:00:00 来自'76_70_20.mp4'的input#1,mov,mp4,m4a,3gp,3g2,mj2: 元数据: major_brand:isom minor_version:512 compatible_brands:isomiso2avc1mp41 creation_time:1970-01-01 00:00:00 编码器:Lavf52.93.0 持续时间:00:00:19.98,开始:0.000000,比特率:10901 kb / s stream#1.0(eng):video:h264,yuv420p,1280x960 [PAR 1:1 DAR 4:3],10804kb / s,29.97 fps,29.97 tbr,30k tbn,59.94 tbc 元数据: creation_time:1970-01-01 00:00:00 stream#1.1(eng):audio:aac,48000Hz,立体声,s16,128kb / s 元数据: creation_time:1970-01-01 00:00:00 来自'76_173_80.mp4'的input#2,mov,mp4,m4a,3gp,3g2,mj2: 元数据: major_brand:isom minor_version:512 compatible_brands:isomiso2avc1mp41 creation_time:1970-01-01 00:00:00 编码器:Lavf52.93.0 时间:00:03:09.99,开始:0.000000,比特率:10393 kb / s stream#2.0(eng):video:h264,yuv420p,1280×960 [PAR1:1 DAR4:3],10321kb / s,29.96fps,29.97tbr,30ktbn,59.94tbc 元数据: creation_time:1970-01-01 00:00:00 stream#2.1(eng):audio:aac,48000Hz,立体声,s16,128kb / s 元数据: creation_time:1970-01-01 00:00:00 似乎stream0编解码器帧速率不同于容器帧速率:119.88(120000/1001) - > 30000.00(30000/1) 来自'81_186_35.mp4'的input#3,mov,mp4,m4a,3gp,3g2,mj2: 元数据: major_brand:isom minor_version:512 compatible_brands:isomiso2avc1mp41 creation_time:1970-01-01 00:00:00 编码器:Lavf52.93.0 持续时间:00:00:35.00,开始:0.000000,比特率:12700 kb / s stream#3.0(eng):video:h264,yuv420p,1280x720 [PAR 1:1 DAR 16:9],12620kb / s,59.91 fps,30k tbr,60k tbn,119.88 tbc 元数据: creation_time:1970-01-01 00:00:00 stream#3.1(eng):audio:aac,48000Hz,立体声,s16,128kb / s 元数据: creation_time:1970-01-01 00:00:00 输出#0,mp4到“Mux1.mp4”: 元数据: major_brand:isom minor_version:512 compatible_brands:isomiso2avc1mp41 creation_time:1970-01-01 00:00:00 编码器:Lavf52.93.0 stream#0.0(eng):video:libx264,yuv420p,1280x960 [PAR 1:1 DAR 4:3],q = 2-31,11575kb / s,30k tbn,29.97 tbc 元数据: creation_time:1970-01-01 00:00:00 stream#0.1(eng):audio:libfaac,48000Hz,立体声,128kb / s 元数据: creation_time:1970-01-01 00:00:00 stream映射: stream#0.0 - >#0.0 stream#2.1 - >#0.1 按[q]停止编码 帧= 883 fps = 632 q = -1.0 Lsize = 44730kB时间= 29.40比特率= 12465.1kbits / s video:41678kBaudio:2969kB全局标题:0kB muxing开销0.184548%
我在这里做一些愚蠢的事吗?
源video来自一个摄像机,是用ffmpeg -i bigfile.mp4 -ss 20 -t 10 -vcodec copy etc..
拍摄的小片段ffmpeg -i bigfile.mp4 -ss 20 -t 10 -vcodec copy etc..
谢谢堆! 戴夫
编辑:解决不了,所以我只是使用avidemux GUI工具。 它似乎附加MP4的就好了。
必须是MP4的问题,或只是一个gopro相机的问题。
您必须将它们转换为可以轻松连接的MPEG格式。 以下是我使用的脚本,并为我的GoProvideo调用“ffcat”。 它基本上运行几个“ffmpeg -i”命令,它们产生可连接的MPEG,然后通过pipe道连接到ffmpeg命令,然后将它们转换成H.264 mp4文件。
它也将video大小设置为720p,但您可能不想要。
“h264options”是我最近在互联网上find的标志h264.code-shop.com
希望这有助于,里德
cmd="( " h264options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \ -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \ -me_method hex -subq 7 -trellis 1 -refs 5 -bf 3 \ -flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16 \ -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\ -qmax 51 -qdiff 4" outfile="out-`date +%F-%H%M.%S`.mp4" for i; do cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; " done cmd="${cmd} ) | ffmpeg -y -i - -threads 8 ${h264options} -vb 10000000 -acodec libfaac -ar 44100 -ab 128k -s 1280x720 ${outfile}" echo "${cmd}" eval ${cmd}
忘了关于FFmpeg,改用MP4Box,很简单,快捷:
mp4box -add video1.mp4 -cat video2.mp4 -cat video3.mp4 output.mp4
它适用于Windows,Linux和OS X: http : //www.videohelp.com/tools/mp4box
如果你在Windows上,你可以使用YAMB,它是MP4Box的一个graphics用户界面,很好用: http : //www.videohelp.com/tools/YAMB
更新2016年6月: FFmpeg添加了一个串联filter,更多信息在这里: https : //stackoverflow.com/a/11175851/218418
假设你想连接电影,你可以使用下面的命令:
ffmpeg -f concat -i inputs.txt -vcodec copy -acodec copy Mux1.mp4
在inputs.txt中使用以下文本:
file 75_540_38HQ2.mp4 file 76_70_20.mp4 file 76_173_80.mp4 file 81_186_35.mp4
注意 :某些发行版(如Ubuntu)在其存储库中没有ffmpeg,而是将ffmpeg定义为avconv的别名。 这对avconv不起作用,所以在这种情况下你必须自己编译ffmpeg。 您可以通过运行ffmpeg来检查是否有真正的ffmpeg,并检查第一个输出行是否以“FFmpeg开发者”结束。
从ffmpeg手册页“示例”部分:
您可以在输出中放入许多相同types的stream:
ffmpeg -i test1.avi -i test2.avi -vcodec copy -acodec copy \ -vcodec copy -acodec copy test12.avi -newvideo -newaudio
除了第一个video和audiostream之外,生成的输出文件test12.avi将包含在inputstream列表中find的第二个video和第二个audiostream。
必须在要添加输出文件的名称之后立即指定“-newvideo”,“-newaudio”和“-newsubtitle”选项。
如果你的意思是你想要连接它们, 常见问题解答有说明。
我不确定这个问题/答案是否属于SuperUser 。
我一直在使用这个脚本相当成功。 结果是完美的,因为它使用原始video。
http://trac.ffmpeg.org/wiki/How%20to%20concatenate%20%28join,%20merge%29%20media%20files
确保你编辑了EXTRA OPTIONSstring。
#!/bin/bash ################################################################################ # # Script name: MultiMedia Concat Script (mmcat) # Author: burek (burek021@gmail.com) # License: GNU/GPL, see http://www.gnu.org/copyleft/gpl.html # Date: 2012-07-14 # # This script concatenates (joins, merges) several audio/video inputs into one # final output (just like as if all the inputs were played in a playlist, one # after another). # # All input files must have at least one audio and at least one video stream. # If not, you can easily add audio silence, using FFmpeg. Just search the # internet for "ffmpeg add silence". # # The script makes use of FFmpeg tool (www.ffmpeg.org) and is free for use under # the GPL license. The inspiration for this script came from this FAQ item: # http://ffmpeg.org/faq.html#How-can-I-join-video-files_003f # # If you find any bugs, please send me an e-mail so I can fix it. # ################################################################################ # # General syntax: mmcat <input1> <input2> <input3> ... <output> # # For example: mmcat file1.flv file2.flv output.flv # would create "output.flv" out of "file1.flv" and "file2.flv". # ################################################################################ # change this to what you need !!! EXTRA_OPTIONS='-vcodec libx264 -crf 23 -preset medium -acodec aac -strict experimental -ac 2 -ar 44100 -ab 128k' ################################################################################ # # NO NEED TO TOUCH ANYTHING AFTER THIS LINE! # ################################################################################ # the version of the script VERSION=1.3 # location of temp folder TMP=/tmp ################################################################################ echo "MultiMedia Concat Script v$VERSION (mmcat) - A script to concatenate multiple multimedia files." echo "Based on FFmpeg - www.ffmpeg.org" echo "Don't forget to edit this script and change EXTRA_OPTIONS" echo "" ################################################################################ # syntax check (has to have at least 3 params: infile1, infile2, outfile ################################################################################ if [ -z $3 ]; then echo "Syntax: $0 <input1> <input2> <input3> ... <output>" exit 1 fi ################################################################################ # get all the command line parameters, except for the last one, which is output ################################################################################ # $first - first parameter # $last - last parameter (output file) # $inputs - all the inputs, except the first input, because 1st input is # handled separately ################################################################################ first=${@:1:1} last=${@:$#:1} len=$(($#-2)) inputs=${@:2:$len} # remove all previous tmp fifos (if exist) rm -f $TMP/mcs_* ################################################################################ # decode first input differently, because the video header does not have to be # kept for each video input, only the header from the first video is needed ################################################################################ mkfifo $TMP/mcs_a1 $TMP/mcs_v1 ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>/dev/null </dev/null & ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>/dev/null </dev/null & # if you need to log the output of decoding processes (usually not necessary) # then replace the "2>/dev/null" in 2 lines above with your log file names, like this: #ffmpeg -y -i $first -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a1 2>$TMP/log.a.1 </dev/null & #ffmpeg -y -i $first -an -f yuv4mpegpipe -vcodec rawvideo $TMP/mcs_v1 2>$TMP/log.v.1 </dev/null & ################################################################################ # decode all the other inputs, remove first line of video (header) with tail # $all_a and $all_v are lists of all a/v fifos, to be used by "cat" later on ################################################################################ all_a=$TMP/mcs_a1 all_v=$TMP/mcs_v1 i=2 for f in $inputs do mkfifo $TMP/mcs_a$i $TMP/mcs_v$i ffmpeg -y -i $f -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 $TMP/mcs_a$i 2>/dev/null </dev/null & { ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>/dev/null </dev/null | tail -n +2 > $TMP/mcs_v$i ; } & # if you need to log the output of decoding processes (usually not necessary) # then replace the "2>/dev/null" in 2 lines above with your log file names, like this: #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 & #{ ffmpeg -y -i $f -an -f yuv4mpegpipe -vcodec rawvideo - 2>$TMP/log.v.$i </dev/null | tail -n +2 > $TMP/mcs_v$i ; } & all_a="$all_a $TMP/mcs_a$i" all_v="$all_v $TMP/mcs_v$i" let i++ done ################################################################################ # concatenate all raw audio/video inputs into one audio/video ################################################################################ mkfifo $TMP/mcs_a_all mkfifo $TMP/mcs_v_all cat $all_a > $TMP/mcs_a_all & cat $all_v > $TMP/mcs_v_all & ################################################################################ # finally, encode the raw concatenated audio/video into something useful ################################################################################ ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i $TMP/mcs_a_all \ -f yuv4mpegpipe -vcodec rawvideo -i $TMP/mcs_v_all \ $EXTRA_OPTIONS \ $last ################################################################################ # remove all fifos ################################################################################ rm -f $TMP/mcs_*
Concat分路器
连接分路器被添加到ffmpeg 1.1。 如果您的ffmpeg版本较旧,请从这里获取最新的静态二进制文件: http : //www.ffmpeg.org/download.html
说明
创build一个文件mylist.txt
与所有您想要以下列forms连接的文件(忽略以短划线开始的行):
# this is a comment file '/path/to/file1' file '/path/to/file2' file '/path/to/file3'
请注意,这些可以是相对path或绝对path。 那么你可以用你的文件编码:
ffmpeg -f concat -i mylist.txt -c copy output
可以使用bash for循环或使用printf来生成此列表文件。 以下任一项都将生成一个包含工作目录中每个* .wav的列表文件:
for f in ./*.wav; do echo "file '$f'" >> mylist.txt; done printf "file '%s'\n" ./*.wav > mylist.txt
资料来源: ffmpeg wiki
如果所有inputvideo都具有相同的编解码器,并且您希望在同一编解码器中输出video,则简单的concat可用于mp4和mkv文件。 https://trac.ffmpeg.org/wiki/Concatenate
你需要创build一个文本文件
# this is a comment file '/path/to/file1' file '/path/to/file2' file '/path/to/file3'
然后使用命令
ffmpeg -f concat -i mylist.txt -c copy output
我使用了相同的参考页面的例子,它工作得很好。 唯一的问题是video未被正确捕获。 它可能会引入audiovideo同步问题,因为它只是将源video中的PTS和DTS信息复制到目标video。
要获得完整的certificate解决scheme,您需要逐个数据包地读取video,然后将所有数据包放在一个video中,并进行自定义优化,比如丢弃重复的PTS数据包并保持单调的PTS值。
MP4Box不会打破audio工作。 我做了以下取得好成绩:
-
从gpac网站下载最新的Linux deb build: http ://gpac.wp.mines-telecom.fr/downloads/gpac-nightly-builds/
-
使用
-force-cat
选项
示例命令行:
MP4Box -force-cat -add in1.mp4 -cat in2.mp4 -cat in3.mp4 ... out.mp4
一些小的评论:
-
上述方式非常重要,因为随着Linux Mint 13发行的MP4Box的最新版本是错误的,并且会导致audio损坏。
-
-force-cat
非常重要,因为video格式标记没有它,从AVC更改为avc3。