feat(results): replace video playback with detection image preview and map
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
'use client';
|
||||
|
||||
import { RefObject } from 'react';
|
||||
import { RefObject, useEffect } from 'react';
|
||||
import { AlertTriangle, Loader2 } from 'lucide-react';
|
||||
import type { DetectionResultLog } from '@/types';
|
||||
import { useDetectionThumbnails } from './useDetectionThumbnails';
|
||||
import BoundingBoxOverlay from '@/components/annotation/boundingBoxOverlay';
|
||||
import {
|
||||
MediaPlayer,
|
||||
MediaProvider,
|
||||
Poster,
|
||||
isVideoProvider,
|
||||
type MediaPlayerInstance,
|
||||
useMediaProvider,
|
||||
} from '@vidstack/react';
|
||||
import {
|
||||
DefaultVideoLayout,
|
||||
@@ -18,22 +21,54 @@ import {
|
||||
interface AnnotatedVideoPlayerProps {
|
||||
videoRef: RefObject<MediaPlayerInstance | null>;
|
||||
logs: DetectionResultLog[];
|
||||
visibleLogs: DetectionResultLog[];
|
||||
videoWidth: number;
|
||||
videoHeight: number;
|
||||
videoUrl: string | null;
|
||||
isLoading: boolean;
|
||||
isError: boolean;
|
||||
onRetry: () => void;
|
||||
onTimeUpdate: () => void;
|
||||
onVideoFrame: (mediaTime: number) => void;
|
||||
onSeeked: () => void;
|
||||
}
|
||||
|
||||
function VideoFrameSync({
|
||||
onVideoFrame,
|
||||
}: Pick<AnnotatedVideoPlayerProps, 'onVideoFrame'>) {
|
||||
const provider = useMediaProvider();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isVideoProvider(provider)) return;
|
||||
|
||||
const video = provider.video;
|
||||
let callbackId: number;
|
||||
|
||||
const update = (_now: number, metadata: VideoFrameCallbackMetadata) => {
|
||||
onVideoFrame(metadata.mediaTime);
|
||||
callbackId = video.requestVideoFrameCallback(update);
|
||||
};
|
||||
|
||||
callbackId = video.requestVideoFrameCallback(update);
|
||||
|
||||
return () => video.cancelVideoFrameCallback(callbackId);
|
||||
}, [onVideoFrame, provider]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function AnnotatedVideoPlayer({
|
||||
videoRef,
|
||||
logs,
|
||||
visibleLogs,
|
||||
videoWidth,
|
||||
videoHeight,
|
||||
videoUrl,
|
||||
isLoading,
|
||||
isError,
|
||||
onRetry,
|
||||
onTimeUpdate,
|
||||
onVideoFrame,
|
||||
onSeeked,
|
||||
}: AnnotatedVideoPlayerProps) {
|
||||
const thumbnails = useDetectionThumbnails(logs);
|
||||
@@ -55,6 +90,12 @@ export default function AnnotatedVideoPlayer({
|
||||
<MediaProvider>
|
||||
<Poster className="vds-poster" />
|
||||
</MediaProvider>
|
||||
<VideoFrameSync onVideoFrame={onVideoFrame} />
|
||||
<BoundingBoxOverlay
|
||||
detections={visibleLogs}
|
||||
videoWidth={videoWidth}
|
||||
videoHeight={videoHeight}
|
||||
/>
|
||||
<DefaultVideoLayout
|
||||
thumbnails={thumbnails}
|
||||
icons={defaultLayoutIcons}
|
||||
|
||||
Reference in New Issue
Block a user