小白心路历程篇,如有错误欢迎指出,感谢各位大佬
本篇包括以下内容:
①采用nginx搭建流媒体服务器,利用ffmpeg工具实现推流和转码工作。
②使用vue+原生hls.js来实现无flash播放m3u8直播流
预备知识:
linux(操作系统基本命令)
nginx(配置参数,基础语法)
docker(利用docker搭建基于rtmp模块的nginx容器)
ffmpeg(一款功能强大的视频处理工具,可以推流,转码,拉流…)
vue基础
实现效果:
vue播放一个m3u8的直播流
搭建流程步骤:
1. 提供一个hls直播流(即http://xxx.m3u8此类格式)
获取方式:
①可采用网上一些现成的hls测试网址(此方式可以跳过下面环境搭建环节,直接进入vue页面测试即可)
②可自行搭建本地化的流媒体服务器,并用ffmpeg转码成hls直播流
2. 在vue中通过引入hls.js,并编写相应代码实现直播流播放
以下为具体实现细节:
一、环境搭建
1.1. 服务端采用nginx+ffmpeg搭建
使用docker构建基于rtmp模块nginx容器
docker镜像名称:alfg/nginx-rtmp
tip:该容器内对应的的配置文件所在位置(可以根据dockerfile查获)
容器内html文件夹所在位置:/opt/nginx/html
容器内logs日志文件夹所在位置:/opt/nginx/logs
容器内nginx配置文件夹所在位置:/opt/nginx/nginx.conf
docker 启动容器参数配置如下:
docker run --name nginx-rtmp -d -p 80:80 \
-v /docker/nginx-rtmp/conf/nginx.conf:/opt/nginx/nginx.conf:ro \
-v /docker/nginx-rtmp/html:/opt/nginx/html \
alfg/nginx-rtmp
若启动后查看容器状态为exited,启动失败,可通过以下docker命令查看失败的原因:
docker logs -f 容器id
nginx中rtmp服务相关配置:
rtmp {#开启一个rtmp应用服务server {listen 1935;chunk_size 4096; #默认流切片大小# create an application with rtmpapplication live {live on;record off;hls on;hls_path /opt/nginx/html/hls;hls_fragment 2s;#在接收到推流时,自动进行流格式转换并推送到本地的hls中,具体参数可以参考ffmpeg官方参数手册#exec ffmpeg -i rtmp://localhost/live/$name -threads 1 -c:v libx264 -profile:v baseline -b:v 350K -s 640x360 -f flv -c:a aac -ac 1 -strict -2 -b:a 56k rtmp://localhost/live360p/$name;#在启动nginx时就执行以下ffmpeg命令 将一个在线的rtmp转成本地的hls流(测试使用,替换成可使用的rtmp地址即可)exec_static ffmpeg -i rtmp://xxxxx.hd -c copy -f flv rtmp://localhost/hls360p/bk;}application hls360p {live on;hls on;#hls流保存位置,将该目录映射到宿主主机方便查看hls_path /opt/nginx/html/hls2;hls_fragment 2s;}}
}http {access_log /dev/stdout combined;ssl_ciphers HIGH:!aNULL:!MD5;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;server {listen 80;location /hls {types {application/vnd.apple.mpegurl m3u8;video/mp2t ts;}#hls的访问实际路径,例如访问http://localhost/hls/${name}.m3u8 则会访问对应目录下的m3u8文件alias /opt/nginx/html/hls2;expires -1;add_header Cache-Control no-cache;#设置允许跨域访问add_header Access-Control-Allow-Origin *;}}
}
踩坑记录:如果是在window操作下的nginx-rtmp模块,则配置中的exec_static指令是不生效的。可通过安装ffmpeg然后以命令行的形式实现推流。
二、客户端实现
采用vue+原生hls实现无flash播放m3u8
在html中引入hls.js,注意,是在html页面中直接全局引入
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
在hls.vue中采用video+原生hls实现监控播放
<template><div id="hls"><video id="video" muted></video></div>
</template>
<script>
export default {name: 'hls-video',components: {},data() {return{}},methods: {//初始化video initVideo () {let video = document.getElementById('video')if(Hls.isSupported()) {let hls = new Hls()//该hls地址为nginx配置中的地址hls.loadSource('http://172.16.1.72/hls/bk.m3u8')hls.attachMedia(video)hls.on(Hls.Events.MANIFEST_PARSED,()=>{video.play()});}else if (video.canPlayType('application/vnd.apple.mpegurl')) {video.src = 'http://172.16.1.72/hls/bk.m3u8'video.addEventListener('loadedmetadata',function() {video.play()})}}},created() {},mounted() {this.initVideo()},computed: {},watch: {}
}
</script>
<style scoped>
</style>
剩下注册路由访问即可。
该方式好处是,原生,简单,一个video标签即可。后续可自行进行vue组件二次封装。
三、思路梳理
3.1. 步骤
①使用ffmpeg进行推流和格式转换,使用nginx做流媒体服务器
②流媒体服务器通过映射路径实现转换后的视频流访问
3.2. 网上还有一种则是采用后端websocket+ffmpeg+flv.js(B站开源的视频直播框架)的解决方案。道理也是相通的,利用ffmpeg进行转码实现无flash播放。
2020年 chrome已经默认屏蔽flash播放了