ffmpeg在命令行上使用ffmpeg加入两个mp4文件


29

我可以使用以下命令成功加入多个文件:

ffmpeg -f concat -i input.txt -codec copy output.mp4

该命令的唯一问题是您需要从名为input.txt的文本文件中读取具有以下内容的文件路径:

file 'C:\Users\fabio\Downloads\Super\Sharks\01.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\02.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\03.mp4'

有没有一种方法可以实现相同的目标而不必从文件中读取文件路径?我没有运气就尝试了以下方法:

ffmpeg -f concat -i file "C:\a\b\01.mp4" file "C:\a\b\02.mp4" -codec copy output.mp4
ffmpeg -f concat -i "C:\a\b\01.mp4" "C:\a\b\02.mp4" -codec copy output.mp4

我必须使用其他命令吗?


Answers:


37

2019更新:

如评论中所述,Stack Overflow很好地描述了可用于串联的选项,并讨论了根据所使用文件的类型使用哪种方法:

如何使用FFmpeg连接两个MP4文件?

2016年原创答案:

您应该能够使用concat协议方法来组合文件:

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

此外,FFmpeg手册讨论了一种专门用于MP4文件的方法,以无损地连接它们,但要求您创建临时文件(或命名管道):

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

1
第一个命令对我来说就像黄油一样。.花了2到3秒钟将我的6个mp4文件连接到输出文件中(大约239 MB)。
萨钦(Sachin)2013年

22
第一条命令对我不起作用。它只是复制了第一个文件。
路易斯·弗洛里特

3
这不起作用,它只是将第一个文件复制到output.mp4
crmpicco

2
文件级串联不适用于MP4,因此不建议此格式使用concat协议,并且通常不起作用。
洛格

1
@brasofilo感谢您的链接。早就应该这样做了,但是我更新了答案以指出人们的方向。
卡森·达林

5

您可以通过将列表输出到ffmpeg stdout并从中读取列表来将文件替换为列表stdin

(echo file 'a.mp4' & echo file 'b.mp4') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "result.mp4"

在Mac OS 10.12.6上使用ffmpeg版本2.4.3-tessus时,这只会引发错误:“无法识别的选项'protocol_whitelist'”。如果没有protocol_whitelist选项,它似乎只是复制第二个MP4文件。
James

2

不,似乎没有办法在单个命令行上使用ffmpeg concat demuxer。您需要使用文件列表创建输入文本文件。我以为自己很奇怪,也许有人以后会把它添加到FFMpeg中。

该问题的可接受答案使用concat协议,而不是op要求的concat多路分配器。


1
其实有。标准输入
Qwertiy

concat协议不应与MP4或需要全局标头的任何其他格式一起使用。
口语

1

您仍然可以在脚本中执行此操作,而无需更改命令。就像是:

echo "file fname1" >$$.tmp    #single redirect creates or truncates file
echo "file fname2" >>$$.tmp   # double redirect appends
echo "file fname3" >>$$.tmp   # do as many as you want.

ffmpeg -f concat -i $$.tmp -codec copy output.mp4

rm $$.tmp  # just to clean up the temp file. 
           # For debugging, I usually leave this out.

$$扩展为运行命令的shell的pid,因此每次运行时文件名都会不同。因此,您可以根据需要使用$$。txt。或者是其他东西...

另外,您可以使用here文件向文件添加一堆数据:

cat <<EOF >$$.tmp
file fname1
file fname2
file fname3
EOF

bash变量替换有效,因此您可以以编程方式确定文件的内容,而不必固定文件。我一直将这种东西嵌入for循环中。最后,重定向的工作原理与上述相同,因此> $$。tmp会被截断然后写入>> $$。tmp追加。


2
这个问题问:“有没有一种方法可以实现相同的目标而不必从文件中读取文件路径?” 您所要做的就是提供一种将文件路径写入文件的方式(在从文件中读取文件路径之前)。这不能回答问题。
斯科特,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.