使用ffmpeg合并多个mp4文件

关键词:ffmpeg、Mac、Python、bash

安装ffmpeg

打开浏览器,进入ffmpeg官方下载页面,选择操作系统对应的可执行文件下载选项,直接下载压缩包并且解压即可。
在这里插入图片描述
在这里插入图片描述
解压完”ffmpeg-4.4.7z”会得到一个”ffmpeg”的可执行文件,此时我们在命令行是无法使用ffmpeg命令的,因为我们并没有安装ffmpeg到系统,只是下载了可执行文件,下一步我们打开Terminal,把ffmpeg的可执行文件移动到”/usr/local/bin”文件夹下面,这样我们就可以在命名行正常使用ffmpeg相关命令了。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ mv ffmpeg /usr/local/bin
$ ffmpeg -version
ffmpeg version 4.4-tessus https://evermeet.cx/ffmpeg/ Copyright (c) 2000-2021 the FFmpeg developers
built with Apple clang version 11.0.0 (clang-1100.0.33.17)
configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100

使用Python生成合并mp4的bash脚本

ffmpeg官网的wiki提供了合并多媒体文件的方法:
在这里插入图片描述
由于mp4文件较多,一行一行敲太麻烦,所以就用python直接生成bash文件,由于python自带的sort的结果可能不是我们想要的,比如会变成0.mp4, 1.mp4, 10.mp4, 2.mp4…,所以安装netsort(pip install natsort)来帮助完成排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import os
from natsort import natsorted

# 存储当前文件夹下的所有mp4文件路径
L = []
for root, dirs, files in os.walk('.'):
files = natsorted(files)
for file in files:
# 只处理mp4文件
if os.path.splitext(file)[1] == '.mp4':
file_path = os.path.join(root, file)
L.append(new_path)

# 生成bash文件
with open('concat_mp4.sh', 'w') as f:
f.write("#! /bin/bash\n\n")
for l in L:
f.write(f"ffmpeg -i {l} -vcodec copy -acodec copy -vbsf h264_mp4toannexb {l.replace('.mp4', '.ts')}\n")

f.write(f'\nffmpeg -i "concat:{"|".join([i.replace(".mp4", ".ts") for i in L])}" -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4\n')
f.write('rm *.ts')

运行该python脚本即可得到下面的bash文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#! /bin/bash

ffmpeg -i ./0.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./0.ts
ffmpeg -i ./1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./1.ts
ffmpeg -i ./2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./2.ts
ffmpeg -i ./3.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./3.ts
ffmpeg -i ./4.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./4.ts
ffmpeg -i ./5.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./5.ts
ffmpeg -i ./6.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./6.ts
ffmpeg -i ./7.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./7.ts
ffmpeg -i ./8.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./8.ts
ffmpeg -i ./9.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./9.ts
ffmpeg -i ./10.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./10.ts
ffmpeg -i ./11.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./11.ts
ffmpeg -i ./12.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./12.ts
ffmpeg -i ./13.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb ./13.ts

ffmpeg -i "concat:./0.ts|./1.ts|./2.ts|./3.ts|./4.ts|./5.ts|./6.ts|./7.ts|./8.ts|./9.ts|./10.ts|./11.ts|./12.ts|./13.ts" -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4
rm *.ts

下面只要在Terminal里运行即可完成当前文件夹下的mp4合并,输出文件为output.mp4。

1
$ bash concat_mp4.sh