15 flvjs 播放 ws 服务代理的不存在的 rtsp 连接, Cannot read properties of null (reading ‘flushStashedSamples‘)
Posted 蓝风9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 = false
console.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‘)的主要内容,如果未能解决你的问题,请参考以下文章
通过Vue+flvjs在HTML5中播放flv格式视频文件—demo及api