Try webrtc if enabled and mse fails with decoding error

This commit is contained in:
Josh Hawkins 2024-06-04 08:04:51 -05:00
parent e6d1ad0ac5
commit 1b9e539903
3 changed files with 35 additions and 7 deletions

View File

@ -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;

View File

@ -31,4 +31,4 @@ export type LiveStreamMetadata = {
consumers: LiveConsumerMetadata[];
};
export type LivePlayerError = "stalled" | "startup";
export type LivePlayerError = "stalled" | "startup" | "mse-decode";

View File

@ -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);
}
}}
/>
</div>
{camera.onvif.host != "" && (