From 1b9e539903175e67be11af9ccfc96cdb10ad2d37 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:04:51 -0500 Subject: [PATCH] Try webrtc if enabled and mse fails with decoding error --- web/src/components/player/MsePlayer.tsx | 20 ++++++++++++++++---- web/src/types/live.ts | 2 +- web/src/views/live/LiveCameraView.tsx | 20 ++++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/web/src/components/player/MsePlayer.tsx b/web/src/components/player/MsePlayer.tsx index d240f0a83..0564a5f73 100644 --- a/web/src/components/player/MsePlayer.tsx +++ b/web/src/components/player/MsePlayer.tsx @@ -8,6 +8,7 @@ import { useRef, useState, } from "react"; +import { isIOS, isSafari } from "react-device-detect"; type MSEPlayerProps = { camera: string; @@ -311,8 +312,11 @@ function MSEPlayer({ onPlaying?.(); }} muted={!audioEnabled} - onProgress={ - onError != undefined + onProgress={() => { + if (isSafari || isIOS) { + onPlaying?.(); + } + return onError != undefined ? () => { if (videoRef.current?.paused) { return; @@ -329,8 +333,8 @@ function MSEPlayer({ }, 3000), ); } - : undefined - } + : undefined; + }} onError={(e) => { if ( // @ts-expect-error code does exist @@ -339,6 +343,14 @@ function MSEPlayer({ onError?.("startup"); } + if ( + // @ts-expect-error code does exist + e.target.error.code == MediaError.MEDIA_ERR_DECODE && + (isSafari || isIOS) + ) { + onError?.("mse-decode"); + } + if (wsRef.current) { wsRef.current.close(); wsRef.current = null; diff --git a/web/src/types/live.ts b/web/src/types/live.ts index 7002304f5..f6c8e463a 100644 --- a/web/src/types/live.ts +++ b/web/src/types/live.ts @@ -31,4 +31,4 @@ export type LiveStreamMetadata = { consumers: LiveConsumerMetadata[]; }; -export type LivePlayerError = "stalled" | "startup"; +export type LivePlayerError = "stalled" | "startup" | "mse-decode"; diff --git a/web/src/views/live/LiveCameraView.tsx b/web/src/views/live/LiveCameraView.tsx index 0efac101a..121189108 100644 --- a/web/src/views/live/LiveCameraView.tsx +++ b/web/src/views/live/LiveCameraView.tsx @@ -190,6 +190,7 @@ export default function LiveCameraView({ const [audio, setAudio] = useState(false); const [mic, setMic] = useState(false); + const [webRTC, setWebRTC] = useState(false); const [pip, setPip] = useState(false); const [lowBandwidth, setLowBandwidth] = useState(false); @@ -199,6 +200,14 @@ export default function LiveCameraView({ }); const preferredLiveMode = useMemo(() => { + if (webRTC && isRestreamed) { + return "webrtc"; + } + + if (webRTC && !isRestreamed) { + return "jsmpeg"; + } + if (mic) { return "webrtc"; } @@ -208,7 +217,7 @@ export default function LiveCameraView({ } return "mse"; - }, [lowBandwidth, mic]); + }, [lowBandwidth, mic, webRTC, isRestreamed]); // layout state @@ -426,7 +435,14 @@ export default function LiveCameraView({ pip={pip} setFullResolution={setFullResolution} containerRef={containerRef} - onError={() => setLowBandwidth(true)} + onError={(e) => { + if (e == "mse-decode") { + setWebRTC(true); + } else { + setWebRTC(false); + setLowBandwidth(true); + } + }} /> {camera.onvif.host != "" && (