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…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
