1 个稳定版本

1.0.0 2019 年 11 月 15 日

#245 in 视频

MIT 许可证

2MB
1K SLoC

Video Ludo logo

Video Ludo

Build Status License Line of code

Video Ludo crate 是一个 Rust 语言编写的电影读取器,允许从组成电影文件的各个流中提取信息。

电影文件

一个 .mp4.ogv 等文件是视频、音频、字幕的容器;每个都是单独的流,所有这些流组合在一起形成一个可重制的电影文件。

常见的电影文件包含多种语言的字幕、多种语言的音频,甚至可能包含多种视频分辨率。

这些都是单独的流,这意味着一个文件可以包含许多同类型的流。

使用 Video Ludo

注意:请确保您的系统已安装 FFmpeg 版本 3.4。

Video Ludo 会读取您想要的任何流,并将编码的流数据转换为计算机可以直接使用的格式;这项任务在单独的线程中完成,您可以使用 StreamReaderEntry 来检索这些信息。

尽管使用很简单,但让我们一步一步来。

步骤 1

首先要做的是构造一个您想读取的 StreamInfo 列表。

let mut stream_info = Vec::new();
// Take the best resolution video stream and output the frame in RGB format (u8u8u8).
stream_info.push(StreamInfo::best_video())

步骤 2

现在让我们创建一个 MovieReader

let (mut movie_reader, mut stream_entries) = MovieReader::try_new(Path::new("resources/Ettore.ogv"), stream_info)
        .expect("Movie Reader creation fail!");

在这行代码中,我传入了电影文件的路径和之前构造的 StreamInfo 列表。作为返回值,我得到了一个 MovieReader 对象和一个 StreamReaderEntry 列表。

  • MovieReader:允许控制读取过程(播放、停止、搜索)。
  • StreamReaderEntry 允许获取 StreamReader 从指定流获取的信息。

内部,MovieReader 为每个传入的 StreamInfo 创建一个 StreamReader。一个 StreamReader 读取流信息,解码它,并将数据转换为所需的原始格式,并将其存储在缓冲区中。

在我们的例子中,我们正在读取最佳可用的视频流,要检索存储的帧,我们可以使用返回的 StreamReaderEntry 对象来访问缓冲区。

步骤 3

返回的条目对象必须从 Any 转换为 Video

let mut video = stream_entries.pop().unwrap().downcast::<Video>().unwrap();

它提供了了解流信息并检索帧的可能性。

步骤 4

我们只需要开始读取文件。

movie_reader.start_read();

就是这样! 您已在单独的线程中开始读取。

获取数据

要从video条目检索数据,我们可以使用pop函数

video.buffer_mut().pop();

该函数仅在存在数据时返回Some(&BufferedFrame),您可以从此引用读取数据,这些数据在调用finalize_pop函数之前可用。

调用finalize_pop是必要的,它所做的简单操作是将数据内存块返回。

流缓冲区

每个StreamReader的缓冲区大小是固定的;当缓冲区满时,它不会接受任何新数据,直到您调用finalize_pop。此外,每个数据(如BufferedFrame)都有一个相对于视频的秒数时间戳,可用于正确播放电影。接收到的数据按时间戳排序。

示例

您可以找到两个示例,展示了我刚描述的内容。您会注意到示例中的视频播放速度非常快。这是因为帧没有与定时器同步;实际上,这个crate的目标不是实现电影<强>播放器,而是让您(或不是)有自由去实现(或不去实现)。

示例 1

cargo run --example video_player

示例 2

cargo run --example video_player_raw

贡献

任何贡献都是开放的;目前缺少音频和字幕StreaReader的实现,因此任何PR都欢迎。

依赖项