diff --git a/web/src/components/player/HlsVideoPlayer.tsx b/web/src/components/player/HlsVideoPlayer.tsx index 2ac9196ba..e72a01e3c 100644 --- a/web/src/components/player/HlsVideoPlayer.tsx +++ b/web/src/components/player/HlsVideoPlayer.tsx @@ -135,23 +135,6 @@ export default function HlsVideoPlayer({ if (!useHlsCompat) { videoRef.current.src = currentSource.playlist; videoRef.current.load(); - // For native HLS, we need to seek after metadata loads since startPosition isn't supported - if (currentSource.startPosition !== undefined) { - videoRef.current.addEventListener( - "loadedmetadata", - () => { - if (videoRef.current && currentSource.startPosition !== undefined) { - // Clamp startPosition to video duration to prevent seeking beyond the end - const clampedPosition = Math.min( - currentSource.startPosition, - videoRef.current.duration || Infinity, - ); - videoRef.current.currentTime = clampedPosition; - } - }, - { once: true }, - ); - } return; } diff --git a/web/src/components/player/dynamic/DynamicVideoPlayer.tsx b/web/src/components/player/dynamic/DynamicVideoPlayer.tsx index 252d39c2b..2a6f3a1cf 100644 --- a/web/src/components/player/dynamic/DynamicVideoPlayer.tsx +++ b/web/src/components/player/dynamic/DynamicVideoPlayer.tsx @@ -111,6 +111,7 @@ export default function DynamicVideoPlayer({ const [loadingTimeout, setLoadingTimeout] = useState(); const [source, setSource] = useState({ playlist: `${apiHost}vod/${camera}/start/${timeRange.after}/end/${timeRange.before}/master.m3u8`, + startPosition: startTimestamp ? timeRange.after - startTimestamp : 0, }); // start at correct time @@ -195,8 +196,26 @@ export default function DynamicVideoPlayer({ playerRef.current.autoplay = !isScrubbing; } + let startPosition = undefined; + + if (startTimestamp) { + const inpointOffset = calculateInpointOffset( + recordingParams.after, + (recordings || [])[0], + ); + const idealStartPosition = Math.max( + 0, + startTimestamp - timeRange.after - inpointOffset, + ); + + if (idealStartPosition >= recordings[0].start_time - timeRange.after) { + startPosition = idealStartPosition; + } + } + setSource({ playlist: `${apiHost}vod/${camera}/start/${recordingParams.after}/end/${recordingParams.before}/master.m3u8`, + startPosition, }); setLoadingTimeout(setTimeout(() => setIsLoading(true), 1000));