当前位置:   article > 正文

15 flvjs 播放 ws 服务代理的不存在的 rtsp 连接, Cannot read properties of null (reading ‘flushStashedSamples‘)_cannot read properties of null (reading 'flushstas

cannot read properties of null (reading 'flushstashedsamples')

前言

这是基于 flvjs 播放 rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务 的时候, 衍生出来的一个问题 

在生产环境上面, 很大一部分 rtsp 服务是正常的可以播放的, 但是 还存在一部分 rtsp 服务是播放不出来的, 我们需要再 产生异常的时候做一些 回调处理 

但是 这时候就会抛出异常如下 

  1. Uncaught TypeError: Cannot read properties of null (reading 'flushStashedSamples')
  2. at __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onIOComplete (flv.js?20b0:3357:1)
  3. at __webpack_modules__../src/io/io-controller.js.IOController._onLoaderComplete (flv.js?20b0:6328:1)
  4. at __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketClose (flv.js?20b0:6902:1)
  5. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onIOComplete @ flv.js?20b0:3357
  6. __webpack_modules__../src/io/io-controller.js.IOController._onLoaderComplete @ flv.js?20b0:6328
  7. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketClose @ flv.js?20b0:6902
  8. 10HelloWorld.vue?18db:55

我们这里 参考的代码来自于 GitHub - LorinHan/flvjs_test: 采用flvjs实现摄像头直播

问题复现

1. 启动 node 代理服务 "node index.js" 

2. 在 flvjs_test 项目下的 front 项目, 调整 HelloWorld.vue, 调整 ws 的链接, 更新 rtsp 的链接为一个不存在的链接即可 

问题的原因

  1. ## 如果待加载的 rtsp 连接不正确, _remuxer 的 NPE 的问题
  2. // 需要有一个正常的 websocket 响应, 才会初始化 _remuxer
  3. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketMessage (flv.js?20b0:6908)
  4. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._dispatchArrayBuffer (flv.js?20b0:6933)
  5. __webpack_modules__../src/io/io-controller.js.IOController._onLoaderChunkArrival (flv.js?20b0:6261)
  6. __webpack_modules__../src/io/io-controller.js.IOController._dispatchChunks (flv.js?20b0:6173)
  7. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onInitChunkArrival (flv.js?20b0:3282)
  8. 里面初始化 _remuxer
  9. # 我们这里异常情况下是是直接走的 ws.close, 而此时 _remuxer 尚未初始化
  10. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketClose (flv.js?20b0:6902)
  11. __webpack_modules__../src/io/io-controller.js.IOController._onLoaderComplete (flv.js?20b0:6328)
  12. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onIOComplete (flv.js?20b0:3351)

基于调整 flvjs 代码处理问题

_remuxer 增加 null check, 然后 重新打包 发布依赖 

这个处理 相对比较简单, 一了百了, 本身按道理来说 这个应该也算是 flvjs 的 bug 

花式操作初始化 _remuxer 处理问题 

好处是 不用修改 flvjs 的代码, 以免造成一些 意料之外的问题  

  1. // createPlayer 的时候增加 deferLoadAfterSourceOpen 的配置
  2. this.player = flvjs.createPlayer({
  3. type: "flv",
  4. isLive: true,
  5. url: `ws://localhost:9999/rtsp/${this.id}/?url=${this.rtsp}`
  6. }, {
  7. deferLoadAfterSourceOpen: false
  8. });
  9. // 在 this.player.load() 之后增加如下代码, 初始化 _remuxer
  10. let controller = this.player._transmuxer._controller
  11. controller._remuxer = {
  12. flushStashedSamples: function () {
  13. console.log("flushStashedSamples")
  14. }
  15. }

刷新一下页面, 发现 那个错误已经被我们绕过了 

但是直接这样的话, 我们兼容不了 rtsp 服务正常的情况, 正常的视频 会包 bindDataSource 的 "is not a function"

花式操作初始化 _remuxer 处理问题, 兼容正常/异常情况

调整上面的代码, 我们将 _remuxer 的初始化调整为 在需要的时候 才自己手动模拟一个 _remuxer 

这时候 就兼容了 正常情况 和 异常情况了 

  1. // createPlayer 的时候增加 deferLoadAfterSourceOpen 的配置
  2. this.player = flvjs.createPlayer({
  3. type: "flv",
  4. isLive: true,
  5. url: `ws://localhost:9999/rtsp/${this.id}/?url=${this.rtsp}`
  6. }, {
  7. deferLoadAfterSourceOpen: false
  8. });
  9. // 在 this.player.load() 之后增加如下代码, 需要的时候, 初始化 _remuxer
  10. let controller = this.player._transmuxer._controller
  11. let wsLoader = controller._ioctl._loader
  12. var oldWsOnCompleteFunc = wsLoader._onComplete
  13. wsLoader._onComplete = function() {
  14. if(!controller._remuxer) {
  15. controller._remuxer = {
  16. flushStashedSamples: function () {
  17. _this.loadingVisiable = false
  18. console.log("flushStashedSamples")
  19. }
  20. }
  21. }
  22. oldWsOnCompleteFunc()
  23. }

异常情况如下 

正常情况如下  

为什么能这样?, 那就需要你去稍微 捋一下 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 事件的细节 

  1. # 处理 第一个 AVCVideoPacket 为 AVCSequence Header 的调用栈
  2. __webpack_modules__../src/core/mse-controller.js.MSEController.appendInitSegment (flv.js?20b0:2409)
  3. (anonymous) (flv.js?20b0:7735)
  4. emit (flv.js?20b0:1248)
  5. (anonymous) (flv.js?20b0:2932)
  6. Promise.then (async)
  7. __webpack_modules__../src/core/transmuxer.js.Transmuxer._onInitSegment (flv.js?20b0:2931)
  8. emit (flv.js?20b0:1248)
  9. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onRemuxerInitSegmentArrival (flv.js?20b0:3379)
  10. __webpack_modules__../src/remux/mp4-remuxer.js.MP4Remuxer._onTrackMetadataReceived (flv.js?20b0:9255)
  11. __webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer._parseAVCDecoderConfigurationRecord (flv.js?20b0:5023)
  12. __webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer._parseAVCVideoPacket (flv.js?20b0:4866)
  13. __webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer._parseVideoData (flv.js?20b0:4853)
  14. __webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer.parseChunks (flv.js?20b0:4400)
  15. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onInitChunkArrival (flv.js?20b0:3303)
  16. __webpack_modules__../src/io/io-controller.js.IOController._dispatchChunks (flv.js?20b0:6173)
  17. __webpack_modules__../src/io/io-controller.js.IOController._onLoaderChunkArrival (flv.js?20b0:6261)
  18. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._dispatchArrayBuffer (flv.js?20b0:6933)
  19. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketMessage (flv.js?20b0:6908)
  20. # 处理 渲染当前 pakcet 的 flv 的视频数据 的调用栈
  21. __webpack_modules__../src/core/mse-controller.js.MSEController._doAppendSegments (flv.js?20b0:2627)
  22. __webpack_modules__../src/core/mse-controller.js.MSEController.appendMediaSegment (flv.js?20b0:2469)
  23. (anonymous) (flv.js?20b0:7738)
  24. emit (flv.js?20b0:1248)
  25. (anonymous) (flv.js?20b0:2938)
  26. Promise.then (async)
  27. __webpack_modules__../src/core/transmuxer.js.Transmuxer._onMediaSegment (flv.js?20b0:2937)
  28. emit (flv.js?20b0:1248)
  29. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onRemuxerMediaSegmentArrival (flv.js?20b0:3386)
  30. __webpack_modules__../src/remux/mp4-remuxer.js.MP4Remuxer._remuxVideo (flv.js?20b0:9754)
  31. __webpack_modules__../src/remux/mp4-remuxer.js.MP4Remuxer.remux (flv.js?20b0:9224)
  32. __webpack_modules__../src/demux/flv-demuxer.js.FLVDemuxer.parseChunks (flv.js?20b0:4415)
  33. __webpack_modules__../src/core/transmuxing-controller.js.TransmuxingController._onInitChunkArrival (flv.js?20b0:3303)
  34. __webpack_modules__../src/io/io-controller.js.IOController._dispatchChunks (flv.js?20b0:6173)
  35. __webpack_modules__../src/io/io-controller.js.IOController._onLoaderChunkArrival (flv.js?20b0:6261)
  36. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._dispatchArrayBuffer (flv.js?20b0:6933)
  37. __webpack_modules__../src/io/websocket-loader.js.WebSocketLoader._onWebSocketMessage (flv.js?20b0:6908)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/157502?site
推荐阅读
相关标签
  

闽ICP备14008679号