nginx-http-flv-module使用鉴权完整版
nginx-http-flv-module基于nginx实现的FLV直播模块。本文介绍怎么使用该模块进行直播和鉴权。
简要说明:直播模块分为两块——推流和拉流。 nginx-http-flv-module就是开创直播间并处理这里流数据用的。
一、安装
前提是你得先安装好nginx,这里对nginx的安装不做概述。
1.下载地址: https://github.com/winshining/nginx-http-flv-module
将包下下来放到你的linux服务器上,至于位置理论上是可以放到任意位置的。
2.进入nginx的安装目录——configure所在目录
我这里将包放到了configure同级目录,如下图:
3.将模块添加至nginx
执行命令:
./configure --add-dynamic-module=/usr/local/nginx/nginx-http-flv-module
注:/usr/local/nginx/nginx-http-flv-module改为你的模块路径
继续执行:
sudo make
在继续执行:
sudo make install
命令说明:加入模块-》重新编译nginx-》重新安装nginx
4.nginx配置
在nginx配置文件加入两段配置即可: 1.
rtmp {
server {
listen 1935;
application live {
live on;
}
}
}
2
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /live {
flv_live on;
chunked_transfer_encoding on; #open 'Transfer-Encoding: chunked' response
add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header
add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header 'Cache-Control' 'no-cache';
}
}
说明:
第一段rtmp跟events和http同级,放到events后面就好(其实放哪都可以,只要层级对了)
第二段找个server下面放(这里放的是80下面)
5.测试
重点:将nginx先stop在restart.
输入下面指令
netstat -anp | grep 1935
如果出现进程说明该模块安装好了,下面就进行推流阶段。
二、FFmpeg安装
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。在这里用作推流。 我之前说过有推流和拉流两部分
在这里再说明一下:
FFmpeg(推流)——》nginx-http-flv-module(直播模块)——》拉流——》显示视频
1.下载
官网下载地址:http://ffmpeg.org/download.html 选择最新的下载 下载好后解压放到你的linux上(理论是可以任意位置)
二.安装 进入FFmpeg目录中,configure同级目录 执行下面命令:
./configure --enable-shared --prefix=/usr/local/ffmpeg --disable-yasm
说明:
–prefix表示程序安装的目录,这里设为/usr/local/ffmpeg。
–enable-shared表示生成动态链接库,可以供以后编程使用,同时生成的可执行程序也依赖这些动库。
–disable-yasm表示禁用yasm。
继续执行
sudo make
在继续执行
sudo make install
编译过程有点长,耐心等待完成之后执行 cd /monchickey/ffmpeg/ 进入安装目录,查看一下发现有bin,include,lib,share这4个目录,其中bin是ffmpeg主程序二进制目录,include是C/C++头文件目录,lib是编译好的库文件目录,share是文档目录,然后进入bin目录,执行 ./ffmpeg -version 查看当前版本的详细信息
默认情况下一般会报libavdevice.so.58: cannot open shared object file: No such file or directory
原因是lib目录未加载到链接到系统库中,系统ld目录列表在/etc/ld.so.conf中,打开文件会发现,里面引用了/etc/ld.so.conf.d/下面所有的.conf文件,比如mariadb-x86_64.conf我们只需要创建一个文件并写入lib路径即可,执行命令: vim /etc/ld.so.conf.d/ffmpeg.conf 然后添加一行内容: /usr/local/ffmpeg/lib 之后保存并退出,然后执行 ldconfig 使配置生效,现在再次执行 ./ffmpeg -version 显示就正常了
如图所示:
到此就安装成功了
三.测试
推流 两种方式: ????准备摄像头的rtsp/rtmp源地址 ????准备一个mp4文件
我这里测试就直接用mp4来测试了
sudo ./ffmpeg -re -stream_loop -1 -i /usr/local/test.mp4 -vcodec copy -acodec copy -f flv -y rtmp://localhost:1935/live/zz
说明: /usr/local/test.mp4 改为你map4的地址 rtmp://localhost:1935/live/zz中的1935和live是你在rtmp配置的,zz你可以理解为指定个直播间名字,可以随意指定
附加一下摄像头推流方式(这里的摄像头是海康):
ffmpeg -re -i rtsp://192.168.1.64/Streaming/Channels/1 -c copy -f flv rtmp://localhost:1935/live/9527
ffmpeg -re -rtsp_transport tcp -i "rtsp://admin:password@192.168.1.64:554/h264/ch1/main/av_stream?videoCodecType=H.264" -vcodec copy -acodec aac -f flv -y rtmp://192.168.31.91:1935/live/9527
说明: admin-》摄像头用户名(默认admin) password-》摄像头密码(自己设置的) 192.168.1.64-》摄像头ip(默认192.168.1.64) 554-》rtsp端口(默认554)
拉流 两种方式: ????rtmp地址 ????http地址
下载一个VLC media player,去官网下载 媒体—》打开网络串流—》网络 输入rtmp地址:rtmp://localhost:1935/live/zz 输入http地址:http://localhost:80/live?port=1935&app=live&stream=zz
如下图所示:
出现视频则说明成功。
四.扩展—flv.sj
这点属于扩展,讲的是用vue播放直播 flv.sj 主要用到了这个
https://github.com/Bilibili/flv.js 通过VUE播放实时视频流 npm install --save flv.js
<template>
<div id="app">
<video
id="videoLive"
crossorigin="anonymous"
controls
autoplay
width="100%"
height="100%"
style="object-fit: fill"
></video>
</div>
</template>
<script>
import flvjs from "flv.js";
export default {
name: "App",
data() {
return {
flvPlayer: null,
};
},
mounted() {
this.createVideo('http://192.168.5.177/live?port=7933&app=myapp&stream=room',"videoLive")
},
methods: {
createVideo(url, elementId) {
if (flvjs.isSupported()) {
let videoElement = document.getElementById(elementId);
this.flvPlayer = flvjs.createPlayer({
type: "flv",
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
isLive: true, //直播模式
hasAudio: false, //关闭音频
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: true, //播放flv时,设置是否启用播放缓存,只在直播起作用。
url: url,
});
this.flvPlayer.attachMediaElement(videoElement);
this.flvPlayer.load();
this.flvPlayer.play();
}
},
},
};
</script>
<style>
#app {
width: 640px;
height: 480px;
border: 1px red solid;
margin: 0 auto;
}
</style>
此时页面就能够正常的播放摄像头的实时视频流了,不过这里两个问题,第一个问题是视频延时大概在6~7秒左右,这是延时是我们无法接受的,第二个问题是当我们在浏览器切换了一个标签后,我们发现视频默认暂停了,当我们再次回到页面的时候就需要手动调整进度条,这个是不行的不够友好。下面先来解决第一个延时问题。 这个延时问题主要是因为ffmpeg在对视频进行转码时的延迟,这时我们来优化ffmpeg转码参数,命令如下。
sudo ./ffmpeg -re -stream_loop -1 -i /usr/local/test.mp4 -vcodec copy -acodec copy -threads 5 -preset ultrafast -max_delay 100000 -f flv -y rtmp://localhost:1935/live/zz
对比第一条参数我们多加了 -threads 5 -preset ultrafast -max_delay 100000 参数,-threads 5的意思是 设置编解码等工作的线程数,线程数多了速度自然比一个线程处理的快 -preset ultrafast 用来指定视频的输出质量,它共有以下几个可以用的值:
ultrafast 超快的 superfast 超高速的 veryfast 非常快 faster 更快 fast 快 medium 中等 slow 缓慢的 slower 较慢的 veryslow 非常慢
我们这里使用的是 ultrafast 超快的,-max_delay 100000 表示指定视频的最大延迟,这里设置100ms。调优参数就设置到这里,下面设置flv.js的参数:
createVideo(url, elementId) {
if (flvjs.isSupported()) {
let videoElement = document.getElementById(elementId);
this.flvPlayer = flvjs.createPlayer({
type: "flv",
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
isLive: true, //直播模式
hasAudio: false, //关闭音频
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: true, //播放flv时,设置是否启用播放缓存,只在直播起作用。
url: url,
}, {
enableStashBuffer: false, //禁用IO存储缓存区
});
this.flvPlayer.attachMediaElement(videoElement);
this.flvPlayer.load();
this.flvPlayer.play();
}
}
主要参数为:
{
enableStashBuffer: false, //禁用IO存储缓存区
}
下面重新执行命令,并刷新页面,查看延迟效果会发现顺畅很多。 可以发现目前延迟大概在500ms左右,如果觉得还有有点慢的话可以调整转码的分辨率和视频大小等参数,可以自行百度查找。
下面解决第二个问题,切换标签页后页面自动暂停问题。
mounted() {
this.createVideo('http://192.168.5.177/live?port=7933&app=myapp&stream=room',"videoLive")
this.monitorVideo()
},
methods: {
createVideo(url, elementId) {
if (flvjs.isSupported()) {
let videoElement = document.getElementById(elementId);
this.flvPlayer = flvjs.createPlayer({
type: "flv",
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
isLive: true, //直播模式
hasAudio: false, //关闭音频
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: true, //播放flv时,设置是否启用播放缓存,只在直播起作用。
url: url,
}, {
enableStashBuffer: false, //禁用IO存储缓存区
});
this.flvPlayer.attachMediaElement(videoElement);
this.flvPlayer.load();
this.flvPlayer.play();
}
},
monitorVideo(){
let videoElement = document.getElementById("videoLive");
videoElement.onpause =function(){
//监听video标签是否暂停,如果暂停就让他继续播放
if (videoElement.paused){
videoElement.play()
}
}
}
},
主要参数如下: 其思想就是监听video标签是否暂停,如果暂停了就让他继续播放,这就相当于做了一个后台播放效果出来了。
掉线重连 这时如果视频服务器突然掉线了怎么办,解决方法如下。
methods: {
createVideo(url, elementId) {
if (flvjs.isSupported()) {
let videoElement = document.getElementById(elementId);
this.flvPlayer = flvjs.createPlayer(
{
type: "flv",
enableWorker: true, //浏览器端开启flv.js的worker,多进程运行flv.js
isLive: true, //直播模式
hasAudio: false, //关闭音频
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: true, //播放flv时,设置是否启用播放缓存,只在直播起作用。
url: url,
},
{
enableStashBuffer: false, //禁用IO存储缓存区
}
);
this.flvPlayer.attachMediaElement(videoElement);
if (url != null && url !== "") {
this.flvPlayer.load();
this.flvPlayer.play();
}
let _then = this;
// 重连 监听flvPlayer异常
this.flvPlayer.on(flvjs.Events.ERROR, function (errType, errDetail) {
console.error("连接异常,正在尝试重新连接", errType, errDetail);
//如果flvPlayer不为空
if (_then.flvPlayer) {
_then.reloadVideo(_then.flvPlayer, elementId, url);
}
});
}
},
reloadVideo(flvPlayer, elementId, url) {
this.destoryVideo(flvPlayer);
// 重新执行createVideo方法
this.createVideo(url, elementId);
},
//销毁flvPlayer
destoryVideo(flvPlayer) {
flvPlayer.pause();
flvPlayer.unload();
flvPlayer.detachMediaElement();
flvPlayer.destroy();
flvPlayer = null;
},
monitorVideo() {
let videoElement = document.getElementById("videoLive");
videoElement.onpause = function () {
//监听video标签是否暂停,如果暂停就让他继续播放
if (videoElement.paused) {
videoElement.play();
}
};
},
}
主要代码如下: 其思想就是通过flvPlayer的on方法监听flvjs的异常,如果出现异常就先将当前的flvPlayer销毁,然后重新调用createVideo方法,不过on监听时间为15秒,也就是说断线15秒以后才会重新连接。
五.总结
累了。。。毁灭吧
|