mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-15 07:35:27 +03:00
refactor search detail dialog to use new generic video player component
This commit is contained in:
parent
3a9af74f54
commit
4c35a0b4e6
@ -6,7 +6,7 @@ import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
|||||||
import { getIconForLabel } from "@/utils/iconUtil";
|
import { getIconForLabel } from "@/utils/iconUtil";
|
||||||
import { useApiHost } from "@/api";
|
import { useApiHost } from "@/api";
|
||||||
import { Button } from "../../ui/button";
|
import { Button } from "../../ui/button";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Textarea } from "../../ui/textarea";
|
import { Textarea } from "../../ui/textarea";
|
||||||
@ -21,7 +21,6 @@ import {
|
|||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { Event } from "@/types/event";
|
import { Event } from "@/types/event";
|
||||||
import HlsVideoPlayer from "@/components/player/HlsVideoPlayer";
|
|
||||||
import { baseUrl } from "@/api/baseUrl";
|
import { baseUrl } from "@/api/baseUrl";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||||
@ -62,8 +61,7 @@ import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
|||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import useImageLoaded from "@/hooks/use-image-loaded";
|
import useImageLoaded from "@/hooks/use-image-loaded";
|
||||||
import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";
|
import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";
|
||||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
import { GenericVideoPlayer } from "@/components/player/GenericVideoPlayer";
|
||||||
import { VideoResolutionType } from "@/types/live";
|
|
||||||
|
|
||||||
const SEARCH_TABS = [
|
const SEARCH_TABS = [
|
||||||
"details",
|
"details",
|
||||||
@ -597,71 +595,19 @@ function ObjectSnapshotTab({
|
|||||||
type VideoTabProps = {
|
type VideoTabProps = {
|
||||||
search: SearchResult;
|
search: SearchResult;
|
||||||
};
|
};
|
||||||
function VideoTab({ search }: VideoTabProps) {
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
|
||||||
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
||||||
|
|
||||||
const endTime = useMemo(() => search.end_time ?? Date.now() / 1000, [search]);
|
|
||||||
|
|
||||||
|
export function VideoTab({ search }: VideoTabProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { data: reviewItem } = useSWR<ReviewSegment>([
|
const { data: reviewItem } = useSWR<ReviewSegment>([
|
||||||
`review/event/${search.id}`,
|
`review/event/${search.id}`,
|
||||||
]);
|
]);
|
||||||
|
const endTime = useMemo(() => search.end_time ?? Date.now() / 1000, [search]);
|
||||||
|
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const source = `${baseUrl}vod/${search.camera}/start/${search.start_time}/end/${endTime}/index.m3u8`;
|
||||||
|
|
||||||
const [{ width: containerWidth, height: containerHeight }] =
|
|
||||||
useResizeObserver(containerRef);
|
|
||||||
const [videoResolution, setVideoResolution] = useState<VideoResolutionType>({
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const videoAspectRatio = useMemo(() => {
|
|
||||||
return videoResolution.width / videoResolution.height || 16 / 9;
|
|
||||||
}, [videoResolution]);
|
|
||||||
|
|
||||||
const containerAspectRatio = useMemo(() => {
|
|
||||||
return containerWidth / containerHeight || 16 / 9;
|
|
||||||
}, [containerWidth, containerHeight]);
|
|
||||||
|
|
||||||
const videoDimensions = useMemo(() => {
|
|
||||||
if (!containerWidth || !containerHeight)
|
|
||||||
return { width: "100%", height: "100%" };
|
|
||||||
|
|
||||||
if (containerAspectRatio > videoAspectRatio) {
|
|
||||||
const height = containerHeight;
|
|
||||||
const width = height * videoAspectRatio;
|
|
||||||
return { width: `${width}px`, height: `${height}px` };
|
|
||||||
} else {
|
|
||||||
const width = containerWidth;
|
|
||||||
const height = width / videoAspectRatio;
|
|
||||||
return { width: `${width}px`, height: `${height}px` };
|
|
||||||
}
|
|
||||||
}, [containerWidth, containerHeight, videoAspectRatio, containerAspectRatio]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className="relative flex h-full w-full flex-col">
|
<GenericVideoPlayer source={source}>
|
||||||
<div className="relative flex flex-grow items-center justify-center">
|
{reviewItem && (
|
||||||
{(isLoading || !reviewItem) && (
|
|
||||||
<ActivityIndicator className="absolute left-1/2 top-1/2 z-10 -translate-x-1/2 -translate-y-1/2" />
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
className="relative flex items-center justify-center"
|
|
||||||
style={videoDimensions}
|
|
||||||
>
|
|
||||||
<HlsVideoPlayer
|
|
||||||
videoRef={videoRef}
|
|
||||||
currentSource={`${baseUrl}vod/${search.camera}/start/${search.start_time}/end/${endTime}/index.m3u8`}
|
|
||||||
hotKeys
|
|
||||||
visible
|
|
||||||
frigateControls={false}
|
|
||||||
fullscreen={false}
|
|
||||||
supportsFullscreen={false}
|
|
||||||
onPlaying={() => setIsLoading(false)}
|
|
||||||
setFullResolution={setVideoResolution}
|
|
||||||
/>
|
|
||||||
{!isLoading && reviewItem && (
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"absolute top-2 z-10 flex items-center",
|
"absolute top-2 z-10 flex items-center",
|
||||||
@ -688,8 +634,6 @@ function VideoTab({ search }: VideoTabProps) {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</GenericVideoPlayer>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user