如何在Ubuntu上合并多个(超过两个)视频?

我想要批量合并视频,每次合并二十个(20)视频。我正在运行一个Linux机器。这些视频是以mp4格式且质量适中。有些视频甚至缺少音频流。到目前为止,我已经尝试了ffmpegmencodercvlc/vlcMP4Box。由于我正在进行批量处理,所以我希望能写一个命令行脚本来实现这个功能。
主要问题在于,我尝试过的一些解决方案对于两个视频的合并效果很好,对带有音频流的视频也有效,而对我视频集合的其他某些子集也有效。然而,我还没有找到一个全面的解决方案来完成这个任务。

有关ffmpeg子集的相关链接:https://stackoverflow.com/questions/7333232/concatenate-two-mp4-files-using-ffmpeg - Ciro Santilli OurBigBook.com
还可以参考这个更受欢迎的问题:Stack Overflow: 如何使用FFmpeg拼接两个MP4文件? - Gabriel Staples
11个回答

我正在使用mkvmerge将多个MP4文件合并成一个文件。
mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4

7最好使用扩展名.mkv作为输出文件,因为它是一个Matroska容器,不管你给什么扩展名。 - haridsv
3这是如何安装mkvmerge的方法:tipsonubuntu.com - Morgoth
3只有这个命令mkvmerge有效。所有的ffmpeg命令都至少会导致音频错位。 - 42n4
7要安装mkvmerge,请执行sudo apt install mkvtoolnix - bomben
这是合并两个.mkv文件的简单快速方法。 - EsmaeelE

您可以使用ffmpeg完成这个任务。
ffmpeg -i concat:"input1.mp4|input2.mp4" output.mp4

参考和更多信息


5我试过这样做。问题在于它没有给出一个合适的输出。
  1. 音频轨道混乱不清。
  2. 视频轨道有一些干扰。
- Dhruv Singal
我使用了不止一个样本,结果质量很高。也许你的源视频质量有问题? - Maythux
你可能是对的。 这个问题已经解决了:http://askubuntu.com/a/637179/420614 - Dhruv Singal
10不要使用concat协议来连接MP4文件。它只适用于大多数普通用户不常遇到的特定格式。相反,应该使用concat demuxer或concat filter来进行连接。 - llogan
我尝试使用ffmpeg处理了两个各为30分钟的mp4文件。结果得到了一个时长为7小时的输出文件。 - A.W.
3只能在支持文件级连接的格式(MPEG-1、MPEG-2 PS、DV)中使用。不要在MP4格式中使用。来源:https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg - Platon Efimov

创建一个名为files.txt的文件,其中包含您想要连接的所有文件,格式如下(以#开头的行将被忽略):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

请注意,这些路径可以是相对路径或绝对路径。然后您可以进行流式复制或重新编码您的文件:
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4

-safe 0 对我有效 - Varun Chandak
对于那些在合并具有不同宽度的视频时遇到问题的人来说,这个解决方案很好用。 - Sanket Patel
能否在同一个文件中指定多个输出,例如文件 'fileA1.mp4' 转换为 'A.mp4',文件 'fileA2.mp4' 转换为 'A.mp4',文件 'B1.mp4' 转换为 'B.mp4' 等? - Antonello
1生命拯救者警报! - Chetan
这对我来说最终起作用了,但是我不得不将输入和输出都设置为.mkv格式才能正常运行。.mp4会导致音频出问题。 - tatsu

这解决了问题: https://stackoverflow.com/a/22324018/5014767

melt 是一个很好的命令行实用程序。 这里 是该页面

从评论中编辑:解决我的问题的命令是 melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264


我写了一个小的shell脚本,使用ffmpeg来合并MP4文件而不进行转码。
for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

这将在 MPEG 容器中创建中间文件,然后将它们连接成 MP4。


3请注意,如果任何文件名包含空格或者在某些情况下包含特殊字符,这个脚本将会失败。对于循环部分,最好只使用for f in *.MP4而不是使用ls。(在脚本中应该尽量避免使用ls有几个重要的原因;还有更好的选择。)此外,除非你确信没有空格或其他特殊字符,否则请为变量使用引号,例如"${f}"(或者只是"$f"),而不是未加引号的$f - Paddy Landau
CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g") 在处理文件名为1、2、3... 10... 20等时效果不佳。它会将它们解析为1、10... 2、20...等等。我建议使用CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g"),这样可以确保顺序正确。 - tisaconundrum

我写了一个围绕着ffmpeg的封装器,叫做vidmerger。它使得在文件夹中合并多个视频非常容易,例如要合并当前目录下的所有mp4文件,只需运行:
vidmerger .

1运行得很顺利,使用Rust构建!我选择直接从代码库中进行cargo build --release,因为我需要在ffmpeg上使用-safe 0选项。 - Cameron


我使用的是LosslessCut,但结果视频只在前5分钟正常。之后图像和声音开始出现延迟。 - Nam G VU

我创建了一个使用Python脚本的工具,结合moviepy,可以连接视频的子片段(如果你想从视频中删除某些部分,这非常有用)。
使用方法如下:
vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>

我的脚本完全使用bash和ffmpeg编写。它将命令行中提供的文件重新编码为一个文件。
要求文件具有相同的分辨率。可以接受不同的元数据旋转,而ffmpeg concat则不能。
rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"

我想推荐我的“videomerge” - 可通过ppa在Ubuntu上获得:
这是一个使用拖放功能的QT5 GUI应用程序。安装方法如下:
sudo add-apt-repository ppa:jentiger-moratai/mediatools
sudo apt update
sudo apt install videomerge

作为我所有的应用程序,我尽量保持用户界面非常简单。

1


仓库给了我一个404 Not Found错误。你有GitHub或SourceForge的链接吗? - rayzinnz
你可以在github上找到它。你的Ubuntu版本是多少?因为那个代码库仍然存在。 - kanehekili