在本文中,笔者将阐述 Rust 推流的基本理论知识和实现过程。本文采用的 Rust 库是 ffmpeg-sys。ffmpeg-sys 是 Rust 对 FFmpeg 的绑定(原汁原味的 C 风格)。对 C 调用 FFmpeg 熟悉的朋友,对 Rust 的调用,也不会有太多的语言障碍问题。
ffmpeg-sys crate地址是:https://crates.io/crates/ffmpeg-sys
介绍完毕,现在重温一下 ffmpeg 推流过程,请看下图:
其过程的文字版描述就是:先初始化组件和网络,然后打开输入文件获取音视频信息,在创建输出流上下文,然后将输入流的信息复制到输出流中,接下来打开输出流,写入头信息,最后循环推流。
了解了大概过程,接着去熟悉下一些特殊类型变量的创建。我们先看 avformat_open_input 函数的签名
avformat_open_input 函数需要 *mut *mut AVFormatContext、*const c_char、*mut AVInputFormat、*mut *mut AVDictionary这几个类型的参数,现在看笔者怎么创建。
创建 AVFormatContext
let mut ifmt_ctx: *mut AVFormatContext = std::ptr::null_mut();
创建 *const c_char
let input_path_cstr = CString::new("rtsp://admin:admin88@192.168.1.11:554/H264?ch=1&subtype=1").expect("to c str");
将参数传递给 avformat_open_input 函数
avformat_open_input(&mut ifmt_ctx, input_path_cstr.as_ptr(), std::ptr::null_mut(), std::ptr::null_mut());
复习完上面的知识点后,就可以开始撸代码了。笔者将完整代码放到了gitee上面,可以在线阅读,也可以clone本地。
代码地址:https://gitee.com/dev-tang/ipcp
编译与测试
cargo build
./target/debug/ipcp 'rtsp://admin:admin88@192.168.1.11:554/H264?ch=1&subtype=1' rtmp://192.168.1.200:1935/live
通过VLC,输入rtmp地址就可以查看测试效果。