#encoder #distributed #split #parallel #home-dir

bin+lib shepherd

一个分布式视频编码器,将文件分割成块,以便在多台机器上并行编码。

5 个版本

0.1.5 2022年9月25日
0.1.4 2020年2月29日
0.1.3 2020年1月13日
0.1.0 2019年11月27日

#152视频

MIT/Apache

46KB
507

shepherd

Latest version Documentation License

一个分布式视频编码器,将文件分割成块,以便在多台机器上并行编码。

安装

使用 Cargo,您可以这样做

$ cargo install shepherd

或者直接克隆仓库并使用以下命令编译二进制文件

$ git clone https://github.com/martindisch/shepherd
$ cd shepherd
$ cargo build --release

最新 x86-64 ELF 二进制文件的直接下载

用法

前提条件是一台或多台(您可能需要更多)计算机——我们将它们称为主机——安装并配置了 ffmpeg,以便您可以直接 SSH 进入。这意味着您需要将您的公钥 ssh-copy-id 到它们上。我仅在 Linux 上进行了测试,但如果您能成功设置 ffmpeg 和 SSH,它可能可以直接在 macOS 或 Windows 上运行,或者只需要稍作修改。

使用方法相当简单

USAGE:
    shepherd [FLAGS] [OPTIONS] <IN> <OUT> --clients <hostnames> [FFMPEG OPTIONS]...

FLAGS:
    -h, --help       Prints help information
    -k, --keep       Don't clean up temporary files
    -V, --version    Prints version information

OPTIONS:
    -c, --clients <hostnames>    Comma-separated list of encoding hosts
    -l, --length <seconds>       The length of video chunks in seconds
    -t, --tmp <path>             The path to the local temporary directory

ARGS:
    <IN>                   The original video file
    <OUT>                  The output video file
    <FFMPEG OPTIONS>...    Options/flags for ffmpeg encoding of chunks. The
                           chunks are video only, so don't pass in anything
                           concerning audio. Input/output file names are added
                           by the application, so there is no need for that
                           either. This is the last positional argument and
                           needs to be preceeded by double hypens (--) as in:
                           shepherd -c c1,c2 in.mp4 out.mp4 -- -c:v libx264
                           -crf 26 -preset veryslow -profile:v high -level 4.2
                           -pix_fmt yuv420p
                           This is also the default that is used if no options
                           are provided.

所以,如果我们有三台机器 c1、c2 和 c3,我们可以这样做

$ shepherd -c c1,c2,c3 -l 30 source_file.mp4 output_file.mp4

以将其分割成约 30 秒的片段并并行编码。默认情况下,它以 H.264 编码,CRF 值为 26,使用 veryslow 预设。如果您想为编码器提供自己的 ffmpeg 选项以获得更多控制,可以通过将其添加到调用的末尾来实现

$ shepherd -c c1,c2 input.mkv output.mp4 -- -c:v libx264 -crf 40

它是如何工作的

  1. 在您的家目录中创建一个临时目录。
  2. 提取音频并编码。这不是并行化的,但这所花费的时间与视频相比微不足道。
  3. 将视频分割成块。这可能会相对较长,因为您基本上是在将整个文件再次写入磁盘。如果能从文件中读取块并将其直接传输到主机,那会更好,但可能难以使用 ffmpeg 实现。
  4. 为每个主机启动一个管理线程和一个编码线程。管理器在远程的home目录中创建一个临时目录,并确保编码器总有东西可以编码。它会传输一个数据块,将其交给编码器处理,同时传输另一个数据块,这样编码器可以在完成工作后立即开始处理,而不浪费任何时间。但是它最多保留一个数据块作为备用,以防止慢速机器获取太多数据块,而其他机器已经完成编码。
  5. 当编码器完成工作且没有更多数据块可处理时,它将退出,管理器在终止自身之前将编码的数据块转移回来。
  6. 一旦所有编码的数据块都到达,它们将被连接起来,并添加音频流。
  7. 所有远程和本地临时目录都将被删除。

由于采用了工作窃取的分配方法,即使有些主机的速度比其他主机慢得多,也不会延迟整体操作。在最坏的情况下,最慢的机器是最后一个开始编码数据块的,在整个编码这个数据块的时间内,它仍然是唯一的工作编码器。这个窗口可以通过使用更小的数据块来轻松减少。

性能

