mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Check websocket readyState for disconnect and fix firefox pip (#12216)
This commit is contained in:
parent
f0159bf41e
commit
f9e1ad253f
@ -128,12 +128,12 @@ function MSEPlayer({
|
|||||||
setSafariPlaying(false);
|
setSafariPlaying(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsRef.current && wsState != WebSocket.CLOSED) {
|
if (wsRef.current) {
|
||||||
setWsState(WebSocket.CLOSED);
|
setWsState(WebSocket.CLOSED);
|
||||||
wsRef.current.close();
|
wsRef.current.close();
|
||||||
wsRef.current = null;
|
wsRef.current = null;
|
||||||
}
|
}
|
||||||
}, [wsState, bufferTimeout, safariPlaying]);
|
}, [bufferTimeout, safariPlaying]);
|
||||||
|
|
||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
setWsState(WebSocket.OPEN);
|
setWsState(WebSocket.OPEN);
|
||||||
@ -359,7 +359,7 @@ function MSEPlayer({
|
|||||||
// ensure we disconnect for slower connections
|
// ensure we disconnect for slower connections
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (wsState === WebSocket.OPEN && !playbackEnabled) {
|
if (wsRef.current?.readyState === WebSocket.OPEN && !playbackEnabled) {
|
||||||
if (bufferTimeout) {
|
if (bufferTimeout) {
|
||||||
clearTimeout(bufferTimeout);
|
clearTimeout(bufferTimeout);
|
||||||
setBufferTimeout(undefined);
|
setBufferTimeout(undefined);
|
||||||
|
@ -21,7 +21,11 @@ import { TooltipProvider } from "@/components/ui/tooltip";
|
|||||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||||
import useKeyboardListener from "@/hooks/use-keyboard-listener";
|
import useKeyboardListener from "@/hooks/use-keyboard-listener";
|
||||||
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { LiveStreamMetadata, VideoResolutionType } from "@/types/live";
|
import {
|
||||||
|
LivePlayerError,
|
||||||
|
LiveStreamMetadata,
|
||||||
|
VideoResolutionType,
|
||||||
|
} from "@/types/live";
|
||||||
import { CameraPtzInfo } from "@/types/ptz";
|
import { CameraPtzInfo } from "@/types/ptz";
|
||||||
import { RecordingStartingPoint } from "@/types/record";
|
import { RecordingStartingPoint } from "@/types/record";
|
||||||
import React, {
|
import React, {
|
||||||
@ -33,6 +37,7 @@ import React, {
|
|||||||
} from "react";
|
} from "react";
|
||||||
import {
|
import {
|
||||||
isDesktop,
|
isDesktop,
|
||||||
|
isFirefox,
|
||||||
isIOS,
|
isIOS,
|
||||||
isMobile,
|
isMobile,
|
||||||
isTablet,
|
isTablet,
|
||||||
@ -275,6 +280,15 @@ export default function LiveCameraView({
|
|||||||
}
|
}
|
||||||
}, [fullscreen, isPortrait, cameraAspectRatio, containerAspectRatio]);
|
}, [fullscreen, isPortrait, cameraAspectRatio, containerAspectRatio]);
|
||||||
|
|
||||||
|
const handleError = useCallback((e: LivePlayerError) => {
|
||||||
|
if (e == "mse-decode") {
|
||||||
|
setWebRTC(true);
|
||||||
|
} else {
|
||||||
|
setWebRTC(false);
|
||||||
|
setLowBandwidth(true);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransformWrapper minScale={1.0}>
|
<TransformWrapper minScale={1.0}>
|
||||||
<div
|
<div
|
||||||
@ -353,7 +367,7 @@ export default function LiveCameraView({
|
|||||||
onClick={toggleFullscreen}
|
onClick={toggleFullscreen}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!isIOS && (
|
{!isIOS && !isFirefox && (
|
||||||
<CameraFeatureToggle
|
<CameraFeatureToggle
|
||||||
className="p-2 md:p-0"
|
className="p-2 md:p-0"
|
||||||
variant={fullscreen ? "overlay" : "primary"}
|
variant={fullscreen ? "overlay" : "primary"}
|
||||||
@ -435,26 +449,21 @@ export default function LiveCameraView({
|
|||||||
pip={pip}
|
pip={pip}
|
||||||
setFullResolution={setFullResolution}
|
setFullResolution={setFullResolution}
|
||||||
containerRef={containerRef}
|
containerRef={containerRef}
|
||||||
onError={(e) => {
|
onError={handleError}
|
||||||
if (e == "mse-decode") {
|
|
||||||
setWebRTC(true);
|
|
||||||
} else {
|
|
||||||
setWebRTC(false);
|
|
||||||
setLowBandwidth(true);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{camera.onvif.host != "" && (
|
|
||||||
<PtzControlPanel
|
|
||||||
camera={camera.name}
|
|
||||||
clickOverlay={clickOverlay}
|
|
||||||
setClickOverlay={setClickOverlay}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</TransformComponent>
|
</TransformComponent>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{camera.onvif.host != "" && (
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<PtzControlPanel
|
||||||
|
camera={camera.name}
|
||||||
|
clickOverlay={clickOverlay}
|
||||||
|
setClickOverlay={setClickOverlay}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</TransformWrapper>
|
</TransformWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import DraggableGridLayout from "./DraggableGridLayout";
|
|||||||
import { IoClose } from "react-icons/io5";
|
import { IoClose } from "react-icons/io5";
|
||||||
import { LuLayoutDashboard } from "react-icons/lu";
|
import { LuLayoutDashboard } from "react-icons/lu";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { LivePlayerMode } from "@/types/live";
|
import { LivePlayerError, LivePlayerMode } from "@/types/live";
|
||||||
|
|
||||||
type LiveDashboardViewProps = {
|
type LiveDashboardViewProps = {
|
||||||
cameras: CameraConfig[];
|
cameras: CameraConfig[];
|
||||||
@ -184,6 +184,21 @@ export default function LiveDashboardView({
|
|||||||
|
|
||||||
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
||||||
|
|
||||||
|
const handleError = useCallback(
|
||||||
|
(cameraName: string, error: LivePlayerError) => {
|
||||||
|
setPreferredLiveModes((prevModes) => {
|
||||||
|
const newModes = { ...prevModes };
|
||||||
|
if (error === "mse-decode") {
|
||||||
|
newModes[cameraName] = "webrtc";
|
||||||
|
} else {
|
||||||
|
newModes[cameraName] = "jsmpeg";
|
||||||
|
}
|
||||||
|
return newModes;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[setPreferredLiveModes],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="scrollbar-container size-full overflow-y-auto px-1 pt-2 md:p-2"
|
className="scrollbar-container size-full overflow-y-auto px-1 pt-2 md:p-2"
|
||||||
@ -315,17 +330,7 @@ export default function LiveDashboardView({
|
|||||||
preferredLiveMode={preferredLiveModes[camera.name] ?? "mse"}
|
preferredLiveMode={preferredLiveModes[camera.name] ?? "mse"}
|
||||||
autoLive={autoLiveView}
|
autoLive={autoLiveView}
|
||||||
onClick={() => onSelectCamera(camera.name)}
|
onClick={() => onSelectCamera(camera.name)}
|
||||||
onError={(e) => {
|
onError={(e) => handleError(camera.name, e)}
|
||||||
setPreferredLiveModes((prevModes) => {
|
|
||||||
const newModes = { ...prevModes };
|
|
||||||
if (e === "mse-decode") {
|
|
||||||
newModes[camera.name] = "webrtc";
|
|
||||||
} else {
|
|
||||||
newModes[camera.name] = "jsmpeg";
|
|
||||||
}
|
|
||||||
return newModes;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
Loading…
Reference in New Issue
Block a user