node通过ffmpeg将多路rtsp、rtmp流媒体转换为多端口websocket流供前端播放
这里写目录标题
1 安装node
node官网下载安装:https://nodejs.org/zh-cn/download/prebuilt-installer
2 安装ffmpeg
ffmpeg官网下载:https://ffmpeg.org/
github下载:https://github.com/FFmpeg/FFmpeg
3 【重要】使用node搭建rtsp、rtmp转码服务器(必须要提前安装ffmpeg)
// 初始化项目并安装插件node-rtsp-stream
npm init -y
npm install express
npm install node-rtsp-stream
npm install get-port
新建index.js作为主文件,代码如下
const Stream =require("node-rtsp-stream");// 引入node-rtsp-stream模块,rtsp/rtmp转码工具const express =require("express");// 引入express模块,http模块封装了http协议const getPort =require("get-port");const app =express();// 创建一个express实例,提供http服务/* **************************************************http-config************************************************ */// 设置跨域资源共享
app.use((req, res, next)=>{
res.header("Access-Control-Allow-Origin","*");// 允许任何源
res.header("Access-Control-Allow-Methods","GET, POST, OPTIONS");
res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");next();});
app.use((req, res, next)=>{
res.setHeader("Content-Security-Policy","default-src https: 'self'; script-src https: 'self' 'unsafe-inline' 'unsafe-eval' http://trusted-domain.com;");next();});/* **************************************************var************************************************ */// ws流使用端口列表let PostList =[];/* **************************************************api************************************************ *//* 关闭组件进程未关闭 */// Name of the stream, used to identify it in the API// 定义接口/* 清除某一端口任务 */
app.get("/cleraWsPort",(req, res)=>{let query = req.query;if(PostList.length ==0){
res.send({status:"success",message:"未找到该端口"});return;}
PostList.forEach((element, index)=>{if(element.port == query.port){
element.stream.stop();
PostList.splice(index,1);
res.send({status:"success",message:"关闭成功:"+ port });}else{
res.send({status:"success",message:"未找到该端口"});}});});/* 清空所有端口任务 */
app.get("/cleraWsAll",async(req, res)=>{for(let index =0; index < PostList.length; index++){await PostList[index].stream.stop();}
PostList =[];
console.log("PostList->>>", PostList);
res.send({status:"success",message:"已清空所有端口"});});/* rtmp、rtsp转weboscket流 */
app.get("/rtmpToWebsocket",(req, res)=>{let query = req.query;// 获取请求参数// 获取该端口是否已经存在,存在则返回该端口,不存在则创建可用端口for(let index =0; index < PostList.length; index++){const element = PostList[index];if(element.name == query.name){/* 存在则返回该端口 */
res.send({port: element.port,message:"已存在该端口"});return;}}// 该视频流为发现,获取可用端口,并进行发布websocket流getPort({port: getPort.makeRange(20000,21000)})// 获取可用端口.then((port)=>{try{// log
console.log("rtmpUrl->>>", query.rtmpUrl);
console.log("port->>>", port);// 创建一个Stream实例,将rtmpUrl转换为websocket流并发布到(getport)指定的端口let stream =newStream({name:"name",streamUrl: query.rtmpUrl,//query.rtmpUrl, wsPort: port,//18965,随机端口号wsPath:"/"+ query.name,//暂时无效,如果需要使用效果需要修改videoStram.js中new WebSocket函数/* ffmpegOptions,其他配置 */ffmpegOptions:{// options ffmpeg flags"-stats":"",// "-r":"60",//key,帧率"-s":"1920x1080",//帧像素},});
PostList.push({name: query.name, port, stream });}catch(error){
console.log("error->>>", error);}
res.send({ port,message:"创建成功"});}).catch((err)=>{
console.error(`Error: ${err}`);});});/* ************************************************http_listen************************************************ */// 监听3000端口
app.listen(9001,()=>{
console.log("Server running on http://localhost:9001");});
// 执行命令为
node ./index.js
传参:
rtmpUrl:‘rtmp或rtsp流媒体路径’
name:‘自己随机定义,唯一标识,name重复的rtmp或rtsp不会进行转码’
请求样例:
http://127.0.0.1:9001/rtmpToWebsocket?rtmpUrl=‘rtmp://xxx’&name=‘name1’
回参样例:
{
port:‘20000’,
message: “创建成功”
}
可以通过前端播放ws://127.0.0.1:20000了
4 前端(vue3)播放websocket流
// 安装jsmpeg-player
npm i jsmpeg-player
npm i axios
<script setup>// jsmpeg播放器import JSMpeg from'jsmpeg-player'import axios from'axios'...
axios.get(`http://127.0.0.1:9001/rtmpToWebsocket?rtmpUrl='rtmp://xxx'&name='name1'`).then((res)=>{
wsport = res.data.port
newJSMpeg.Player(`ws://127.0.0.1:`+ wsport +`/`,{bufferSize:8,videoBufferSize:20484096,canvas: document.getElementById('video')})})...</script><template><canvas :id="video" style="width: 100%; height: 100%"></canvas></template>
版权归原作者 PlanAPlanB 所有, 如有侵权,请联系我们删除。