diff --git a/web/src/components/player/MsePlayer.tsx b/web/src/components/player/MsePlayer.tsx index 38568434d..d240f0a83 100644 --- a/web/src/components/player/MsePlayer.tsx +++ b/web/src/components/player/MsePlayer.tsx @@ -47,7 +47,7 @@ function MSEPlayer({ const [wsState, setWsState] = useState(WebSocket.CLOSED); const [connectTS, setConnectTS] = useState(0); - const [receivedData, setReceivedData] = useState(false); + const [bufferTimeout, setBufferTimeout] = useState(); const videoRef = useRef(null); const wsRef = useRef(null); @@ -103,7 +103,6 @@ function MSEPlayer({ const onConnect = useCallback(() => { if (!videoRef.current?.isConnected || !wsURL || wsRef.current) return false; - setReceivedData(false); setWsState(WebSocket.CONNECTING); setConnectTS(Date.now()); @@ -310,18 +309,33 @@ function MSEPlayer({ onLoadedData={() => { handleLoadedMetadata?.(); onPlaying?.(); - setReceivedData(true); }} muted={!audioEnabled} - onStalled={() => { - if (receivedData) { - onError?.("stalled"); - } else { - onError?.("startup"); - } - }} - onError={() => { - if (!receivedData) { + onProgress={ + onError != undefined + ? () => { + if (videoRef.current?.paused) { + return; + } + + if (bufferTimeout) { + clearTimeout(bufferTimeout); + setBufferTimeout(undefined); + } + + setBufferTimeout( + setTimeout(() => { + onError("stalled"); + }, 3000), + ); + } + : undefined + } + onError={(e) => { + if ( + // @ts-expect-error code does exist + e.target.error.code == MediaError.MEDIA_ERR_NETWORK + ) { onError?.("startup"); } diff --git a/web/src/components/player/WebRTCPlayer.tsx b/web/src/components/player/WebRTCPlayer.tsx index 0311c8c44..a8434646c 100644 --- a/web/src/components/player/WebRTCPlayer.tsx +++ b/web/src/components/player/WebRTCPlayer.tsx @@ -35,7 +35,7 @@ export default function WebRtcPlayer({ const pcRef = useRef(); const videoRef = useRef(null); - const [receivedData, setReceivedData] = useState(false); + const [bufferTimeout, setBufferTimeout] = useState(); const PeerConnection = useCallback( async (media: string) => { @@ -168,8 +168,6 @@ export default function WebRtcPlayer({ pcRef.current.close(); pcRef.current = undefined; } - - setReceivedData(false); }; }, [ camera, @@ -203,17 +201,27 @@ export default function WebRtcPlayer({ autoPlay playsInline muted={!audioEnabled} - onLoadedData={() => { - setReceivedData(true); - onPlaying?.(); - }} - onStalled={() => { - if (receivedData) { - onError?.("stalled"); - } else { - onError?.("startup"); - } - }} + onLoadedData={onPlaying} + onProgress={ + onError != undefined + ? () => { + if (videoRef.current?.paused) { + return; + } + + if (bufferTimeout) { + clearTimeout(bufferTimeout); + setBufferTimeout(undefined); + } + + setBufferTimeout( + setTimeout(() => { + onError("stalled"); + }, 3000), + ); + } + : undefined + } onClick={ iOSCompatFullScreen ? () => setiOSCompatControls(!iOSCompatControls)