Contents

使用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.mp4openLDAP.mp4SSH.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.mkvbody.mkvback.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

以下是命令中发生的事情的简要说明:

  1. 提供带有*-i*标志的输入文件
  2. 使用*-filter_complex*从输入文件中选择流
  3. 按特定顺序选择实际流:来自第一个、第二个和第三个文件的视频和音频
  4. 使用过滤器concat=n=3:v=1:a=1 [v] [a]
  5. 将生成的音频和视频流映射到输出

在第 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.mpegsculpt.mpegMold.mpeg

$ ffmpeg -i "concat:clay.mpeg\|sculpt.mpeg\|mold.mpeg" -c copy output.mkv

请注意,我们使用**(反斜杠)来转义管道符号。