Live view improvements (#20177)

This commit is contained in:
Josh Hawkins
2025-09-22 21:21:51 -05:00
committed by GitHub
parent bdb7a18602
commit 7f7eefef7f
4 changed files with 242 additions and 201 deletions

View File

@@ -84,6 +84,17 @@ function MSEPlayer({
return `${baseUrl.replace(/^http/, "ws")}live/mse/api/ws?src=${camera}`;
}, [camera]);
const handleError = useCallback(
(error: LivePlayerError, description: string = "Unknown error") => {
// eslint-disable-next-line no-console
console.error(
`${camera} - MSE error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live`,
);
onError?.(error);
},
[camera, onError],
);
const handleLoadedMetadata = useCallback(() => {
if (videoRef.current && setFullResolution) {
setFullResolution({
@@ -237,9 +248,9 @@ function MSEPlayer({
onDisconnect();
}
if (isIOS || isSafari) {
onError?.("mse-decode");
handleError("mse-decode", "Safari cannot open MediaSource.");
} else {
onError?.("startup");
handleError("startup", "Error opening MediaSource.");
}
});
},
@@ -267,9 +278,9 @@ function MSEPlayer({
onDisconnect();
}
if (isIOS || isSafari) {
onError?.("mse-decode");
handleError("mse-decode", "Safari cannot open MediaSource.");
} else {
onError?.("startup");
handleError("startup", "Error opening MediaSource.");
}
});
},
@@ -297,7 +308,7 @@ function MSEPlayer({
if (wsRef.current) {
onDisconnect();
}
onError?.("mse-decode");
handleError("mse-decode", "Safari reported InvalidStateError.");
return;
} else {
throw e; // Re-throw if it's not the error we're handling
@@ -424,7 +435,10 @@ function MSEPlayer({
(bufferThreshold > 10 || bufferTime > 10)
) {
onDisconnect();
onError?.("stalled");
handleError(
"stalled",
"Buffer time (10 seconds) exceeded, browser may not be playing media correctly.",
);
}
const playbackRate = calculateAdaptivePlaybackRate(
@@ -470,7 +484,7 @@ function MSEPlayer({
videoRef.current
) {
onDisconnect();
onError("stalled");
handleError("stalled", "Media playback has stalled.");
}
}, timeoutDuration),
);
@@ -479,6 +493,7 @@ function MSEPlayer({
bufferTimeout,
isPlaying,
onDisconnect,
handleError,
onError,
onPlaying,
playbackEnabled,
@@ -663,7 +678,7 @@ function MSEPlayer({
if (wsRef.current) {
onDisconnect();
}
onError?.("startup");
handleError("startup", "Browser reported a network error.");
}
if (
@@ -674,7 +689,7 @@ function MSEPlayer({
if (wsRef.current) {
onDisconnect();
}
onError?.("mse-decode");
handleError("mse-decode", "Safari reported decoding errors.");
}
setErrorCount((prevCount) => prevCount + 1);
@@ -683,7 +698,7 @@ function MSEPlayer({
onDisconnect();
if (errorCount >= 3) {
// too many mse errors, try jsmpeg
onError?.("startup");
handleError("startup", `Max error count ${errorCount} exceeded.`);
} else {
reconnect(5000);
}

View File

@@ -37,6 +37,18 @@ export default function WebRtcPlayer({
return `${baseUrl.replace(/^http/, "ws")}live/webrtc/api/ws?src=${camera}`;
}, [camera]);
// error handler
const handleError = useCallback(
(error: LivePlayerError, description: string = "Unknown error") => {
// eslint-disable-next-line no-console
console.error(
`${camera} - WebRTC error '${error}': ${description} See the documentation: https://docs.frigate.video/configuration/live`,
);
onError?.(error);
},
[camera, onError],
);
// camera states
const pcRef = useRef<RTCPeerConnection | undefined>();
@@ -212,7 +224,7 @@ export default function WebRtcPlayer({
useEffect(() => {
videoLoadTimeoutRef.current = setTimeout(() => {
onError?.("stalled");
handleError("stalled", "WebRTC connection timed out.");
}, 5000);
return () => {
@@ -327,7 +339,7 @@ export default function WebRtcPlayer({
document.visibilityState === "visible" &&
pcRef.current != undefined
) {
onError("stalled");
handleError("stalled", "WebRTC connection stalled.");
}
}, 3000),
);
@@ -344,7 +356,7 @@ export default function WebRtcPlayer({
// @ts-expect-error code does exist
e.target.error.code == MediaError.MEDIA_ERR_NETWORK
) {
onError?.("startup");
handleError("startup", "Browser reported a network error.");
}
}}
/>