我正在尝试使用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文件合并在一起并使其正常工作。


当前回答

如果您想连接文件,而不必创建一个烦人的单独文本文件,只需包含文件名,您可以这样做:

echo -e "file 'in1.mp4'\nfile 'in2.mp4'" | ffmpeg -f concat -safe 0 -i /dev/stdin -c copy out.mp4

事实上,每次命令需要传入文件时,您都可以回显一个字符串并将其通过管道发送到命令,只需使用/dev/stdin作为文件名。

其他回答

对于Windows Powershell

创建文件列表

PS > ls file* | % { $n = $_.name; "file '\$n'" } | out-file mylist.txt

检查创建的文件

PS > cat mylist.txt
file '/path/to/file1.mkv'
file '/path/to/file2.mkv'
file '/path/to/file3.mkv'

运行ffmpeg(不要忘记列表文件的attach./)

PS > ffmpeg -safe 0 -f concat -i ./mylist.txt -c copy file.mkv
ffmpeg version git-2020-05-15-b18fd2b Copyright (c) 2000-2020 the FFmpeg developers
...

下面将三个.mp3文件连接成一个.m4a。

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

期权的含义

-filter_complex“concat=n=3:v=0:a=1

连接:连接过滤器连接流n: 输入段计数(=同步的音频-视频流或仅音频或仅视频流)v: 输出视频流计数a: 输出音频流计数-vn:禁用视频(-an将禁用音频)-y: 无提示覆盖输出文件

请参阅man ffmpeg或ffmpeg-h full以打印所有选项(包括所有格式和编解码器特定选项)。

对于MP4文件

对于.mp4文件(我从DailyMotion.com获得:一集50分钟的电视节目,仅分三部分下载,作为三个.mp4视频文件),以下是适用于Windows 7的有效解决方案,不需要重新编码文件。

我将这些文件重命名为file1.mp4、file2.mp4和file3.mp4),以便这些部分按照正确的顺序观看完整的电视集。

然后我创建了一个简单的批处理文件(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

批处理文件和ffmpeg.exe必须与要连接的.mp4文件放在同一文件夹中。然后运行批处理文件。运行通常需要不到10秒的时间。.

附录(2018/10/21)-

如果您正在寻找的是一种在不需要大量重新键入的情况下指定当前文件夹中所有mp4文件的方法,请在Windows批处理文件中尝试此方法(必须包含选项-safe 0):

:: Create File List
for %%i in (*.mp4) do echo file '%%i'>> mylist.txt

:: Concatenate Files
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

这在Windows 7上以批处理文件的形式运行。不要尝试在命令行上使用它,因为它只在批处理文件中工作!

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

您可以使用“Concat filter”进行快速连接。

它执行重新编码。当输入具有不同的视频/音频格式时,此选项最佳。

对于合并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

这适用于相同的以及多种输入文件类型。

对于MP4文件:

如果它们不完全相同(100%相同的编解码器、相同的分辨率、相同的类型)MP4文件,则必须首先将它们转换为中间流:

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

注意!:输出将类似于第一个文件(而不是第二个文件)