先放一张成果图稳定军心
- 可以调声音、全屏、画中画、暂停
概述
这几天一直在搭建一个web端的直播平台,需求是无插件,低延迟,开源免费。
但是网上的教程,大多比较零散,没有整合成一套解决方案。
所以搜索了很多资料,也问了不少群里的大佬。本篇博客是一个资源整合贴,也是一个避坑贴。
最终选定的解决方案:ffmpeg推流——>nginx-http-flv-module流服务器——>flv.js前端播放器
直播流协议:http-flv。优势:延迟低,无插件播放。
案优势:所有组件均为开源免费。ffmpeg成熟、资料多。nginx-http-flv-module流服务器作者仍在维护,功能强大。flv.js是b站的开源播放器,GitHub有1W多star,可以无插件播放http-flv直播流。
nginx-http-flv-module流服务器搭建
我的服务器环境是 Ubuntu 16.04.3 LTS + nginx-1.1.17 + nginx-http-flv-module最新版。具体配置方法如下:
centos7下,nginx-1.1.17不适用,出现各种异常,最后换为nginx-1.8.1.tar.gz解决问题。浪费大量时间!
nginx和nginx-http-flv-module的编译安装
下载NGINX和nginx-http-flv-module。
将它们解压到某一路径。
打开NGINX的源代码路径并执行:
将模块编译进NGINX
./configure --add-module=/path/to/nginx-http-flv-module
make
make install
来自nginx-http-flv-module的官方GitHub
作者大da一笔带过的事,可花费我了很长时间尝试。
总结:
- /path/to应该修改成你的nginx-http-flv-module文件夹的位置。
- nginx和nginx-http-flv-module源码下载命令
wget http://nginx.org/download/nginx-1.1.17.tar.gz
git clone git://github.com/winshining/nginx-http-flv-module.git
- 解压后的两个文件夹应在同一目录下。
修改nginx的配置文件
- 打开配置文件
vim /usr/local/nginx/conf/nginx.conf #打开配置文件
- 删除原内容,复制nginx-http-flv-module的官方GitHub中的配置。在readme的这个位置:
- 一些关键配置:
worker_processes 1; #运行在Windows上时,设置为1,因为Windows不支持Unix domain socket
#worker_processes auto; #1.3.8和1.2.5以及之后的版本
#worker_cpu_affinity 0001 0010 0100 1000; #只能用于FreeBSD和Linux
#worker_cpu_affinity auto; #1.9.10以及之后的版本
error_log logs/error.log error;
#如果此模块被编译为动态模块并且要使用与RTMP相关的功
#能时,必须指定下面的配置项并且它必须位于events配置
#项之前,否则NGINX启动时不会加载此模块或者加载失败
#load_module modules/ngx_http_flv_live_module.so;
events {
worker_connections 4096;
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80;
location / {
root /var/www;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /live {
flv_live on; #打开HTTP播放FLV直播流功能
chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回复
add_header 'Access-Control-Allow-Origin' '*'; #添加额外的HTTP头
add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的HTTP头
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header 'Cache-Control' 'no-cache';
}
location /dash {
root /tmp;
add_header 'Cache-Control' 'no-cache';
}
location /stat {
#push和pull状态的配置
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /var/www/rtmp; #指定stat.xsl的位置
}
#如果需要JSON风格的stat, 不用指定stat.xsl
#但是需要指定一个新的配置项rtmp_stat_format
#location /stat {
# rtmp_stat all;
# rtmp_stat_format json;
#}
location /control {
rtmp_control all; #rtmp控制模块的配置
}
}
}
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用
log_size 1m; #log模块用来记录日志的缓冲区大小
server {
listen 1935;
server_name www.test.*; #用于虚拟主机名后缀通配
application myapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}
application hls {
live on;
hls on;
hls_path /tmp/hls;
}
application dash {
live on;
dash on;
dash_path /tmp/dash;
}
}
server {
listen 1935;
server_name *.test.com; #用于虚拟主机名前缀通配
application myapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}
}
server {
listen 1935;
server_name www.test.com; #用于虚拟主机名完全匹配
application myapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}
}
}
说明:如果采用动态编译nginx-http-flv-module模块的方式,需要将load_module “modules/ngx_http_flv_live_module.so”;前面的#去掉rtmp测试地址: rtmp://192.168.30.205:1935/myapp/mystream
http-flv测试地址: http://192.168.30.205/live?po...
- 可以用VLC测试播放
- 注意gop_cache这个参数,on时延迟高,但第一帧画面加载快。off时正好相反,延迟低,第一帧加载略慢。
- 还有很多参数我还不懂怎么调
- 配置完成!
ffmpeg推流设置
- 先,ffmpeg是个开源且强大的工具,可在官网直接下载。http://ffmpeg.org/download.html
- 再将ffmpeg的bin目录导入环境变量Path。
- 最后,cmd推流命令,详情请参考这篇资料https://www.jianshu.com/p/c141fc7881e7
- 举例,我用海康摄像头的命令:
ffmpeg -rtsp_transport tcp -i "rtsp://admin:123456@192.168.10.128.19:554/h264/ch1/sub/av_stream" -vcodec copy -acodec aac -f flv "rtmp://192.168.55.65:1935/myapp/video19"
-g 25:每隔25帧,插入一个关键帧,可提高缓冲速度。而且延迟不会明显增加。
- url根据nginx配置文件的不同,而改变。
rtmp://example.com[:port]/appname/streamname
- 注意这里用flv.js音频配置必须是 aac 否者就会报错(除非你不加入音频)
-vcodec copy -acodec aac -f flv
flv.js手把手教你对接http-flv(使用Angular7,vue的话应该类似的)
- 不懂前端的vue,node.js这些东西,或不想麻烦怎么办?直接导入在线js文件!cdn网址:https://www.bootcdn.cn/flv.js/
- flv.js的在线导入代码:
<script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.js"></script>
- 项目中上手配置
npm install --save flv.js
引入flv.js
- 直接上代码
import flvjs from 'flv.js/dist/flv.min.js'
- 上图-亲测引入flv.min.js不会报错 反之则会被语法检查错误
播放视频
- 上图
- 直接撸代码
/**
* @description flv视频播放
*/
flvVideoPlayer() {
if (this.httpSrc && flvjs.isSupported()) {
if (this.flvPlayer) {
this.flvPlayer.pause()
this.flvPlayer.unload()
this.flvPlayer.detachMediaElement()
this.flvPlayer.destroy()
this.flvPlayer = null
}
let videoElement = this.video.nativeElement
this.flvPlayer = flvjs.createPlayer({
type: 'flv',
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
isLive: true, //直播模式
hasAudio: true, //开启音频
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: false, //播放flv时,设置是否启用播放缓存,只在直播起作用。
url: this.httpSrc,
})
this.flvPlayer.attachMediaElement(videoElement)
this.flvPlayer.load()
this.flvPlayer.play()
this.flvPlayer.on('error', (err) => {
console.log('err-------------------', err)
})
}
}
- html简洁写法
<video class="video" #videoElement id="videoElementflv" controls muted>
播放失败
</video>
- 播放成果可以调声音、全屏、画中画、暂停
flv.js卸载(不这样卸载可能会有其他报错的可能,踩过坑)
- 上面代码有提及
if (this.flvPlayer) {
this.flvPlayer.pause()
this.flvPlayer.unload()
this.flvPlayer.detachMediaElement()
this.flvPlayer.destroy()
this.flvPlayer = null
}
最后一件事
如果您已经看到这里了,希望您还是点个赞再走吧~
您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。