因为最近项目有直接连接海康摄像头的实时视频播放需求,海康的子码流是RTSP是不能自己在浏览器中播放,之前也没接触过此方面的技术和需求,特此记录一下,node.js使用ffmpeg将海康的子码流进行转码播放。话不多说,直接上代码

node.js

var express =  require("express");
var expressWebSocket = require("express-ws");
var ffmpeg = require("fluent-ffmpeg");
const fs = require('fs');
const path = require('path');
const http = require('http');
ffmpeg.setFfmpegPath("/opt/homebrew/Cellar/ffmpeg/6.0/bin/ffmpeg");
var webSocketStream = require("websocket-stream/stream");
function localServer() {let app = express();app.use(express.static(__dirname));expressWebSocket(app, null, {perMessageDeflate: true});app.ws("/rtsp/:id/", requestHandle)app.listen(8888);console.log("express listened")
}
function requestHandle(ws, req) {// 这里是针对回放视频的条件参数let url = req.query.url;if(req.query.starttime && req.query.endtime){url = url + '?starttime=' + req.query.starttime + '&endtime=' + req.query.endtime}console.log("rtsp url:", url);console.log("rtsp params:", req.params);if(url.indexOf('rtsp') > -1){rtspRequestHandle(url, ws)}else {videoRequestHandle(url)}}/*** 将视频文件输出为指定码流* 并分为主子码流,主码流传给net服务,子码流传给vue*/
function videoRequestHandle(url){// 指定格式主码流配置const mainStreamConfig = {codec: 'h264',bitRate: '3000k',resolution: '1280x720',fps: 25,};// 指定格式子码流配置const subStreamConfig = {codec: 'h264',bitRate: '1000k',resolution: '640x360',fps: 25,};// 循环处理每个视频文件fs.readdir(url, (err, files) => {if (err) {console.error(err);return;}files.forEach(file => {const filePath = path.join(url, file);// 使用 fluent-ffmpeg 进行视频编解码处理ffmpeg(filePath)// 主码流.outputOptions(`-c:v ${mainStreamConfig.codec}`,`-b:v ${mainStreamConfig.bitRate}`,`-s ${mainStreamConfig.resolution}`,`-r ${mainStreamConfig.fps}`).output(`${filePath}_main.mp4`)// 子码流.outputOptions(`-c:v ${subStreamConfig.codec}`,`-b:v ${subStreamConfig.bitRate}`,`-s ${subStreamConfig.resolution}`,`-r ${subStreamConfig.fps}`).output(`${filePath}_sub.mp4`).on('end', () => {// 处理完成后发送主码流给 .net 服务sendToDotNet(`${filePath}_main.mp4`);// 读取子码流文件并发送给 Vue 客户端const subStream = fs.createReadStream(`${filePath}_sub.mp4`);sendToVue(subStream, `${file}_sub.mp4`);}).run();});});
}function sendToDotNet(filePath) {// 将文件以Buffer对象形式读取const fileBuffer = fs.readFileSync(filePath);// 构造HTTP请求选项const options = {hostname: 'your.net.service.host',port: 80,path: '/api/analyze_video',method: 'POST',headers: {'Content-Type': 'application/octet-stream', // 暂时以二进制流方式发送'Content-Length': fileBuffer.length,}};// 发送HTTP请求const req = http.request(options, res => {console.log(`statusCode: ${res.statusCode}`);res.on('data', d => {process.stdout.write(d);});});req.on('error', error => {console.error(error);});// 将文件数据写入请求主体req.write(fileBuffer);req.end();
}
// 实现将子码流传输给 Vue 客户端的逻辑代码
// function sendToVue(stream, fileName) {// }// 针对摄像头rtsp转码
function rtspRequestHandle(url, ws){const stream = webSocketStream(ws, {binary: true,browserBufferTimeout: 1000000}, {browserBufferTimeout: 1000000});try {ffmpeg(url).addInputOption('-analyzeduration', '100000', '-max_delay', '1000000')// .addInputOption("-rtsp_transport", "tcp", "-buffer_size", "1024000")  // 这里可以添加一些 RTSP 优化的参数.on("start", function () {console.log(url, "Stream started.");}).on("codecData", function () {console.log(url, "Stream codecData.")// 摄像机在线处理}).on("error", function (err, stdout, stderr) {console.log(url, "An error occured: ", err.message);console.error(stdout);console.error(stderr);}).on("end", function () {console.log(url, "Stream end!");// 摄像机断线的处理}).outputFormat("flv").videoCodec("copy").noAudio().pipe(stream);} catch (error) {console.log(error);}
}localServer();

vue中调用

实时播放

<template><div class="wrap"><video v-show="isShow" class="video" muted autoplay ref="player"></video></div>
</template>export default {name: 'RTSPPlayer',props: {},data() {return {}},mounted () {// 如果浏览器支持flvjs,则执行相应的程序if (flvjs.isSupported()) {// 准备监控设备流地址let url = this.videoUrlif(this.videoUrl.indexOf('rtsp') != -1){url = localStorage.getItem('VUE_APP_VIDEO_SOCKET') + 'hikvision/?url=' + this.videoUrl}console.log('ws:url------>', url)// 创建一个flvjs实例// 下面的ws://localhost:8888换成你搭建的websocket服务地址,后面加上设备流地址this.player = flvjs.createPlayer({type: 'flv',isLive: true,url: url})this.player.on('error', (e) => {console.log('transcoding error: ', e)return false})// 将实例挂载到video元素上面this.player.attachMediaElement(this.$refs.player)try {// 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了this.player.load()this.player.play()} catch (error) {console.log('play error: ', error)}}},beforeDestroy () {// 页面销毁前 关闭flvjsthis.player.destroy()}
};
</script>

历史视频回放

与实时视频播放类似路径不同,需带时间区间参数,这些网上有说明,下面代码仅供参考,具体业务具体分析。
注:这里回放可能视频不会显示,需检查视频后台的视频流格式,需改为H264

getVideo(rtspUrl){// 如果浏览器支持flvjs,则执行相应的程序if (flvjs.isSupported()) {if(rtspUrl.indexOf("rtsp") != -1){rtspUrl = localStorage.getItem('VUE_APP_VIDEO_SOCKET') + 'hikvision/?url=' +rtspUrl.replace("Channels", "tracks").slice(0, -1) + '1&starttime=' + this.beginTime + '&endtime=' + this.endTime}console.log('ws:url------>', rtspUrl)// 创建一个flvjs实例// 下面的ws://localhost:8888换成你搭建的websocket服务地址,后面加上设备流地址this.player = flvjs.createPlayer({type: 'flv',isLive: true,url: rtspUrl})this.player.on('error', (e) => {console.log(e)})// 将实例挂载到video元素上面this.player.attachMediaElement(this.$refs.player)try {// 开始运行加载 只要流地址正常 就可以在h5页面中播放出画面了this.player.load()this.player.play()} catch (error) {console.log(error)}}},

后期还会更新使用node-media-server搭建直播流服务
直播流地址已更新
若代码有什么不足可指出优化,有什么疑问,欢迎评论区讨论

node.js使用ffmpeg将RTSP转码服务相关推荐

  1. Node.js联机游戏——gobang五子棋(客户端+服务端+websocket的双人游戏)

    Node.js联机游戏--gobang五子棋(客户端+服务端+websocket的双人游戏) 五子棋的基本结构 ~·基本画图 ~·判断机制 ~···横向/竖向判断 ~···斜向判断 搭建服务器阶段 ~ ...

  2. 计算机毕业设计Node.js校园二手拍卖网(源码+程序+LW+远程调试)

    项目运行 环境配置: Node.js最新版+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue. 项目技术: Express框架 + Node.js+ Vue 等 ...

  3. 计算机毕业设计Node.js+Express智慧工地管理系统(源码+程序+lw+远程调试)

    项目运行 环境配置: Node.js最新版+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue. 项目技术: Express框架 + Node.js+ Vue 等 ...

  4. 计算机毕业设计Node.js+Express幼儿健康管理系统(源码+程序+lw+远程调试)

    项目运行 环境配置: Node.js最新版+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue. 项目技术: Express框架 + Node.js+ Vue 等 ...

  5. 计算机毕业设计Node.js+Express学生健康管理系统(源码+程序+lw+远程调试)

    项目运行 环境配置: Node.js最新版+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue. 项目技术: Express框架 + Node.js+ Vue 等 ...

  6. 计算机毕业设计Node.js+Vue酒店管理系统(程序+源码+LW+部署)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: Node.js+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue ...

  7. 计算机毕业设计Node.js+Express银行理财推荐系统(源码+程序+lw+远程调试)

    项目运行 环境配置: Node.js最新版+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue. 项目技术: Express框架 + Node.js+ Vue 等 ...

  8. Nginx+rtmp+ffmpeg搭建视频转码服务

    第一步,安装nginx-rtmp-module 模块 因为nginx搭建流媒体服务需要用到 nginx-rtmp-module 模块,所以先安装nginx-rtmp-module # cd /root ...

  9. Day 27: Restify —— 在Node.js中构建正确的REST Web服务

    今天决定学一个叫做restify的Node.js模块.restify模块使得在Node.js中写正确的REST API变得容易了很多,而且它还提供了即装即用的支持,如版本控制.错误处理.CORS和内容 ...

最新文章

  1. 谈谈对于企业级系统架构的理解(zz)
  2. Swift3.0语言教程删除字符与处理字符编码
  3. linux体验服务器,体验Ubuntu做服务器
  4. python退出mainloop_python - Python Turtle mainloop()的用法 - 堆栈内存溢出
  5. 视网膜脱离oct报告图_刚刚,爱尔眼科发布关于艾芬医生诊疗过程的核查报告
  6. adb 启动命令,pc启动两个微信,INSTALL_FAILED_CONFLICTING_PROVIDER
  7. 基于QQ服务器JavaMail邮箱SSL密码第三方发送邮件
  8. c语言复杂数据类型存储,C语言基础-复杂数据类型
  9. SubSonic:一个对象的引用是必需的对于非静态字段
  10. RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility.
  11. Spring Cloud学习笔记---一分钟知晓Zuul
  12. 中国古代哲学 (基础知识)
  13. 中兴如何远程服务器时间同步,IPTV系统时钟同步功能配置方法——中兴
  14. 不一样的课程表,不一样的Excle--用Excle进行设计(42):排序所演绎的数据逻辑
  15. 女子租房有钱交房租 男中介竟然不收她钱_无界财富
  16. 【工具】1063- 前端40+精选VSCode插件,总有几个你未拥有!
  17. bochs linux 安装软件,bochs linux镜像
  18. ISME:华中农大李霞组发现大豆根际微生物组变化与根瘤菌共生效率的关系
  19. 手机之家在线签名_手写签名在线生成器在线-手写签名在线生成器在线
  20. android 截取视频部分内容,安卓手机如何剪裁视频 手机视频裁剪多余部分 - 迅捷录屏大师...

热门文章

  1. 高速PCB设计应避免过孔via将参考平面打碎 形成分割槽 造成信号完整性问题
  2. 【OpenCV 例程 300篇】247. 特征检测之最大稳定极值区域(MSER)
  3. 点云交互式可视化mayavi
  4. 限定时间内数字增长动画,先快后慢
  5. 大数据技术发展史:大数据的前世今生
  6. IBM 区块链试点寻求解决快递的最后一英里
  7. 干货 | API开放提升效率和安全性攻略
  8. 中国DR设备行业市场发展研究报告(2022版)
  9. 导入带隐藏列的Excel发生错位
  10. Vue 页面启动时 input 框获得聚焦 focus