对于rtsp的视频流网上有很多种的解决方案,但是大的趋势还是利用ffmpeg的工具进行rtsp的视频解析进行一个推流,我最终选择bilibili开源的flv.js,代码十分的简单全部都在底层封装好了。实现的方式也比较容易理解,ffmpeg进行rtsp的视频流解析转为flv视频流通过websocket通信把flv的流推给前端。其中两个地方比较坑需要注意linux搭建ffmpeg比较麻烦,一定要安装编译后的版本,不能取源码。
一、搭建服务端
1、安装node
服务端主要是用node运行解析rtsp转为flv的服务。安装过程并不多说了。
2、安装ffmpeg
3、搭建后端服务
找一个文件夹创建一个package.json文件,将下面代码粘入
{
"name": "ffmpeg-server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.17.1",
"express-ws": "^4.0.0",
"ffmpeg": "0.0.4",
"fluent-ffmpeg": "^2.1.2",
"http": "0.0.0",
"websocket-stream": "^5.5.0"
}
}
然后再此文件夹运行upm install,服务器的环境搭建好了,在此文件夹创建一个index.js文件把下面代码粘入
var express = require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath("D:/Gsafety/project-demo/flvWbsockectPlayRESP/ffmpeg/bin/ffmpeg");// 这里的目录指向先前安装好的ffmpeg
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
var http = require("http");
function localServer() {
let app = express();
app.use(express.static(__dirname));
expressWebSocket(app, null, {
perMessageDeflate: true
});
app.ws("/rtsp/:id/", rtspRequestHandle)
app.listen(8888);//进行websocket通信的服务端端口
console.log("express listened")
}
function rtspRequestHandle(ws, req) {
console.log("rtsp request handle");
const stream = webSocketStream(ws, {
binary: true,
browserBufferTimeout: 1000000
}, {
browserBufferTimeout: 1000000
});
let url = req.query.url;
console.log("rtsp url:", url);
console.log("rtsp params:", req.params);
try {
ffmpeg(url)
.addInputOption("-rtsp_transport", "tcp", "-buffer_size", "102400") // 这里可以添加一些 RTSP 优化的参数
.on("start", function () {
console.log(url, "Stream started.");
})
.on("codecData", function () {
console.log(url, "Stream codecData.")// 摄像机在线处理
})
.on("error", function (err) {
console.log(url, "An error occured: ", err.message);
})
.on("end", function () {
console.log(url, "Stream end!");// 摄像机断线的处理
})
.outputFormat("flv").videoCodec("copy").noAudio().pipe(stream);
} catch (error) {
console.log(error);
}
}
localServer();
在此文件cmd的窗口运行node.js,如果打印日志出现express listened,这样服务端就搭建成功了
【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~
安装flv.js依赖
定义一个video来播放flv视频流的容器。
<video
style="width:918px;height:600px;margin-left:10px;"
ref="player"
class="centeredVideo"
controls
autoplay
width="1024"
height="576">
Your browser is too old which doesn't support HTML5 video.
</video>
ts代码:
private id='1';//websokect的通信id(自己定义一个,一个地址对应一个id)
private rtsp= 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov';//播放rtsp的地址
private player:any= null;//播放的对象
这里我在mounted的钩子函数中进行的播放操作
if (flvjs.isSupported()) {
let video = this.$refs.player;
let videoUrl=publishObjectPath.value.videoUrl;
if (video) {
this.player = flvjs.createPlayer({
type: "flv",
isLive: true,
url: videoUrl+`/rtsp/${this.id}/?url=${this.rtsp}`//这里的videoUrl我在json配置文件中进行配置连接的地址
});
this.player.attachMediaElement(video);
try {
this.player.load();
this.player.play(); // 他还有很多的函数可以看一下flv.js的官方文档
} catch (error) {
console.log(error);
};
}
}
"videoUrl": "ws://172.20.0.188:8998/streamWs" //streamWs是通过nginx进行代理
三、搭建到互联网环境上,不在同一个服务器和不同网段需要使用nginx代理
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 8998;
server_name localhost;
location /streamWs/ {
proxy_pass http://172.20.0.34:8888/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
在配置proxy_pass的时候后面不加/,会将代理的字段再拼接上去这样你的接口是通的,但是不能进行通信,加上/才会把代理字段替换代理成你要代理的地址。这样线上就可以看到效果啦!