1 个稳定版本
1.0.0 | 2019 年 11 月 15 日 |
---|
#245 in 视频
2MB
1K SLoC
Video Ludo
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都欢迎。