前言
工作需要,记录一下前后端推拉流方案,基于HTTP-FLV协议,使用node + flv.js + ffmpeg进行前后端交互。
此方案为demo版,目的是打通前后端链路,项目应用正在研究中。
步骤
1.安装ffmpeg
后端推流需要借助ffmpeg流媒体服务器,需要在本机安装,安装方式参考如下:
参考:https://zhuanlan.zhihu.com/p/324472015添加链接描述
2.前端代码实现
引入flv.js,更多用法参照官网
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<video id="videoElement"></video>
<button id="btn">click</button>
<script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
<script>
const btn = document.getElementById("btn");
btn.addEventListener("click", function () {
if (flvjs.isSupported()) {
var videoElement = document.getElementById("videoElement");
var flvPlayer = flvjs.createPlayer({
type: "flv",
isLive: true,
// 在线视频流,20230926亲测可用
url: "ws://127.0.0.1:9999/rtsp/78910/?url=rtmp://ns8.indexforce.com/home/mystream",
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
});
</script>
</body>
</html>
3.后端代码实现
后端项目自行构建,这里只提供js文件代码;
借助了express,websocket,ffmpeg组件,需要自行安装;
整体逻辑:建立前后端socket链接–》获取页面传过来的视频流–》调用ffmpeg解析并推流
var express = require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
ffmpeg.setFfmpegPath("ffmpeg");
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
var http = require("http");
// config
let rtspServerPort = 9999;
function localServer() {
let app = express();
app.use(express.static(__dirname));
expressWebSocket(app, null, {
perMessageDeflate: true,
});
app.ws("/rtsp/:id/", rtspRequestHandle);
app.listen(rtspServerPort);
console.log("express listened on port : " + rtspServerPort);
}
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();
4.结果
点击按钮后加载视频