15 flvjs 播放 ws 服务代理的不存在的 rtsp 连接, Cannot read properties of null (reading ‘flushStashedSamples‘)
前言
这是基于 flvjs 播放 rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务 的时候, 衍生出来的一个问题
在生产环境上面, 很大一部分 rtsp 服务是正常的可以播放的, 但是 还存在一部分 rtsp 服务是播放不出来的, 我们需要再 产生异常的时候做一些 回调处理
但是 这时候就会抛出异常如下
Uncaught TypeError: Cannot read properties of null (reading 'flushStashedSamples')at __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onIOComplete (flv.js?20b0:3357:1)at __webpack_modules__../src/io/io-controller.js.IOController._onLoaderComplete (flv.js?20b0:6328:1)at __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketClose (flv.js?20b0:6902:1)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onIOComplete @ flv.js?20b0:3357
__webpack_modules__../src/io/io-controller.js.IOController._onLoaderComplete @ flv.js?20b0:6328
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketClose @ flv.js?20b0:6902
10HelloWorld.vue?18db:55
我们这里 参考的代码来自于 GitHub - LorinHan/flvjs_test: 采用flvjs实现摄像头直播
问题复现
1. 启动 node 代理服务 "node index.js"
2. 在 flvjs_test 项目下的 front 项目, 调整 HelloWorld.vue, 调整 ws 的链接, 更新 rtsp 的链接为一个不存在的链接即可
问题的原因
## 如果待加载的 rtsp 连接不正确, _remuxer 的 NPE 的问题
// 需要有一个正常的 websocket 响应, 才会初始化 _remuxer
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketMessage (flv.js?20b0:6908)
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._dispatchArrayBuffer (flv.js?20b0:6933)
__webpack_modules__../src/io/io-controller.js.IOController._onLoaderChunkArrival (flv.js?20b0:6261)
__webpack_modules__../src/io/io-controller.js.IOController._dispatchChunks (flv.js?20b0:6173)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onInitChunkArrival (flv.js?20b0:3282)里面初始化 _remuxer# 我们这里异常情况下是是直接走的 ws.close, 而此时 _remuxer 尚未初始化
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketClose (flv.js?20b0:6902)
__webpack_modules__../src/io/io-controller.js.IOController._onLoaderComplete (flv.js?20b0:6328)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onIOComplete (flv.js?20b0:3351)
基于调整 flvjs 代码处理问题
_remuxer 增加 null check, 然后 重新打包 发布依赖
这个处理 相对比较简单, 一了百了, 本身按道理来说 这个应该也算是 flvjs 的 bug
花式操作初始化 _remuxer 处理问题
好处是 不用修改 flvjs 的代码, 以免造成一些 意料之外的问题
// createPlayer 的时候增加 deferLoadAfterSourceOpen 的配置
this.player = flvjs.createPlayer({type: "flv",isLive: true,url: `ws://localhost:9999/rtsp/${this.id}/?url=${this.rtsp}`
}, {deferLoadAfterSourceOpen: false
});// 在 this.player.load() 之后增加如下代码, 初始化 _remuxer
let controller = this.player._transmuxer._controller
controller._remuxer = {flushStashedSamples: function () {console.log("flushStashedSamples")}
}
刷新一下页面, 发现 那个错误已经被我们绕过了
但是直接这样的话, 我们兼容不了 rtsp 服务正常的情况, 正常的视频 会包 bindDataSource 的 "is not a function"
花式操作初始化 _remuxer 处理问题, 兼容正常/异常情况
调整上面的代码, 我们将 _remuxer 的初始化调整为 在需要的时候 才自己手动模拟一个 _remuxer
这时候 就兼容了 正常情况 和 异常情况了
// createPlayer 的时候增加 deferLoadAfterSourceOpen 的配置
this.player = flvjs.createPlayer({type: "flv",isLive: true,url: `ws://localhost:9999/rtsp/${this.id}/?url=${this.rtsp}`
}, {deferLoadAfterSourceOpen: false
});// 在 this.player.load() 之后增加如下代码, 需要的时候, 初始化 _remuxer
let controller = this.player._transmuxer._controller
let wsLoader = controller._ioctl._loader
var oldWsOnCompleteFunc = wsLoader._onComplete
wsLoader._onComplete = function() {if(!controller._remuxer) {controller._remuxer = {flushStashedSamples: function () {_this.loadingVisiable = falseconsole.log("flushStashedSamples")}}}oldWsOnCompleteFunc()
}
异常情况如下
正常情况如下
为什么能这样?, 那就需要你去稍微 捋一下 flv.js 的代码了
以及对 javascript 稍微有所了解
正常状态的监听 和 异常状态的监听
正常状态的监听可以使用 : flvjs 的 MEDIA_INFO, METADATA_ARRIVED, SCRIPTDATA_ARRIVED, 或者 video 的 canpaly 事件
异常状态可以使用 : video 的 error 事件
异常状态为什么不能使用 flvjs 的 ERROR 事件?
因为 flvjs 的 ERROR 是在播放的过程中产生的异常, 才会提交 ERROR 事件
flvjs 的 ERROR 会在 appendInitSegment/_doAppendSegments 中可能提交
但是这两个的处理都是在 正常的拿到了 flv 的数据之后, 才会执行
因此 请注意 flvjs 的 ERROR 事件的细节
# 处理 第一个 AVCVideoPacket 为 AVCSequence Header 的调用栈
__webpack_modules__../src/core/mse-controller.js.MSEController.appendInitSegment (flv.js?20b0:2409)
(anonymous) (flv.js?20b0:7735)
emit (flv.js?20b0:1248)
(anonymous) (flv.js?20b0:2932)
Promise.then (async)
__webpack_modules__../src/core/transmuxer.js.Transmuxer._onInitSegment (flv.js?20b0:2931)
emit (flv.js?20b0:1248)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onRemuxerInitSegmentArrival (flv.js?20b0:3379)
__webpack_modules__../src/remux/mp4-remuxer.js.MP4Remuxer._onTrackMetadataReceived (flv.js?20b0:9255)
__webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer._parseAVCDecoderConfigurationRecord (flv.js?20b0:5023)
__webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer._parseAVCVideoPacket (flv.js?20b0:4866)
__webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer._parseVideoData (flv.js?20b0:4853)
__webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer.parseChunks (flv.js?20b0:4400)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onInitChunkArrival (flv.js?20b0:3303)
__webpack_modules__../src/io/io-controller.js.IOController._dispatchChunks (flv.js?20b0:6173)
__webpack_modules__../src/io/io-controller.js.IOController._onLoaderChunkArrival (flv.js?20b0:6261)
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._dispatchArrayBuffer (flv.js?20b0:6933)
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketMessage (flv.js?20b0:6908)# 处理 渲染当前 pakcet 的 flv 的视频数据 的调用栈
__webpack_modules__../src/core/mse-controller.js.MSEController._doAppendSegments (flv.js?20b0:2627)
__webpack_modules__../src/core/mse-controller.js.MSEController.appendMediaSegment (flv.js?20b0:2469)
(anonymous) (flv.js?20b0:7738)
emit (flv.js?20b0:1248)
(anonymous) (flv.js?20b0:2938)
Promise.then (async)
__webpack_modules__../src/core/transmuxer.js.Transmuxer._onMediaSegment (flv.js?20b0:2937)
emit (flv.js?20b0:1248)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onRemuxerMediaSegmentArrival (flv.js?20b0:3386)
__webpack_modules__../src/remux/mp4-remuxer.js.MP4Remuxer._remuxVideo (flv.js?20b0:9754)
__webpack_modules__../src/remux/mp4-remuxer.js.MP4Remuxer.remux (flv.js?20b0:9224)
__webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer.parseChunks (flv.js?20b0:4415)
__webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onInitChunkArrival (flv.js?20b0:3303)
__webpack_modules__../src/io/io-controller.js.IOController._dispatchChunks (flv.js?20b0:6173)
__webpack_modules__../src/io/io-controller.js.IOController._onLoaderChunkArrival (flv.js?20b0:6261)
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._dispatchArrayBuffer (flv.js?20b0:6933)
__webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketMessage (flv.js?20b0:6908)
完
15 flvjs 播放 ws 服务代理的不存在的 rtsp 连接, Cannot read properties of null (reading ‘flushStashedSamples‘)相关推荐
- TreeSet引发的OSGI服务代理创建异常
看故障日志: Method entry: getService, args org.apache.karaf.deployer.features.FeatureDeploymentListener@4 ...
- oracle json入参调用ws服务返回请求失败_Spring 5.2.2技术集成 —Spring HTTP调用程序和JAXWS...
下面提到的AccountService接口类需要看Spring 5.2.2 技术的集成-RMI.Hessian,就不在此赘述了. 一.Spring HTTP调用程序 与Hessian相 ...
- Dubbo-go 服务代理模型
简介:HSF 是阿里集团 RPC/服务治理 领域的标杆,Go 语言又因为其高并发,云原生的特性,拥有广阔的发展前景和实践场景,服务代理模型只是一种落地场景,除此之外,还有更多的应用场景值得我们在研发的 ...
- springboot 配置多个请求服务代理
springboot 配置服务代理 有时候,我们可能有下边这样的需求: 即,针对于分布式服务,我们会有多种业务接口服务,但是服务器上可能只要求开放一个服务的端口,比如上图的restA项目端口是对外开放 ...
- 【gSOAP】gSOAP生成服务代理和对象C语言代码示例
用gSOAP实现一个简单四则运算的服务器及代理. Table of Contents 头文件 编写头文件calc.h 生成头文件calc.h wsdl2h使用方法 生成服务端和客户端(代理)程序 so ...
- DSF框架使用(DAO、序列化、注解、服务接口、服务代理)
1.首先说一下什么是DSF DSF(到家服务框架):提供服务接口供客户端调用,实现服务端服务共享.避免服务的不一致及二次开发:(个人理解:类似于对外提供的API接口-只是这里是提供的服务的接口) 2. ...
- springboot做代理分发服务+代理鉴权
还原背景 大家都做过b-s架构的应用,也就是基于浏览器的软件应用.现在呢有个场景就是FE端也就是前端工程是前后端分离的,采用主流的前端框架VUE编写.服务端采用的是springBoot架构. 现在有另 ...
- mysql服务器是否支持tcp/ip连接,(3)MySQL客户端与服务端的TCP/IP及socket连接方式-Go语言中文社区...
MySQL客户端与服务端的TCP/IP及socket连接方式 客户端与服务器模型 客户端与服务端模型 TCP/IP方式连接 解释说明 TCP/IP套接字方式是MySQL在任何平台下都提供的连接方式,也 ...
- Linux运维学习:高级提升(1)——HTTP服务代理缓存加速
HTTP缓存机制 Web 缓存大致可以分为:数据库缓存.服务器端缓存(代理服务器缓存.CDN 缓存).浏览器缓存. 浏览器缓存也包含很多内容: HTTP 缓存.indexDB.cookie.local ...
最新文章
- 葡萄城报表介绍:交叉报表
- VTK:RenderMan之PolyDataRIB
- It is indirectly referenced from required .class file
- vue中实现美团双级联动菜单
- NXP(I.MX6uLL)DDR3实验——DDR3重要时间参数、时钟配置与原理图简析
- Spark SQL(十)之基于物品的推荐公式
- css叠层_CSS 中重要的层叠概念
- python 正则表达式 符号及其定义
- 如何在C中调用C++的示例代码
- IIS7 请求筛选模块被配置为拒绝超过请求内容长度的请求
- ipython安装成功后用不了_ipython安装避坑指南
- win10如何解决非系统盘中出现的msdia80.dll文件
- android手机屏分辨率和屏幕逻辑,手机屏幕分辨率术语:逻辑分辨率和物理分辨率...
- java输出英文字母_用JAVA编一个程序输出全部的英文字母
- 如何确认是文章发表在哪里?
- 大器晚成总比一事无成要强
- UOS系统下安装软件打不开的解决方法
- JSP中连接SQL 2000数据库的问题总结
- TA-Lib介绍安装及使用教程
- 【HTML】HTML网页设计---智能动物园系统网站端