前言
RTSP是指实时流传输协议(Real Time Streaming Protocol,RTSP)目前的浏览器还不支持接收这种协议的数据,所以是没办法做到是直接接收的,需要通过后端转流封装成新的格式推流到前端才能进行播放。
具体流程
用Nodejs调用Ffmpeg来接收RTSP协议数据流,并进行转流封装为.flv的视频格式使用websocket推流到前端,最后前端使用flv.js进行接收来实现实时RTSP流视频播放。
后端
var express = require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath("D:/Program Files (x86)/ffmpeg-4.2.2-win64-static/bin/ffmpeg");
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
function localServer() {
let app = express();
app.use(express.static(__dirname));
expressWebSocket(app, null, {
perMessageDeflate: true
});
app.ws("/rtsp/:id/", rtspRequestHandle)
app.listen(8888);
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();
ffmpeg的原生命令行较为复杂,而 fluent-ffmpeg 则将这些命令抽象为一个npm包,对于前端来说,无疑是借助这种方式上手更舒服(只不过作者已经好久没更新了。。。)
ffmpeg.setFfmpegPath 这个函数将外部的ffmpeg库载入,有全局的话可以直接写即可
ffmpeg.setFfmpegPath('ffmpeg')
前端
<script src="flv.min.js"></script>
<video id="videoElement"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',//flv格式
isLive: true,//标记为直播流
url: `ws://localhost:8888/rtsp/${1}/?url=${you rtsp url}`,
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
前端使用flv.js开源播放器。
不过这样传参会个问题,RTSP地址也带参数的话会和?url所冲突。不过也好解决用对URL地址编码和解码即可:
//前端
url: `ws://localhost:8888/rtsp/${1}/?url=${encodeURIComponent(you rtsp url)}`,
//后端
const querystring = require('querystring');
let url = querystring.unescape(req.query.url);
总结
这样一个简易的播放RTSP就实现了
最后感谢阅读