前言

这是基于 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‘)相关推荐

  1. TreeSet引发的OSGI服务代理创建异常

    看故障日志: Method entry: getService, args org.apache.karaf.deployer.features.FeatureDeploymentListener@4 ...

  2. oracle json入参调用ws服务返回请求失败_Spring 5.2.2技术集成 —Spring HTTP调用程序和JAXWS...

            下面提到的AccountService接口类需要看Spring 5.2.2 技术的集成-RMI.Hessian,就不在此赘述了. 一.Spring HTTP调用程序 与Hessian相 ...

  3. Dubbo-go 服务代理模型

    简介:HSF 是阿里集团 RPC/服务治理 领域的标杆,Go 语言又因为其高并发,云原生的特性,拥有广阔的发展前景和实践场景,服务代理模型只是一种落地场景,除此之外,还有更多的应用场景值得我们在研发的 ...

  4. springboot 配置多个请求服务代理

    springboot 配置服务代理 有时候,我们可能有下边这样的需求: 即,针对于分布式服务,我们会有多种业务接口服务,但是服务器上可能只要求开放一个服务的端口,比如上图的restA项目端口是对外开放 ...

  5. 【gSOAP】gSOAP生成服务代理和对象C语言代码示例

    用gSOAP实现一个简单四则运算的服务器及代理. Table of Contents 头文件 编写头文件calc.h 生成头文件calc.h wsdl2h使用方法 生成服务端和客户端(代理)程序 so ...

  6. DSF框架使用(DAO、序列化、注解、服务接口、服务代理)

    1.首先说一下什么是DSF DSF(到家服务框架):提供服务接口供客户端调用,实现服务端服务共享.避免服务的不一致及二次开发:(个人理解:类似于对外提供的API接口-只是这里是提供的服务的接口) 2. ...

  7. springboot做代理分发服务+代理鉴权

    还原背景 大家都做过b-s架构的应用,也就是基于浏览器的软件应用.现在呢有个场景就是FE端也就是前端工程是前后端分离的,采用主流的前端框架VUE编写.服务端采用的是springBoot架构. 现在有另 ...

  8. mysql服务器是否支持tcp/ip连接,(3)MySQL客户端与服务端的TCP/IP及socket连接方式-Go语言中文社区...

    MySQL客户端与服务端的TCP/IP及socket连接方式 客户端与服务器模型 客户端与服务端模型 TCP/IP方式连接 解释说明 TCP/IP套接字方式是MySQL在任何平台下都提供的连接方式,也 ...

  9. Linux运维学习:高级提升(1)——HTTP服务代理缓存加速

    HTTP缓存机制 Web 缓存大致可以分为:数据库缓存.服务器端缓存(代理服务器缓存.CDN 缓存).浏览器缓存. 浏览器缓存也包含很多内容: HTTP 缓存.indexDB.cookie.local ...

最新文章

  1. 葡萄城报表介绍:交叉报表
  2. VTK:RenderMan之PolyDataRIB
  3. It is indirectly referenced from required .class file
  4. vue中实现美团双级联动菜单
  5. NXP(I.MX6uLL)DDR3实验——DDR3重要时间参数、时钟配置与原理图简析
  6. Spark SQL(十)之基于物品的推荐公式
  7. css叠层_CSS 中重要的层叠概念
  8. python 正则表达式 符号及其定义
  9. 如何在C中调用C++的示例代码
  10. IIS7 请求筛选模块被配置为拒绝超过请求内容长度的请求
  11. ipython安装成功后用不了_ipython安装避坑指南
  12. win10如何解决非系统盘中出现的msdia80.dll文件
  13. android手机屏分辨率和屏幕逻辑,手机屏幕分辨率术语:逻辑分辨率和物理分辨率...
  14. java输出英文字母_用JAVA编一个程序输出全部的英文字母
  15. 如何确认是文章发表在哪里?
  16. 大器晚成总比一事无成要强
  17. UOS系统下安装软件打不开的解决方法
  18. JSP中连接SQL 2000数据库的问题总结
  19. TA-Lib介绍安装及使用教程
  20. 【HTML】HTML网页设计---智能动物园系统网站端

热门文章

  1. 无人叉车如何打造智能物流仓储?
  2. 为什么x86模式里BIOS在0x7c00加载MBR
  3. UNIX高级环境编程—第八章进程控制
  4. 网络仿真工具Mahimahi的安装和基础用法
  5. (译)SAP APO介绍
  6. Python numpy 开N次方
  7. 神奇的计算机网络教案,网络信息技术教案
  8. 翰林网上阅卷系统 共享资源在行动
  9. 基于 JAVAEE 的企业固定资产管理系统的设计与实现
  10. 豆瓣图书爬取并进行评论的特征提取