使用ffmpeg连接两个mp4文件

我试图使用ffmpeg连接两个mp4文件。 我需要这是一个自动过程,因此我select了ffmpeg。 我将这两个文件转换成.ts文件,然后将它们连接起来,然后尝试对该连接的.ts文件进行编码。 这些文件是h264和aac编码,我希望保持质量相同或尽可能接近原始。

ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts cat part1.ts part2.ts > parts.ts ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4 

不幸的是我在编码过程中从ffmpeg得到下面的错误信息:

 [h264 @ 0x1012600]sps_id out of range [h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period [h264 @ 0x1012600]sps_id out of range [h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period [NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s av_interleaved_write_frame(): Error while opening file 

这发生在编码的一半左右,这让我认为你不能连接两个.ts文件并使其工作。

FFmpeg有三个concat方法。 (在Windows中,使用双引号"

concat协议

 ffmpeg -i 'concat:input1|input2' -codec copy output 

concatvideofilter

 ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \ -filter_complex '[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] concat=n=3:v=1:a=1 [v] [a]' \ -map '[v]' -map '[a]' output.mkv 

请注意,此方法执行重新编码。

连接分路器

 $ cat mylist.txt file '/path/to/file1' file '/path/to/file2' file '/path/to/file3' $ ffmpeg -f concat -i mylist.txt -c copy output 

对于Windows

 (echo file ../../../../1.mp4 & echo file ../../../../2.mp4 )>%tmp%/list.txt ffmpeg -safe 0 -f concat -i %tmp%/list.txt -c copy c:/output.mp4 

哪一个使用

  • concat协议 :使用支持文件级联(MPEG-1,MPEG-2 PS,DV)的格式。
  • concatfilter :如果您需要重新编码,例如在应用filter或文件使用不同的编解码器时使用(或者您可以对“不匹配”进行重新编码,以便它们是相同的编解码器,则使用不同的编解码器)选项,以避免重新编码部分input)。
  • concat demuxer :当你想避免重新编码,而你的格式不支持文件级联。

如果有疑问,尝试连接分路器。

另见

  • FFmpeg FAQ:如何joinvideo文件?
  • FFmpeg Wiki:如何连接(连接,合并)媒体文件

这是一个快速(less于1分钟)和无损的方式来做到这一点,而不需要中间文件: –

 ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4 

“ls”包含要join的文件“perl”实时创build连接文件到pipe道中“-i – ”部分告诉ffmpeg从pipe道读取

(注意 – 我的文件中没有空格或怪异的东西 – 如果你想用“硬”文件来做这个想法,你需要适当的shell转义)。

我结束了使用MPG作为中间格式,它的工作(注意这是一个危险的例子,-qscale 0将重新编码video…)

 ffmpeg -i 1.mp4 -qscale 0 1.mpg ffmpeg -i 2.mp4 -qscale 0 2.mpg cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4 

我试图将三个.mp3audio文件连接成一个.m4a文件,这个ffmpeg命令起作用。

input命令:

 ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 -filter_complex concat=n=3:v=0:a=1 -f MOV -vn -y input.m4a 

意思是: “-filter_complex concat = n = 3:v = 0:a = 1”

concat意味着使用媒体连接(join)function。
n表示确认input文件的总数。
v意味着有video ? 使用0 =没有video,1 =包含video。
一种手段有audio ? 使用0 =没有audio,1 =包含audio。
-f表示强制设置文件格式(查看所有支持的格式,使用ffmpeg -formats
-vn表示禁用video(也可以禁用audio,如果不需要)
-y表示覆盖输出文件(如果输出文件已经存在)。

有关更多信息:使用ffmpeg -h full打印所有选项(包括所有格式和编解码器特定选项,很长)

对于MP4文件:

如果他们不完全相同(100%相同的编解码器和相同的分辨率)的MP4文件,那么你必须首先将它们转码为MPEGstream:

 ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts // now join ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4 

结果 :输出将像第一个文件(而不是第二个文件)

对于MP4文件

对于.mp4文件(我从DailyMotion.com获得:一个50分钟的电视节目,只能下载三部分,作为三个.mp4video文件)以下是Windows 7的有效解决scheme,并不涉及重新编码文件。

我重命名了文件(如file1.mp4file2.mp4file3.mp4 ),使得这些部分以正确的顺序查看完整的电视剧集。

然后我创build了一个简单的batch file (concat.bat),其内容如下:

 :: Create File List echo file file1.mp4 > mylist.txt echo file file2.mp4 >> mylist.txt echo file file3.mp4 >> mylist.txt :: Concatenate Files ffmpeg -f concat -i mylist.txt -c copy output.mp4 

batch fileffmpeg.exe必须放在与要join的.mp4文件相同的文件夹中。 然后运行batch file。 通常运行时间不到十秒钟。

有关ffmpeg中各种连接方式的详细文档可以在这里find 。

你可以使用'Concat filter'来快速连接。

它执行重新编码。 当input具有不同的video/audio格式时,此选项是最好的。

连接2个文件:

 ffmpeg -i input1.mp4 -i input2.webm \ -filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \ -map "[v]" -map "[a]" output.mp4 

连接3个文件:

 ffmpeg -i input1.mp4 -i input2.webm -i input3.mp4 \ -filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] [2:v:0] [2:a:0] concat=n=3:v=1:a=1 [v] [a]" \ -map "[v]" -map "[a]" output.mp4 

这适用于相同以及多个input文件types。

这是一个脚本,我把几个GoPro mp4连接成一个720p mp4。 希望有帮助。

 #!/bin/sh cmd="( " 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 -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4" echo "${cmd}" eval ${cmd} 

基于rogerdpack和Ed999的回应,我创build了我的.sh版本

 #!/bin/bash [ -e list.txt ] && rm list.txt for f in *.mp4 do echo "file $f" >> list.txt done ffmpeg -f concat -i list.txt -c copy joined-out.mp4 && rm list.txt 

它将当前文件夹中的所有*.mp4文件joined-out.mp4

在Mac上testing。

结果文件大小是我的60testing文件的确切总和。 不应该有任何损失。 正是我所需要的

 ffmpeg \ -i input_1.mp4 \ -i input_2.mp4 \ -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]' \ -map [vid] \ -c:v libx264 \ -crf 23 \ -preset veryfast \ output.mp4