使用FFmpeg连接视频
1. 概述
ffmpeg 是一套免费的开源多媒体文件管理工具。使用ffmpeg,我们可以在不同的视频和音频格式之间进行转换。此外,我们可以更改采样率、录制流式音频和视频、调整视频大小以及连接视频。
在本教程中,我们从在 Ubuntu、CentOS 和 Debian 上安装程序的步骤开始。重要的是,我们还将演示如何使用该命令连接视频。
2. 安装ffmpeg
** ffmpeg的安装过程需要root或者sudo权限。**为了演示,让我们更新apt包列表并安装ffmpeg:
$ sudo apt update
...
$ sudo apt install ffmpeg
...
最后,让我们通过*-version打印有关ffmpeg*的信息来检查我们的安装:
$ ffmpeg -version
ffmpeg version 4.4.2-1ubuntu3 Copyright (c) 2000-2022 the FFmpeg developers
...
输出的标题显示了程序的版本,但我们也可以看到它的配置和它使用的库。
此外,我们可以使用snap 在 Debian/Ubuntu 机器上安装最新稳定版本 的ffmpeg 。
接下来,让我们转到视频连接。
3. 串联先决条件
使用ffmpeg合并视频时,可以采用多种方法 。其中有 concat 函数:
- 解复用器
- 筛选
- 协议
此外,每个用例都取决于相关视频的属性。重要的是,我们需要确保所有与编码相关的属性与我们选择的方法一致:
- 时基
- 高度和宽度
- 编解码器
- 像素格式
对于某些方法,我们必须使用具有相同编码的文件,而其他方法则允许使用不同的文件。
4. Concat 脚本解复用器
concat 脚本解 复用器通常是所有合并方法中最简单的。它非常快,并且没有质量损失。这是因为不需要解码或重新编码。
为了使用 concat demuxer 方法连接视频,我们首先创建一个文本文件,列出所有视频文件。然后我们运行一个命令来处理该列表。在本例中,我们将使用文件Kali.mp4、openLDAP.mp4和SSH.mp4。
4.1. 列出 Concat Demuxer 的文件
让我们使用printf 命令编译要在文本文件中连接的视频列表:
$ printf "file '%s'\n" *.mp4 > list.txt
该命令将当前目录中以*.mp4结尾的文件名写入list.txt*。请注意,视频文件路径应位于单引号内的新行上,并以单词file为前缀:
$ cat list.txt
file 'Kali.mp4'
file 'openLDAP.mp4'
file 'SSH.mp4'
ffmpeg按顺序读取并连接视频,因为它们出现在列表中。重要的是,第一个文件从时间戳零 (0) 开始,而随后的每个文件都从前一个文件的结束位置开始。因此,ffmpeg使用每个文件的持续时间来调整下一个文件的时间戳。
4.2. 使用 Concat Demuxer 连接
现在,让我们使用*-f concat标志来合并list.txt*文件中的视频:
$ ffmpeg -f concat -i list.txt -c copy outfile.mp4
这里,-i标志的值表示输入文件的路径。此外,-c copy确保没有重新编码。
接下来,我们添加***-safe*作为一个重要选项,其值决定是拒绝 ( 1 ) 还是接受 ( 0 ) 不安全路径**:
$ ffmpeg -f concat -safe 0 -i list.txt -c copy outfile.mp4
大多数情况下,文件路径在以下情况下是安全的:
- 没有指定协议
- 仅包含可移植字符集中的字符(字母、数字、句点、下划线和连字符)
- 名称开头没有句点
最后,ffmpeg的转码过程包括解复用、解码、编码和复用。由于我们使用的是 -c copy,因此只剩下解复用和复用。
5. Concat 多媒体过滤器
当然,我们经常有不同编码的视频。我们可以将它们与 concat 过滤器合并,因为它会在其过程中重新编码。此外,它还可以在合并之前过滤输入文件。由于要经过整个转码链,所以这种方式一般比较慢。
至关重要的是,要使 concat 过滤器正常工作,所有视频文件必须从时间戳零 (0.00) 开始。
5.1. 将视频与单个音频流连接起来
为了解释接触过滤器,我们将使用start.mkv、body.mkv和back.mkv与单个音频流:
$ ffmpeg -i start.mkv -i body.mkv -i rear.mkv -filter_complex \
"[0:v] [0:a] [1:v] [1:a] [2:v] [2:a]
concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mkv
以下是命令中发生的事情的简要说明:
- 提供带有*-i*标志的输入文件
- 使用*-filter_complex*从输入文件中选择流
- 按特定顺序选择实际流:来自第一个、第二个和第三个文件的视频和音频
- 使用过滤器concat=n=3:v=1:a=1 [v] [a]
- 将生成的音频和视频流映射到输出
在第 4 步中,我们要加入的文件数在n的值中(默认为 2)。接下来,我们跟随 v(默认为 1),它设置输出视频流的数量。同样,a(默认为 0)设置每个部分中的音频流数。它还设置输出音频流的数量。
最后,步骤 5 中的*-map标志允许在每个输出文件中选择自定义流(如果有多个)。用户可以跳过-map* 并让ffmpeg处理流选择。
5.2. 将视频与多个音频流连接起来
同样,让我们将开头、情节和结尾与两个音频流连接起来。即流 0 中的视频,流 1 和 2 中的音频:
$ ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -filter_complex \
'[0:0] [0:1] [0:2] [1:0] [1:1] [1:2] [2:0] [2:1] [2:2]
concat=n=3:v=1:a=2 [v] [a1] [a2]' \
-map '[v]' -map '[a1]' -map '[a2]' output.mkv
请注意,此示例中的第二行类似于*[0:v] [0:a] [0:a] [1:v] [1:a] [1:a] [2:v] [2:a] [2:a]* 在我们前面的例子的符号中。事实上,这表明我们有一个视频流([0:v]、[1:v]、[2:v])和双音频流([0:a][0:a]、[1: a][1:a]、[2:a][2:a])。
6. 物理级联协议
concat 协议是与ffmpeg连接视频的另一种方式。它从大量资源中读取和寻找,将每个资源视为唯一的。 但是,这种方法不适用于多种格式,包括MP4。正是这些格式的性质以及该方法的基本串联阻止了其一般应用。我们可以将 concat 协议与 MPEG 等格式一起使用,它允许文件级连接。
例如,让我们连接文件clay.mpeg、sculpt.mpeg和Mold.mpeg:
$ ffmpeg -i "concat:clay.mpeg\|sculpt.mpeg\|mold.mpeg" -c copy output.mkv
请注意,我们使用**(反斜杠)来转义管道符号。