视频直播已经非常普遍了,推流和拉流是两个基本的技术步骤。对FFmpeg来说,推流
/拉流
分别和写文件
/读文件
没有太大不同,只是要针对性的处理一些细节。
将视频/音频流推送到服务器,常见的推流协议为RTMP
。
从服务器将视频/音频流拉取到本地播放,常见的协议有RTMP, HLS, HTTP-FLV(HDL)
等。
Real Time Messaging Protocol(RTMP), 即时消息传送协议,
Adobe为Flash播放器和服务器之间音视频数据传输开发的私有协议, 该协议针对的是Flash Video,即FLV
。
推流常用RTMP
。但是拉流由于浏览器等不再支持flash
,所以拉流场景应用受限。
HTTP Live Streaming(HLS), 是Apple提出的直播流协议。跨平台性比较好,HTML5可以直接打开播放,移动端兼容性良,但延迟比较高。
同样针对于FLV
视频格式,通过HTTP协议传输给客户端。
这不是本例子的重点,所以只是搭建一个简单的流媒体服务器用来测试拉流和推流效果。
推荐在Ubuntu或WSL2下进行搭建
安装nginx
和rtmp
模块
sudo apt install nginx libnginx-mod-rtmp
# WSL2启动nginx(Ubuntu默认安装后即启动)
sudo service nginx start
使用sudo systemctl status nginx
或浏览器打开localhost
查看nginx是否运行成功。
下载nginx
和rtmp
对应的包,安装。
这里仅做RTMP
的配置,HLS
等协议不再介绍,这不是要介绍的重点。
打开nginx配置文件
sudo vim /etc/nginx/nginx.conf
追加内容
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
allow play all;
}
}
}
测试配置是否正确并重启nginx
sudo nginx -t
sudo nginx -s reload
# 推流
ffmpeg -re -i hevc.mkv -vcodec libx264 -acodec aac -f flv rtmp://127.0.0.1:1935/live/test
# 拉流
ffplay rtmp://127.0.0.1:1935/live/test
效果如下
推流过程和转码过程是几乎相同的(如果视频源的编码和封装格式符合条件,可以直接解封装后直接发送,不需要转码等步骤),这里仅说明几处不同的地方。
创建输出AVForamtContex
时,选择flv
格式
CHECK(avformat_alloc_output_context2(&encoder_fmt_ctx, nullptr, "flv", nullptr) >= 0);
其次,如果是推送视频文件(非摄像头等),推流前要使用av_usleep(sleep_us)
控制推流速度,否则会不间断的推送帧。
编译并推理测试:
pushing xxx.mkv rtmp://127.0.0.1:1935/live/test
直接使用Player代码就可以了。