目录
说明
总体思路
FFmpeg
Nginx
flv.js
效果展示
总结
前段时间,我写了一篇在angular框架下使用videojs播放RTMP视频流的文章,虽然播放起来流畅度较好,但仍然有一个缺陷:
由于RTMP协议本身属于Adobe公司且未开源,因而必须调用Flash才能播放并得到最好的支持,即使引入了video.js以及videojs-flash两个库作为兼容并使用了HTML5中的
同时,由于Flash本身的设计缺陷,Adobe公司和各大主流浏览器对Flash的支持也在减少甚至是直接移除了Flash插件,并趋向于采用原生HTML5标准中的
因而,本着提高用户体验和便于后期维护的方针,通过查阅资料,我采用了当下比较流行的直播方案进行改造,该方案为FFmpeg-nginx-Http-flv的组合。
如下图所示:
具体为由FFmpeg拉取海康相机的RTSP流,通过转换推出RTMP流,接着nginx主机模块拉取这个RTMP流,通过转换推出Http-flv流给浏览器中的flv.js包进行拉取播放。
下面我对这个方案的各个部分进行逐一的描述:
FFmpeg拉取海康相机的RTSP流,只需要遵循海康相机的RTSP流拉取规范,即对于FFmpeg来说需要输入输出参数,一条完整的FFmpeg输入输出参数如下所示:
ffmpeg -i rtsp://admin:[email protected]:554/h264/ch1/main/av_stream -vcodec copy -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 -f flv rtmp://127.0.0.1/Mylive/test
调出控制台,转到ffmpeg.exe程序所在的文件夹,输入或贴入上述参数即可,admin改为海康相机的登陆账号,密码改为海康相机的登陆密码。
对参数命令的部分解释,其他参数设置可以参考FFmpeg官方参数说明:
参数 |
解释 |
-i filename |
输入文件 |
-f fmt |
强制采用格式fmt |
-vcodec (codec) (copy) |
-vcodec codec 强制使用codec格式编解码方式,如-vcodec xvid 使用xvid压缩 如果用copy表示原始编解码数据必须被拷贝。 |
-acodec (codec) (copy) |
使用codec编解码 如:-acodec AAC 使用AAC音频编码 |
-ar rate int |
设置音频采样率(单位:Hz),PSP只认24000 |
-strict strictness int |
遵循的严格标准等级(from INT_MIN to INT_MAX) |
-ac channels int |
设置声道数,1就是单声道,2就是立体声,转换单声道的TVrip可以用1(节省一半容量),高品质的DVDrip就可以用2 |
-s size 1280x720 |
制定分辨率 |
-qscale int |
使用固定的视频量化标度(VBR) 以 |
ffmpeg进入推流状态:
Nginx我使用的是未央千城大神的模块方案——基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module,相较于已有的nginx-rtmp-module方案,其具有不少优势,具体可以参阅他的博文,这里是github地址。
在上面的FFmpeg环节已经对完整的FFmpeg输入输出参数进行了一个简单的介绍。我们再来看看这条参数,红色部分我未在上面作说明:
ffmpeg -i rtsp://admin:[email protected]:554/h264/ch1/main/av_stream -vcodec copy -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 -f flv rtmp://127.0.0.1/Mylive/test
这部分是推给nginx主机的链接地址:
对应Nginx主机配置文件的几个部分,用记事本打开nginx.conf进行文件:
worker_processes 4;
error_log logs/error.log error;
events {
worker_connections 1024;
}
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 10s;
server {
listen 1935;
#chunk_size 4096;
application Mylive {
live on;
gop_cache on;
}
application hls {
live on;
allow publish all;
allow play all;
hls on;
hls_path temp/hls;
hls_fragment 8s;
}
}
}
http {
server {
listen 8080;
location / {
root html;
}
location /live {
flv_live on;
chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回复
add_header 'Access-Control-Allow-Origin' '*'; #添加额外的HTTP头
add_header 'Access-Control-Allow-Credentials' 'true';
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root html;
}
location /hls {
#server hls fragments
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias temp/hls;
expires -1;
}
}
}
整个配置文件我们最关心的是这几个参数:
其他参数可以根据官方文档自行调整。
完成了前面FFmpeg和Nginx主机的搭建,我们就可以进行前端的呈现了,这里我选择的是由bilibili开源的flv.js库:Github地址。
建立一个angular项目,在项目中引入flv.js库:
npm install --save flv.js
在组件component中:
Html中加入video标签:
|
|
Typescript中引入flvjs对象并使用,值得注意的是flv.js已经对Typescript进行了适配,故直接引入即可:
import * as flvjs from 'flv.js';
title = 'app';
player: any;
flvPlayer: any;
ngOnInit(): void {
// 获取DOM对象
this.player = document.getElementById('videoElement');
if (flvjs.default.isSupported()) {
// 创建flvjs对象
this.flvPlayer = flvjs.default.createPlayer({
type: 'flv', // 指定视频类型
isLive: true, // 开启直播
hasAudio: false, // 关闭声音
cors: true, // 开启跨域访问
url: 'http://127.0.0.1:8080/live?port=1935&app=Mylive&stream=test', // 指定流链接
});
// 将flvjs对象和DOM对象绑定
this.flvPlayer.attachMediaElement(this.player);
// 加载视频
this.flvPlayer.load();
// 播放视频
this.flvPlayer.play();
}
console.log(flvjs.default.getFeatureList());
}
start(): void {
this.flvPlayer.play();
}
pause(): void {
this.flvPlayer.pause();
}
stop(): void {
this.flvPlayer.pause();
this.flvPlayer.unload();
// 卸载DOM对象
this.flvPlayer.detachMediaElement();
// 销毁flvjs对象
this.flvPlayer.destroy();
}
这里要特别说明的是在创建flvjs对象时的url连接,为了能够顺利播放视频,因此链接必须正确,这里对链接中的参数进行说明:
完整链接:http://127.0.0.1:8080/live?port=1935&app=Mylive&stream=test
参数说明:
上述参数除第3个外均可根据实际情况进行修改,但注意和FFmpeg、Nginx主机的对应。如果搭建完成无法显示图像,请首先检查参数是否正确和一一对应。
效果如下图所示:
在windows环境下运行Nginx,延迟在3~4秒左右,并注意到有丢包的现象,这个可以通过后期参数进行优化;如果是在linux环境下运行Nginx,延迟会压缩到1~2秒。该延时也和nginx-http-flv-module官方介绍的延时一致。
本文介绍了FFmpeg-nginx-Http-flv的组合实现直播的方案,并将几个“独立的轮子”组装在了一起,让大家对这种比较主流的直播方案有一个比较直观的认识,方便以后的定制和优化。
完整资源地址
希望这篇文章对你有所帮助。也感谢这几位造这几个“轮子”的大神。同时也欢迎大家给我指正文中不正确的地方,谢谢。