Handle firefox buggy behavior

This commit is contained in:
Nicolas Mowen 2025-08-14 10:19:23 -06:00
parent e58c02aa0e
commit d637935595
2 changed files with 35 additions and 3 deletions

View File

@ -43,7 +43,7 @@ type HlsVideoPlayerProps = {
fullscreen: boolean; fullscreen: boolean;
frigateControls?: boolean; frigateControls?: boolean;
inpointOffset?: number; inpointOffset?: number;
onClipEnded?: () => void; onClipEnded?: (currentTime: number) => void;
onPlayerLoaded?: () => void; onPlayerLoaded?: () => void;
onTimeUpdate?: (time: number) => void; onTimeUpdate?: (time: number) => void;
onPlaying?: () => void; onPlaying?: () => void;
@ -387,7 +387,11 @@ export default function HlsVideoPlayer({
} }
} }
}} }}
onEnded={onClipEnded} onEnded={() => {
if (onClipEnded) {
onClipEnded(getVideoTime() ?? 0);
}
}}
onError={(e) => { onError={(e) => {
if ( if (
!hlsRef.current && !hlsRef.current &&

View File

@ -14,6 +14,7 @@ import axios from "axios";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { calculateInpointOffset } from "@/utils/videoUtil"; import { calculateInpointOffset } from "@/utils/videoUtil";
import { isFirefox } from "react-device-detect";
/** /**
* Dynamically switches between video playback and scrubbing preview player. * Dynamically switches between video playback and scrubbing preview player.
@ -223,6 +224,33 @@ export default function DynamicVideoPlayer({
[recordingParams, recordings], [recordingParams, recordings],
); );
const onValidateClipEnd = useCallback(
(currentTime: number) => {
if (!onClipEnded || !controller || !recordings) {
return;
}
if (!isFirefox) {
onClipEnded();
}
// Firefox has a bug where clipEnded can be called prematurely due to buffering
// we need to validate if the current play-point is truly at the end of available recordings
const lastRecordingTime = recordings.at(-1)?.start_time;
if (
!lastRecordingTime ||
controller.getProgress(currentTime) < lastRecordingTime
) {
return;
}
onClipEnded();
},
[onClipEnded, controller, recordings],
);
return ( return (
<> <>
<HlsVideoPlayer <HlsVideoPlayer
@ -236,7 +264,7 @@ export default function DynamicVideoPlayer({
inpointOffset={inpointOffset} inpointOffset={inpointOffset}
onTimeUpdate={onTimeUpdate} onTimeUpdate={onTimeUpdate}
onPlayerLoaded={onPlayerLoaded} onPlayerLoaded={onPlayerLoaded}
onClipEnded={onClipEnded} onClipEnded={onValidateClipEnd}
onPlaying={() => { onPlaying={() => {
if (isScrubbing) { if (isScrubbing) {
playerRef.current?.pause(); playerRef.current?.pause();