我正在尝试使用ffmpeg连接两个mp4文件 . 我需要这是一个自动过程因此我选择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文件连在一起并让它工作 .
15 回答
FFmpeg有三种串联方法 .
1. concat视频过滤器
请注意,此方法执行重新编码 .
2. concat demuxer
对于Windows:
3. concat协议
由于这些格式的性质和此方法执行的简单连接,此方法不适用于许多格式,包括MP4 .
使用哪一个
concat filter :如果您的输入没有相同的参数(宽度,高度等),或者格式/编解码器不相同,或者您想要执行任何过滤,请使用此选项 . (您可以仅重新编码不匹配的输入,以便它们共享相同的编解码器和其他参数,然后使用concat解复用器来避免重新编码其他输入) .
concat demuxer :当您想要避免重新编码时使用,并且您的格式不支持文件级别连接(一般用户使用的大多数文件不支持文件级别连接) .
concat protocol :与支持文件级联接的格式(MPEG-1,MPEG-2 PS,DV)一起使用 . 不要与MP4一起使用 .
如果有疑问,请尝试使用concat demuxer .
另见
FFmpeg FAQ: How can I join video files?
FFmpeg Wiki: How to concatenate (join, merge) media files
这是一个快速(不到1分钟)和无损的方式来做到这一点,而不需要中间文件:
“ls”包含要连接的文件“perl”将连接文件即时创建到管道中“-i - ”部分告诉ffmpeg从管道读取
(注意 - 我的文件中没有空格或奇怪的东西 - 如果你想用“硬”文件做这个想法,你需要适当的shell转义) .
for MP4文件:
如果它们不完全相同(100%相同的编解码器,相同的分辨率,相同的类型)MP4文件,那么您必须首先将它们转码为中间流:
NOTE! :输出将像第一个文件(而不是第二个文件)
我最终使用mpg作为中间格式并且它工作(注意这是一个危险的例子,-qscale 0将重新编码视频......)
FOR MP4 FILES
对于 .mp4 文件(我从DailyMotion.com获得:一个50分钟的电视剧集,只能分三部分下载,作为三个.mp4视频文件),以下是 Windows 7 的有效解决方案,并且 NOT 涉及重新编码文件 .
我重命名了文件(如file1.mp4,file2.mp4,file3.mp4),以便部件按照正确的顺序查看完整的电视剧集 .
然后我创建了一个简单的 batch file (concat.bat),其中包含以下内容:
必须将 batch file 和 ffmpeg.exe 放在与要连接的 .mp4 files 相同的文件夹中 . 然后运行批处理文件 . 运行通常不到十秒钟 .
.
Addendum (2018/10/21) -
如果您正在寻找的是一种方法,用于指定当前文件夹中的所有mp4文件而无需重新输入,请在Windows _686645中尝试此操作( MUST 包括选项 -safe 0 ):
这适用于Windows 7中的批处理文件 . Don't 尝试在命令行中使用它,因为它只能在批处理文件中使用!
我试图将三个
.mp3
音频文件连接成一个.m4a
文件,这个ffmpeg命令可以工作 .输入命令:
含义: " -filter_complex concat=n=3:v=0:a=1" :
有关更多信息:使用
ffmpeg -h full
打印所有选项(包括所有格式和编解码器特定选项,非常长)有关ffmpeg中各种串联方式的详细文档可以是found here .
您可以使用'Concat filter'进行快速连接 .
它执行重新编码 . 当输入具有不同的视频/音频格式时,此选项最佳 .
For Concatenating 2 files:
For Concatenating 3 files:
这适用于同一个以及多个输入文件类型 .
这是我用几个GoPro mp4连接到720p mp4的脚本 . 希望它有所帮助 .
基于rogerdpack和Ed999的回复,我创建了我的.sh版本
它将当前文件夹中的所有
*.mp4
文件加入joined-out.mp4
在Mac上测试 .
结果文件大小是我的60个测试文件的精确总和 . 不应该有任何损失 . 正是我需要的
从这里的文档:https://trac.ffmpeg.org/wiki/Concatenate
这种方法适用于所有平台 .
我需要能够在跨平台脚本中封装它,所以我使用了
fluent-ffmpeg
并提出了以下解决方案:我发现在使用选项3在接受的答案中在Mac上连接几个MP4时,管道操作员对我不起作用 .
以下单行程序在Mac(High Sierra)上工作以连接mp4s,无需创建中间文件 .
ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
合并当前目录中的所有mp4文件
我个人喜欢不创建我之后必须删除的外部文件,所以我的解决方案是包含文件编号列表(如
file_1_name, file_2_name, file_10_name, file_20_name, file_100_name
,...)这对我有用(在Windows上)
特别是
Python
使用一些python代码用尽可能多的mp4来实现一个文件夹import glob import os
对于mp4文件,我发现使用opensource命令行工具“mp4box”会更好更快 . 然后你可以这样使用它:
mp4box.exe -add video1.mp4 -cat video2.mp4 destvideo.mp4
在大多数平台上下载:https://gpac.wp.imt.fr/mp4box/