node通过ffmpeg将多路rtsp、rtmp流媒体转换为多端口websocket流供前端播放 ...

打印 上一主题 下一主题

主题 946|帖子 946|积分 2838

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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)

  1. // 初始化项目并安装插件node-rtsp-stream
  2. npm init -y
  3. npm install express
  4. npm install node-rtsp-stream
  5. npm install get-port
复制代码
新建index.js作为主文件,代码如下
  1. const Stream = require("node-rtsp-stream"); // 引入node-rtsp-stream模块,rtsp/rtmp转码工具
  2. const express = require("express"); // 引入express模块,http模块封装了http协议
  3. const getPort = require("get-port");
  4. const app = express(); // 创建一个express实例,提供http服务
  5. /* **************************************************http-config************************************************ */
  6. // 设置跨域资源共享
  7. app.use((req, res, next) => {
  8.   res.header("Access-Control-Allow-Origin", "*"); // 允许任何源
  9.   res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
  10.   res.header(
  11.     "Access-Control-Allow-Headers",
  12.     "Origin, X-Requested-With, Content-Type, Accept"
  13.   );
  14.   next();
  15. });
  16. app.use((req, res, next) => {
  17.   res.setHeader(
  18.     "Content-Security-Policy",
  19.     "default-src https: 'self'; script-src https: 'self' 'unsafe-inline' 'unsafe-eval' http://trusted-domain.com;"
  20.   );
  21.   next();
  22. });
  23. /* **************************************************var************************************************ */
  24. // ws流使用端口列表
  25. let PostList = [];
  26. /* **************************************************api************************************************ */
  27. /* 关闭组件进程未关闭 */
  28. // Name of the stream, used to identify it in the API
  29. // 定义接口
  30. /* 清除某一端口任务 */
  31. app.get("/cleraWsPort", (req, res) => {
  32.   let query = req.query;
  33.   if (PostList.length == 0) {
  34.     res.send({ status: "success", message: "未找到该端口" });
  35.     return;
  36.   }
  37.   PostList.forEach((element, index) => {
  38.     if (element.port == query.port) {
  39.       element.stream.stop();
  40.       PostList.splice(index, 1);
  41.       res.send({ status: "success", message: "关闭成功:" + port });
  42.     } else {
  43.       res.send({ status: "success", message: "未找到该端口" });
  44.     }
  45.   });
  46. });
  47. /* 清空所有端口任务 */
  48. app.get("/cleraWsAll", async (req, res) => {
  49.   for (let index = 0; index < PostList.length; index++) {
  50.     await PostList[index].stream.stop();
  51.   }
  52.   PostList = [];
  53.   console.log("PostList->>>", PostList);
  54.   res.send({ status: "success", message: "已清空所有端口" });
  55. });
  56. /* rtmp、rtsp转weboscket流 */
  57. app.get("/rtmpToWebsocket", (req, res) => {
  58.   let query = req.query; // 获取请求参数
  59.   // 获取该端口是否已经存在,存在则返回该端口,不存在则创建可用端口
  60.   for (let index = 0; index < PostList.length; index++) {
  61.     const element = PostList[index];
  62.     if (element.name == query.name) {
  63.       /* 存在则返回该端口 */
  64.       res.send({ port: element.port, message: "已存在该端口" });
  65.       return;
  66.     }
  67.   }
  68.   // 该视频流为发现,获取可用端口,并进行发布websocket流
  69.   getPort({ port: getPort.makeRange(20000, 21000) }) // 获取可用端口
  70.     .then((port) => {
  71.       try {
  72.         // log
  73.         console.log("rtmpUrl->>>", query.rtmpUrl);
  74.         console.log("port->>>", port);
  75.         // 创建一个Stream实例,将rtmpUrl转换为websocket流并发布到(getport)指定的端口
  76.         let stream = new Stream({
  77.           name: "name",
  78.           streamUrl: query.rtmpUrl, //query.rtmpUrl,
  79.           wsPort: port, //18965,随机端口号
  80.           wsPath: "/" + query.name, //暂时无效,如果需要使用效果需要修改videoStram.js中new WebSocket函数
  81.           /* ffmpegOptions,其他配置 */
  82.           ffmpegOptions: {
  83.             // options ffmpeg flags
  84.             "-stats": "", //
  85.             "-r": "60", //key,帧率
  86.             "-s": "1920x1080", //帧像素
  87.           },
  88.         });
  89.         PostList.push({ name: query.name, port, stream });
  90.       } catch (error) {
  91.         console.log("error->>>", error);
  92.       }
  93.       res.send({ port, message: "创建成功" });
  94.     })
  95.     .catch((err) => {
  96.       console.error(`Error: ${err}`);
  97.     });
  98. });
  99. /* ************************************************http_listen************************************************ */
  100. // 监听3000端口
  101. app.listen(9001, () => {
  102.   console.log("Server running on http://localhost:9001");
  103. });
复制代码
  1. // 执行命令为
  2. 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流

  1. // 安装jsmpeg-player
  2. npm i jsmpeg-player
  3. npm i axios
复制代码
  1. <script setup>
  2. // jsmpeg播放器
  3. import JSMpeg from 'jsmpeg-player'
  4. import axios from 'axios'
  5. ...
  6. axios.get(`http://127.0.0.1:9001/rtmpToWebsocket?rtmpUrl='rtmp://xxx'&name='name1'`).then((res) => {
  7.         wsport = res.data.port
  8.                 new JSMpeg.Player(`ws://127.0.0.1:` + wsport + `/`, {
  9.         bufferSize: 8,
  10.         videoBufferSize: 20484096,
  11.         canvas: document.getElementById('video')
  12.    })
  13. })
  14. ...
  15. </script>
  16. <template>
  17. <canvas :id="video" style="width: 100%; height: 100%"></canvas>
  18. </template>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张国伟

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表