web浏览器播放rtsp视频流,海康监控API
概述
这里记录一下如何让前端播放rtsp协议的视频流
项目中调用海康API,生成的视频流(hls、ws、rtmp等)通过PotPlayer播放器都无法播放,说明视频流有问题,唯独rtsp视频流可以播放。
但是浏览器本身是无法播放rtsp视频的,即使是使用videojs、flvjs等工具。
网上的方案都是通过后端基于ffmpeg工具进行转码。那么我的理解是后端Node起到的是中转作用:调用ffmpeg工具对传入的rtsp流进行转码再传给前端
这里记录整个过程与出现的问题解决
准备
需要三部分的准备:
- ffmpeg工具
- nodeJS转码
- 前端播放
ffmpeg安装与配置
- 下载ffmpeg https://ffmpeg.org/download.html


-
下载并解压完成后
我这里放在 D:\DevelopSoftware\ffmpeg
-
配置环境变量
我的电脑 => 属性 => 高级系统设置 => 环境变量 => Path => 添加
D:\DevelopSoftware\ffmpeg\bin
-
打开cmd输入
ffmpeg或者ffmpeg -version出现东西就说明OK了
如果
'ffmpeg' 不是内部或外部命令,也不是可运行的程序或批处理文件, 重启cmd窗口, 还是不行的话网上搜一下吧
本节参考自 ffmpeg安装教程(windows版)
nodejs编写转码服务
先随便建个文件夹
npm i express express-ws fluent-ffmpeg websocket-stream
或者
yarn add express express-ws fluent-ffmpeg websocket-stream
新建 index.js
var express = require('express')
var expressWebSocket = require('express-ws')
var ffmpeg = require('fluent-ffmpeg')
var webSocketStream = require('websocket-stream/stream')
var WebSocket = require('websocket-stream')
var http = require('http')ffmpeg.setFfmpegPath('ffmpeg')// config
let rtspServerPort = 2156function localServer() {let app = express()app.use(express.static(__dirname))expressWebSocket(app, null, {perMessageDeflate: true})// :id是动态参数, 前端调用时传递, 可以去掉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.urlconsole.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()
运行
node index.js

前端调用转码服务
新建 demo.html
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js"></script><!-- <script src="./js/flv.min.js"></script>--><style>body,center {padding: 0;margin: 0;}.v-container {width: 640px;height: 360px;border: solid 1px red;}video {width: 100%;height: 100%;}</style></head><body><div class="v-container"><video id="player1" muted autoplay="autoplay" preload="auto" controls="controls"></video></div><script>if (flvjs.isSupported()) {var videoElement = document.getElementById('player1')var flvPlayer = flvjs.createPlayer({type: 'flv',url: 'ws://localhost:2156/rtsp/111/?url=rtsp://xxx.xxx.xxx:554/openUrl/jmQgiJi'})flvPlayer.attachMediaElement(videoElement)flvPlayer.load()}</script></body>
</html>
这两节源自 rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务
videojs + flvjs使用
yarn add video.js flv.js videojs-flvjs-es6
import videojs from 'video.js'
import flvjs from 'flv.js'
import 'video.js/dist/video-js.css'
import 'videojs-flvjs-es6'let myPlayerconst initVideo = (videoUrl) => {// videojs初始化myPlayer = videojs(document.querySelector('#videoBox'), // video元素, vue2或vue3推荐使用ref方式{// poster: '//vjs.zencdn.net/v/oceans.png',autoplay: 'muted', //自动播放controls: true, //用户可以与之交互的控件loop: true, //视频一结束就重新开始muted: true, //默认情况下将使所有音频静音// aspectRatio: '16:9', //显示比率techOrder: ['html5', 'flvjs'], // 兼容顺序flvjs: {mediaDataSource: {cors: true,withCredentials: false,},},controlBar: {remainingTimeDisplay: {displayNegative: false,},},playbackRates: [0.5, 1, 1.5, 2],},function onPlayerReady() {this.on('play', function () {console.log('视频开始播放')})this.on('pause', function () {console.log('视频暂停播放')})this.on('error', function () {console.log('加载错误')isError.value = true})})// 播放myPlayer.reset()myPlayer.src({src: 'ws://localhost:2156/rtsp/?url=' + videoUrl,type: 'video/x-flv',})// myPlayer.load('ws://localhost:2156/rtsp/1/?url=rtsp://xxxx:554/openUrl/rMYr6w0')myPlayer.play()
}
<video ref="videoPlayer" id="videoBox" style="width:100%;height:100%;"></video>
总结
海康平台支持多种协议的视频流,如果流无法播放,可能是设备配置或者分辨率或者… 出了问题!!
这种事情当然是让后端去处理咯,是跟厂商联调还是怎么着,关我前端啥事儿!!!把精力用到更有意义的地方才是正解,例如像我一样水一篇文章, Nice!
当然,尽量直接使用海康平台API返回的流,转码始终是下策。
感谢各大佬的文章:
rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务
ffmpeg安装教程(windows版)
相关文章:
web浏览器播放rtsp视频流,海康监控API
概述 这里记录一下如何让前端播放rtsp协议的视频流 项目中调用海康API,生成的视频流(hls、ws、rtmp等)通过PotPlayer播放器都无法播放,说明视频流有问题,唯独rtsp视频流可以播放。 但是浏览器本身是无法播放rtsp视频的,即使…...
操作系统原理:程序、进程、线程的概念
文章目录 程序、进程、线程的概念程序(Program)进程(Process)线程(Thread)关系总结 在日常对操作系统的使用中,大家肯定对程序、进程和线程多少有所耳闻。作为操作系统的重要一部分,…...
Golang是如何实现动态数组功能的?Slice切片原理解析
Hi 亲爱的朋友们,我是 k 哥。今天,咱们聊一聊Golang 切片。 当我们需要使用数组,但是又不能提前定义数组大小时,可以使用golang的动态数组结构,slice切片。在 Go 语言的众多特性里,slice 是我们经常用到的数…...
SQL注入 报错注入+附加拓展知识,一篇文章带你轻松入门
第5关--------------------------------------------> 前端直接不会显示账号密码的打印;但是在接收前端的数据的那部分后端那里,会看前端传递过来的值是否正确,如果不正确,后端接收值那里就会当MySQL语句执行错误,…...
springboot项目里的包spring-boot-dependencies依赖介绍
springboot项目里的包’spring-boot-dependencies‘依赖 我们一般是在项目的pom dependencyManagement标签里引入spring-boot-dependencies,或者根spring-boot-starter-parent里也是继承了它,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本…...
C# 下的限定符运算详解(全部,任意,包含)与示例
文章目录 1.限定符概述2. 全部限定符运算(All)3. 任意限定符运算(Any)4. 包含限定符运算(Contains)总结 当我们在C#编程中需要进行条件判断或集合操作时,限定符(qualifiersÿ…...
消息队列RabbitMQ部分知识
1.简述RabbitMQ的架构设计 RabbitMQ 是一个开源的消息代理,采用了高级消息队列协议(AMQP),其架构设计主要包括以下几个关键组件和概念: 1.消息生产者( Producer): 负责发送消息到…...
看门狗应用编程-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板
看门狗应用编程 看门狗应用编程介绍 看门狗定时器的基本概念 看门狗是一个可以在一定时间内被复位/重置的计数器 如果在规定时间内没有复位,看门狗计时器溢出会对CPU产生复位信号使系统重启 有些看门狗可以只产生中断信号而不会使系统复位 I.MX6UL/I.MX6ULL So…...
Bug 解决 | 本地项目上线后出现错误
目录 一、前言 二、原因分析 1、本地代码误发线上 2、环境差异 3、配置差异 4、资源路径差异 5、API 接口差异 6、用量差异 一、前言 大家好,我是小洪爱分享。在开发上线项目的过程中,我们经常会遇到一种让人头疼的情况。那就是开发好的项目功能…...
为什么我工作 10 年后转行当程序员?逆袭翻盘!
今天文章的主人公暂且称他为 A 君。不过 A 君有点特别,非科班,工作 10 年后才转行 iOS 程序员。今年 36 岁,目前在某行业头部企业任职前端负责人,管理 40 人的前端团队。 废话不多说,我们开始 A 君(为了描…...
见证中国数据库的崛起:从追赶到引领的壮丽征程《四》
见证中国数据库的崛起:从追赶到引领的壮丽征程《四》 四、未来展望:中国数据库的机遇与挑战新技术带来的机遇全球化竞争的挑战数据安全与隐私保护的挑战人才培养的持续挑战 【纪录片】中国数据库前世今生 在数字化潮流席卷全球的今天,数据库作…...
OpenCV||超细节的基本操作
一、图像读取 retval cv2.imread(filename[, flags]) filename:需要读取的图片路径名,支持多种图片格式,如JPEG、PNG、TIFF等。flags:一个可选参数,指定加载图像的颜色类型。常用的值包括: cv2.IMGEAD_A…...
算法训练(leetcode)第三十八天 | 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和、392. 判断子序列
刷题记录 *1143. 最长公共子序列1035. 不相交的线53. 最大子数组和392. 判断子序列 *1143. 最长公共子序列 leetcode题目地址 本题和718. 最长重复子数组相似,只是本题不要求连续,需要记录前面最长的子序列,在此基础上累计长度。 dp[i][j]…...
STM32——外部中断(EXTI)
目录 前言 一、外部中断基础知识 二、使用步骤 三、固件库实现 四、STM32CubeMX实现 总结 前言 外部中断(External Interrupt,简称EXTI)是微控制器用于响应外部事件的一种方式,当外部事件发生时(如按键按下、传感器信号…...
MySQL多实例部署
1、软件包下载 //环境:一台rocky Linux虚拟机,并且做好的基本配置及时钟同步,使用Xshell连接 [rootmysql ~]# yum -y install tar lrzsz libncurses* libaio perl//将包文件拖进去 [rootmysql ~]# rz -E rz waiting to receive. [rootmysql…...
云开发喝酒小程序3.6全新漂亮UI猜拳喝酒小程序 【已去除流量主】
云开发喝酒小程序3.6全新漂亮UI猜拳喝酒小程序 已去除流量主。UI特别漂亮,实属精品代码。 【已测】云开发喝酒小程序3.6漂亮UI猜拳喝酒小程序 已去除流量主。 云开发(serverless)小程序无需服务器,注册一个小程序就可以直接上线…...
图论进阶之路-最短路(Floyd)
时间复杂度:O(n^3) 使用场景:当需要得知任意两个点的最短距离以及其路径时使用 准备:需要两个矩阵 一个记录最短距离(D) 一个记录最短路径的最后一个结点(P) 其核心在于不断的判断越过中间…...
安装sqllab靶机之后,练习关卡报403 forbidden
解决办法: 在nginx的conf文件中添加上访问index.php vim /usr/local/nginx/conf/nginx.conf 保存退出 再重启一下nginx,就完成了。 ./nginx -s reload...
微信VX多开 免扫码 登录 互斥体 可视化 Exui v1.1 易语言源码附成品软件
UI设计: 1. EXUI界面库20240204 调用的模块: 1. wow64_hook_3.02.ec(压缩包内含) 2. 精易模块[v11.1.0].ec(自行下载) 更新日志: v1.1 2024年7月25日13:28:43 { 1. 有人反馈 设置了V…...
JavaEE 从入门到精通(一) ~ Maven
晚上好,愿这深深的夜色给你带来安宁,让温馨的夜晚抚平你一天的疲惫,美好的梦想在这个寂静的夜晚悄悄成长。 目录 前言 1.1 概念 什么是 Maven? Maven 的核心概念 1.2 maven依赖坐标 1.3 maven仓库 1.4 maven安装 1.5 mave…...
嵌入式系统的实时性能优化详解
嵌入式系统的实时性能优化详解 实时系统概述 实时系统是指能够在规定的时间内完成特定任务的系统,其正确性不仅取决于计算结果的正确性,还取决于结果产生的时间。在嵌入式系统中,实时性能优化至关重要。 实时系统分类 硬实时系统…...
零基础部署MedGemma 1.5医疗助手:5分钟搭建你的本地AI医生
零基础部署MedGemma 1.5医疗助手:5分钟搭建你的本地AI医生 1. 为什么选择MedGemma 1.5医疗助手 在医疗信息查询领域,我们常常面临两个困境:要么依赖不专业的网络搜索,要么需要花费大量时间预约专业医生。MedGemma 1.5医疗助手提…...
NSSCTF题包(脱壳类和SMC)
题包里的这些类型的题这些已经接触了很长时间,但是仍然需要进行巩固,在这里先感谢师傅们还有胡楚昊大佬对我的帮助和支持这套题还有去花类的,前面文章讲过了脱壳类:主要应用的是自动脱壳以及ESP定律法手动脱壳ESP定律法࿱…...
SkeyeVSS中国标GB28181、流媒体源RTMP/RTSP/HTTP/ONVIF、RTMP推流等协议视频流实时播放流程详解
本文基于 core/app/sev/vss/internal/logic/http/video/stream_play.go 的源码:从参数与设备查询,到按接入协议分支、触发 MS 拉流或 GB28181 Invite,再到返回 StreamResp 与异步处理。 源码地址 点击直达 一、接口入口与请求体 项目说明…...
自媒体人利器:OpenClaw+百川2-13B自动生成短视频脚本
自媒体人利器:OpenClaw百川2-13B自动生成短视频脚本 1. 为什么需要自动化脚本生成工具 作为一个每天需要产出3-5条短视频的自媒体创作者,我经常陷入创意枯竭和重复劳动的困境。传统的工作流程需要手动搜索热点、构思脚本、撰写分镜,这个过程…...
**发散创新:用Go语言构建高性能服务网格代理——从零实现Sidecar模式**在微服务架构日益普及的今天,
发散创新:用Go语言构建高性能服务网格代理——从零实现Sidecar模式 在微服务架构日益普及的今天,服务网格(Service Mesh) 已成为保障流量治理、安全认证与可观测性的核心基础设施。传统基于API网关的集中式控制方式已难以满足动态…...
告别卡顿!Nginx+HTTP-FLV模块搭建低延迟直播系统(含OBS/VLC对比测试)
低延迟直播系统实战:NginxHTTP-FLV协议优化指南 直播行业的爆发式增长对技术架构提出了更高要求。当观众在电商直播间抢购商品时,当在线教育师生进行实时互动时,哪怕1秒的延迟都可能影响用户体验。本文将深入探讨如何基于Nginx和HTTP-FLV模块…...
Cherry Studio容器化部署实战指南:从环境搭建到生产运维
Cherry Studio容器化部署实战指南:从环境搭建到生产运维 【免费下载链接】cherry-studio 🍒 Cherry Studio is a desktop client that supports for multiple LLM providers. Support deepseek-r1 项目地址: https://gitcode.com/GitHub_Trending/ch/c…...
C++模板编程:从函数到类的实现原理
1. C模板编程深度解析:从函数模板到类模板的实现原理1.1 模板编程的必要性在C开发中,经常会遇到需要处理不同数据类型但逻辑相同的场景。以二维坐标点类为例,传统实现方式需要为每种数据类型创建独立的类:// 浮点型坐标点类 class…...
嵌入式设备与PC通信协议设计核心原则
嵌入式设备与PC上位机通信协议设计原则1. 通信协议概述嵌入式系统与PC上位机之间的参数配置和数据交换需要设计高效的通信协议。在资源受限的嵌入式环境中,固定二进制协议因其高效性成为首选方案。一个完善的通信协议应包含以下基本域:帧头:标…...
