* fix recordings check

* Only calculate inpoint offset for beginning of hour segment

* Cleanup

* Fix seeking

* add Czech

* explore i18n fix

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
This commit is contained in:
Josh Hawkins 2025-05-19 15:43:22 -05:00 committed by GitHub
parent 717517aeb5
commit 8a143b4284
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 44 additions and 27 deletions

View File

@ -109,6 +109,7 @@ imdecode
imencode
imread
imwrite
inpoint
interp
iostat
iotop

View File

@ -1,6 +1,7 @@
{
"documentTitle": "Explore - Frigate",
"generativeAI": "Generative AI",
"exploreMore": "Explore more {{label}} objects",
"exploreIsUnavailable": {
"title": "Explore is Unavailable",
"embeddingsReindexing": {

View File

@ -230,7 +230,7 @@ export default function HlsVideoPlayer({
hotKeys={hotKeys}
onPlayPause={onPlayPause}
onSeek={(diff) => {
const currentTime = getVideoTime();
const currentTime = videoRef.current?.currentTime;
if (!videoRef.current || !currentTime) {
return;

View File

@ -2,6 +2,7 @@ import { Recording } from "@/types/record";
import { DynamicPlayback } from "@/types/playback";
import { PreviewController } from "../PreviewPlayer";
import { TimeRange, ObjectLifecycleSequence } from "@/types/timeline";
import { calculateInpointOffset } from "@/utils/videoUtil";
type PlayerMode = "playback" | "scrubbing";
@ -42,7 +43,10 @@ export class DynamicVideoController {
newPlayback(newPlayback: DynamicPlayback) {
this.recordings = newPlayback.recordings;
this.timeRange = newPlayback.timeRange;
this.inpointOffset = this.timeRange.after - this.recordings[0].start_time;
this.inpointOffset = calculateInpointOffset(
this.timeRange.after,
this.recordings[0],
);
if (this.timeToStart) {
this.seekToTimestamp(this.timeToStart);

View File

@ -13,6 +13,7 @@ import { VideoResolutionType } from "@/types/live";
import axios from "axios";
import { cn } from "@/lib/utils";
import { useTranslation } from "react-i18next";
import { calculateInpointOffset } from "@/utils/videoUtil";
/**
* Dynamically switches between video playback and scrubbing preview player.
@ -197,18 +198,10 @@ export default function DynamicVideoPlayer({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [controller, recordings]);
/** the HLS endpoint returns the vod segments with the first
* segment of the hour trimmed, meaning it will start at
* the beginning of the hour, cutting off any difference
* that the segment has.
*/
const inpointOffset = useMemo(() => {
if (!recordingParams || !recordings) {
return 0;
}
return recordingParams.after - recordings[0].start_time;
}, [recordingParams, recordings]);
const inpointOffset = useMemo(
() => calculateInpointOffset(recordingParams.after, (recordings || [])[0]),
[recordingParams, recordings],
);
return (
<>

View File

@ -6,10 +6,11 @@ export const supportedLanguageKeys = [
"it",
"nl",
"nb-NO",
"tr",
"pl",
"zh-CN",
"yue-Hant",
"ru",
"tr",
"pl",
"uk",
"cs",
];

View File

@ -0,0 +1,26 @@
import { Recording } from "@/types/record";
/** the HLS endpoint returns the vod segments with the first
* segment of the hour trimmed, meaning it will start at
* the beginning of the hour, cutting off any difference
* that the segment has.
*/
export function calculateInpointOffset(
timeRangeStart: number | undefined,
firstRecordingSegment: Recording | undefined,
): number {
if (!timeRangeStart || !firstRecordingSegment) {
return 0;
}
// if the first recording segment does not cross over
// the beginning of the time range then there is no offset
if (
firstRecordingSegment.start_time < timeRangeStart &&
firstRecordingSegment.end_time > timeRangeStart
) {
return timeRangeStart - firstRecordingSegment.start_time;
}
return 0;
}

View File

@ -190,8 +190,8 @@ function ThumbnailRow({
/>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent className="smart-capitalize">
<ExploreMoreLink objectType={objectType} />
<TooltipContent>
{t("exploreMore", { label: objectType })}
</TooltipContent>
</TooltipPortal>
</Tooltip>
@ -283,12 +283,3 @@ function ExploreThumbnailImage({
</SearchResultActions>
);
}
function ExploreMoreLink({ objectType }: { objectType: string }) {
const formattedType = objectType.replaceAll("_", " ");
const label = formattedType.endsWith("s")
? `${formattedType}es`
: `${formattedType}s`;
return <div>Explore More {label}</div>;
}