与所有并行处理一样,Amdahl定律会出现并导致你不会仅仅因为双倍的处理能力就得到两倍的速度。采用这种方法,你需要为在开始之前将视频分成数据块、将它们传输到编码器和将结果返回以及重新组装它们而付费。尽管我应该澄清,将数据块传输到编码器只会造成直到每个编码器都得到它的第一个数据块之前的明显延迟,但后续的数据块可以在编码器工作的时候发送,这样它们就不会浪费时间等待了。返回和组装编码数据块并不需要太大的代价,因为我们处理的压缩数据要更多。

为了更好地理解权衡,我使用了我能够访问的几台计算机进行了一些测试。它们是我的主要桌面电脑,两台较旧的电脑和一台笔记本电脑。为了确定每台机器的能力,以便我们可以将实际速度与预期速度进行比较,我让每台机器使用与我用于实际工作的相同设置编码一段略短于4分钟的剪辑,这段剪辑是从我要编码的真实视频中提取的。如果你想知道为什么编码需要这么长时间,那是因为我使用了veryslow预设置来实现最大效率,尽管它肯定不值得编码时间的大量增加。但它是一个很好的模拟,如果我们使用像AV1这样的更苛刻的编解码器会是什么样子。

机器 持续时间(秒) 能力
桌面 1373 1.000
旧1 2571 0.53
旧2 3292 0.42
笔记本电脑 5572 0.25
总计 - 2.20

通过给我的桌面分配“能力”级别1,我们可以根据它们完成编码任务所需的时间来确定它们的能力,从而将它们与其他机器进行比较。通过将三台其他能力较低的机器混合在一起,我们可以略微超过系统理论编码能力的两倍。

我是在一个短剪辑上确定这些能力级别的,因为在这台能力较低的机器上编码整个视频会花费很长时间,尤其是笔记本电脑。但我仍然需要在至少一台机器上编码整个视频,以便将分布式编码进行比较。我在最快的桌面电脑上做了这件事,为了进一步验证能力级别对整个视频的有效性,我咬紧牙关在第二强大的机器上也做了同样的操作。

机器 持续时间(秒) 能力
桌面 9356 1.00
旧1 17690 0.53

现在我们有了我们想要通过并行编码来超越的基准,以及确认能力级别对整个视频是有效的。让我们看看我们可以实现多少理论上的、但无法达到的2.2倍速度提升。

并行编码视频耗时5283秒,占我最快计算机的56.5%时间,或者说是提高了1.77倍的速度。我们投入了大约两倍的计算能力,与预期两倍速度提升的目标相差不远。在这种情况下,我们利用额外资源的效率达到了80%。我还尝试并行编码短片,速度非常快,但提升速度只有1.32倍,有些令人失望。我怀疑我们用更长视频可以获得更好的结果,因为编码片段总是比创建和传输它花费的时间更长(否则分配就没有意义了)。视频越长,编码(我们可以并行化)在总处理时间中的比例就越大,这样做就越有效。

我还研究了工作如何在节点之间根据它们的处理能力进行分配。在并行编码结束时,可以确定任何给定主机编码了多少片段。

主机 片段 能力
桌面 73 1.00
旧1 39 0.53
旧2 31 0.42
笔记本电脑 19 0.26

从片段数量推断处理能力几乎与我的初步确定完全相同,证实了这一点,并证明了工作分配是高效的。

为了进一步了解系统的扩展性,我增加了两台机器,将总处理能力提升到3.29。

机器 持续时间(秒) 能力
桌面 1373 1.00
c1 2129 0.64
旧1 2571 0.53
c2 3022 0.45
旧2 3292 0.42
笔记本电脑 5572 0.25
总计 - 3.29

在这6台机器上并行编码视频耗时3865秒,占我最快计算机的41.3%时间,或者说是提高了2.42倍的速度。这里利用额外资源的效率达到了74%。正如预期的那样,虽然我们可以通过增加更多资源来加速,但我们面临着递减的回报。尽管效率下降的比率并不像可能的那样糟糕。

限制

虽然你可以使用自己的ffmpeg选项来控制视频的编码方式,但目前还没有音频的此类选项,默认为192 kb/s AAC。

许可证

根据您的选择,许可协议为以下之一

贡献

除非您明确说明,否则您根据Apache-2.0许可证定义的任何有意提交以供包含在作品中的贡献,均应按上述方式双重许可,没有任何附加条款或条件。

依赖关系

~3–11MB
~104K SLoC