From 7182a1b63db1922ea93ea65a53e448cafa47e2b5 Mon Sep 17 00:00:00 2001 From: Michael Hollister Date: Thu, 12 Jun 2025 17:18:53 -0500 Subject: [PATCH] Receivers: Imporved player error handling --- receivers/common/web/player/Player.ts | 2 +- receivers/common/web/player/Renderer.ts | 54 +++++++++++++++++++------ 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/receivers/common/web/player/Player.ts b/receivers/common/web/player/Player.ts index f948aab..c7f62fd 100644 --- a/receivers/common/web/player/Player.ts +++ b/receivers/common/web/player/Player.ts @@ -87,7 +87,7 @@ export class Player { case PlayerType.Html: { this.player.src = ""; - // this.player.onerror = null; + this.player.onerror = null; this.player.onloadedmetadata = null; this.player.ontimeupdate = null; this.player.onplay = null; diff --git a/receivers/common/web/player/Renderer.ts b/receivers/common/web/player/Renderer.ts index 8ff2afd..791853b 100644 --- a/receivers/common/web/player/Renderer.ts +++ b/receivers/common/web/player/Renderer.ts @@ -202,13 +202,23 @@ function onPlay(_event, value: PlayMessage) { } }); - player.dashPlayer.on(dashjs.MediaPlayer.events.ERROR, (data) => { window.targetAPI.sendPlaybackError({ - message: `DashJS ERROR: ${JSON.stringify(data)}` - })}); + player.dashPlayer.on(dashjs.MediaPlayer.events.ERROR, (data) => { + toast('Media playback error, please close the player and reconnect sender devices if you experience issues', ToastIcon.WARNING); + logger.error('Dash player error:', data); - player.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, (data) => { window.targetAPI.sendPlaybackError({ - message: `DashJS PLAYBACK_ERROR: ${JSON.stringify(data)}` - })}); + window.targetAPI.sendPlaybackError({ + message: JSON.stringify(data) + }); + }); + + player.dashPlayer.on(dashjs.MediaPlayer.events.PLAYBACK_ERROR, (data) => { + toast('Media playback error, please close the player and reconnect sender devices if you experience issues', ToastIcon.WARNING); + logger.error('Dash player playback error:', data); + + window.targetAPI.sendPlaybackError({ + message: JSON.stringify(data) + }); + }); player.dashPlayer.on(dashjs.MediaPlayer.events.STREAM_INITIALIZED, () => { onPlayerLoad(value); }); @@ -245,10 +255,22 @@ function onPlay(_event, value: PlayMessage) { }); } else if ((value.container === 'application/vnd.apple.mpegurl' || value.container === 'application/x-mpegURL') && !videoElement.canPlayType(value.container)) { - player.hlsPlayer.on(Hls.Events.ERROR, (eventName, data) => { - window.targetAPI.sendPlaybackError({ - message: `HLS player error: ${JSON.stringify(data)}` - }); + player.hlsPlayer.on(Hls.Events.ERROR, (_eventName, data) => { + if (data.fatal) { + toast('Media playback error, please close the player and reconnect sender devices if you experience issues', ToastIcon.WARNING); + logger.error('HLS player error:', data); + + window.targetAPI.sendPlaybackError({ + message: JSON.stringify(data) + }); + + if (data.type === Hls.ErrorTypes.MEDIA_ERROR) { + player.hlsPlayer.recoverMediaError(); + } + } + else { + logger.warn('HLS non-fatal error:', data); + } }); player.hlsPlayer.on(Hls.Events.LEVEL_LOADED, (eventName, level: LevelLoadedData) => { @@ -263,7 +285,6 @@ function onPlay(_event, value: PlayMessage) { playerCtrlDuration.style.display = "none"; } }); - } // Player event handlers @@ -292,8 +313,15 @@ function onPlay(_event, value: PlayMessage) { } }; - videoElement.onerror = (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error) => { - logger.error("Player error", {source, lineno, colno, error}); + // parameters seem to always be undefined... + // videoElement.onerror = (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error) => { + videoElement.onerror = () => { + toast('Media playback error, please close the player and reconnect sender devices if you experience issues', ToastIcon.WARNING); + logger.error('Html player error:', { playMessage: value, videoError: videoElement.error }); + + window.targetAPI.sendPlaybackError({ + message: JSON.stringify({ playMessage: value, videoError: videoElement.error }) + }); }; videoElement.onloadedmetadata = (ev) => {