前言
搭建流媒体服务器,实现推流和拉流。查看相关技术栈nginx、easyDarwin、webRTC。easyDarwin是由国内开源流媒体团队维护和迭代的一整套开源流媒体视频平台框架,Golang 开发,有成品的web界面,但是开源的只支持rtsp、rtmp协议(前端需要服务的支持,对前端播放不友好),不支持hls协议,放弃。
webRTC是一项开源的跨平台的实时通信技术,实现音视频传输、屏幕共享、P2P文件共享等功能。支持的功能较多,延迟极低,支持的大部分终端播放,但是配置较为复杂、需要的服务器资源和网络带宽要求比较高,有兴趣的可以了解下。
对比下来使用nginx作为流媒体服务,搭建一个简易的流媒体服务最为简单方便。
安装nginx
使用nginx安装包和docker版都可以,注意不管是安装包还是docker必须要集成rtmp模块才可以。
nginx配置信息
#user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
listen 9001;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
#HLS切片文件及索引文件拉取路径
location /live{
add_header Access-Control-Allow-Origin *;
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
# HLS切片文件目录
alias /tmp/hls;
expires -1;
}
}
}
# rtmp配置
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
##开启RTMP实时流推流和拉流服务,地址格式:rtmp://ip:1935/live/xxx
live on;
##开启HLS切片服务
hls on;
##HLS切片保存路径
hls_path /tmp/hls;
hls_fragment 2;
hls_playlist_length 5;
record off;
}
}
}
其中nginx开启了hls分片服务,并设置了分片时间和分片数量,越小维度的时间延迟就越小,但会带来访问带宽的增加,可根据实际情况进行配置。
配置好之后启动nginx,就已经启动了一个端口为1935的rtmp服务。这个时候就需要使用工具向rtmp服务中推送视频流以生成m3u8文件和切片。这里使用ffmpeg进行推送
安装ffmpeg
1.下载 FFmpeg 压缩包:
前往 FFmpeg 官方下载页面 下载最新的 FFmpeg 压缩包。你可以选择 tar 文件或 zip 文件,根据你的喜好。
2.解压缩压缩包:
使用终端进入你下载的压缩包所在的目录,然后执行以下命令来解压缩: tar xzf ffmpeg-xxx.tar.gz这将解压缩文件到一个名为 ffmpeg-xxx 的目录中,其中 xxx 是版本号。
5.将 FFmpeg 添加到 PATH:
为了方便在终端中使用 FFmpeg,你可以将 FFmpeg 可执行文件所在的目录添加到系统的 PATH 环境变量中。这样,你可以在任何目录中运行 FFmpeg 命令。
打开终端并执行以下命令,将 FFmpeg 所在的目录添加到 PATH(假设 FFmpeg 解压缩后的目录是 /path/to/ffmpeg-xxx):
echo 'export PATH=$PATH:/path/to/ffmpeg-xxx' >> ~/.bashrc
source ~/.bashrc
请确保替换 /path/to/ffmpeg-xxx 为你实际解压缩的目录的路径。
6.验证安装:
最后,你可以在终端中运行以下命令来验证 FFmpeg 是否已成功安装:
这将显示 FFmpeg 的版本信息,以确认安装是否成功。
通过ffmpeg推送nginx的rtmp服务视频流
本次操作是通过一个视频接口中的流转接复制操作(如果是本地文件、其他流来源详情命令可去ffmpeg官方了解)执行以下命令完成的流程是:访问接口,将接口中的视频复制并推送到nginx的rtmp服务中(注意:视频和音频的格式需要吻合,否则以下命令会报错)
ffmpeg -headers "User-Agent: VLC/2.2.6 LibVLC/2.2.6" -i "http://xxx.xx.xx.xx:8081/video?type=play&id=sip%3Aip7c12%40" -c:v copy -c:a aac -f flv "rtmp://10.11.148.48:1935/live/ip11c19"
执行以上命令行推送后,即可去nginx切片保存路径中查看,如果有m3u8文件和分片文件即推送成功
由此nginx将hls分片文件夹代理出来,将m3u8文件进行代理,前端即可得到m3u8文件,至此视频流配置工作即完成。
前端播放
前端使用的是hls.js作为播放插件,vue组件代码如下
<template>
<div>
<video ref="videoElement" class="video-container" controls></video>
</div>
</template>
<script>
import Hls from 'hls.js';
import router from '@/router';
export default {
name: 'LiveStreaming',
data() {
return {
videoUrl: null,
hls: null
};
},
mounted() {
this.initializeHls();
router.afterEach((to, from) => {
// 在标签页切换后执行的逻辑
if (this.hls) {
console.log('销毁');
this.hls.destroy();
this.hls = null;
}
});
},
methods: {
initializeHls() {
const src = this.$route.query.videoUrl;
const videoElement = this.$refs.videoElement;
const loadVideo = () => {
this.hls = new Hls();
this.hls.loadSource(src);
this.hls.attachMedia(videoElement);
this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
videoElement.play();
});
this.hls.on(Hls.Events.ERROR, (_, data) => {
if (data.type == "networkError") {
setTimeout(() => {
loadVideo();
}, 1000); // 1秒延迟
}
});
};
loadVideo();
},
}
}
</script>
<style scoped>
.video-container {
width: 100%;
height: auto;
}
</style>
前端拿到m3u8文件地址之后,通过hls.js进行播放一定需要注意的一点是,当使用hls执行播放之后,打开浏览器f12,可以查看到后台不断的在请求m3u8文件和分片数据,一定要查验自己平台(各个平台情况不同,但也需要检查一下,如果播放视频前端为新打开一个浏览器级的tab则无此问题)在关闭视频的时候比如关闭了tab标签、弹框等操作之后,检查后台是否还在不断请求数据,如果有需要依据自身框架情况,监测此等事件,并执行hls对象销毁操作,否则客户端和服务端都有可能有压力风险