Simplify dynamic video player

This commit is contained in:
Nicolas Mowen 2024-03-28 13:34:13 -06:00
parent e8a6a99b46
commit 2e4ec3c02d
3 changed files with 59 additions and 58 deletions

View File

@ -201,15 +201,8 @@ function PreviewVideoPlayer({
// canvas to cover preview transition
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const [videoWidth, videoHeight] = useMemo(() => {
if (!previewRef.current) {
return [0, 0];
}
const [videoSize, setVideoSize] = useState<number[]>([0, 0]);
return [previewRef.current.videoWidth, previewRef.current.videoHeight];
// we know the video size will be known on load
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [loaded]);
// handle switching sources
useEffect(() => {
@ -218,9 +211,12 @@ function PreviewVideoPlayer({
}
if (canvasRef.current) {
canvasRef.current
.getContext("2d")
?.drawImage(previewRef.current, 0, 0, videoWidth, videoHeight);
const context = canvasRef.current.getContext("2d");
if (context) {
context.drawImage(previewRef.current, 0, 0, videoSize[0], videoSize[1]);
}
setHasCanvas(true);
}
@ -235,7 +231,7 @@ function PreviewVideoPlayer({
return (
<div
className={`relative w-full rounded-2xl bg-black overflow-hidden ${className ?? ""} ${onClick ? "cursor-pointer" : ""}`}
className={`relative rounded-2xl bg-black overflow-hidden ${onClick ? "cursor-pointer" : ""} ${className ?? ""}`}
onClick={onClick}
>
{currentHourFrame && (
@ -246,9 +242,9 @@ function PreviewVideoPlayer({
)}
<canvas
ref={canvasRef}
width={videoWidth}
height={videoHeight}
className={`absolute h-full left-1/2 -translate-x-1/2 ${!loaded && hasCanvas ? "" : "hidden"}`}
width={videoSize[0]}
height={videoSize[1]}
className={`h-full absolute left-1/2 -translate-x-1/2 ${!loaded && hasCanvas ? "" : "hidden"}`}
/>
<video
ref={previewRef}
@ -269,8 +265,15 @@ function PreviewVideoPlayer({
previewRef.current?.pause();
}
if (previewRef.current && startTime && currentPreview) {
previewRef.current.currentTime = startTime - currentPreview.start;
if (previewRef.current) {
setVideoSize([
previewRef.current.videoWidth,
previewRef.current.videoHeight,
]);
if (startTime && currentPreview) {
previewRef.current.currentTime = startTime - currentPreview.start;
}
}
}}
>

View File

@ -41,26 +41,6 @@ export default function DynamicVideoPlayer({
const apiHost = useApiHost();
const { data: config } = useSWR<FrigateConfig>("config");
// playback behavior
const grow = useMemo(() => {
if (!config) {
return "aspect-video";
}
const aspectRatio =
config.cameras[camera].detect.width /
config.cameras[camera].detect.height;
if (aspectRatio > 2) {
return "";
} else if (aspectRatio < 16 / 9) {
return isDesktop ? "" : "aspect-tall";
} else {
return "aspect-video";
}
}, [camera, config]);
// controlling playback
const playerRef = useRef<HTMLVideoElement | null>(null);
@ -169,9 +149,9 @@ export default function DynamicVideoPlayer({
}, [controller, recordings]);
return (
<div className={`w-full relative ${className ?? ""}`}>
<>
<HlsVideoPlayer
className={isDesktop ? `w-full ${grow}` : "max-h-[50dvh]"}
className={isDesktop ? `w-full ${className}` : "max-h-[50dvh]"}
videoRef={playerRef}
visible={!(isScrubbing || isLoading)}
currentSource={source}
@ -195,7 +175,7 @@ export default function DynamicVideoPlayer({
)}
</HlsVideoPlayer>
<PreviewPlayer
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${isDesktop ? `w-full ${grow}` : "max-h-[50dvh]"}`}
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${isDesktop ? `w-full ${className}` : "max-h-[50dvh]"}`}
camera={camera}
timeRange={timeRange}
cameraPreviews={cameraPreviews}
@ -205,6 +185,6 @@ export default function DynamicVideoPlayer({
setPreviewController(previewController);
}}
/>
</div>
</>
);
}

View File

@ -194,23 +194,36 @@ export function RecordingView({
// motion timeline data
const getCameraAspect = useCallback(
(cam: string) => {
if (!config) {
return undefined;
}
const camera = config.cameras[cam];
if (!camera) {
return undefined;
}
return camera.detect.width / camera.detect.height;
},
[config],
);
const mainCameraAspect = useMemo(() => {
if (!config) {
const aspectRatio = getCameraAspect(mainCamera);
if (!aspectRatio) {
return "normal";
}
const aspectRatio =
config.cameras[mainCamera].detect.width /
config.cameras[mainCamera].detect.height;
if (aspectRatio > 2) {
} else if (aspectRatio > 2) {
return "wide";
} else if (aspectRatio < 16 / 9) {
return "tall";
} else {
return "normal";
}
}, [config, mainCamera]);
}, [getCameraAspect, mainCamera]);
const grow = useMemo(() => {
if (isMobile) {
@ -335,8 +348,8 @@ export function RecordingView({
key={mainCamera}
className={
isDesktop
? `flex justify-center mb-5 ${mainCameraAspect == "tall" ? "h-full" : "w-[78%]"}`
: `w-full ${mainCameraAspect == "wide" ? "" : "aspect-video"}`
? `flex justify-center mb-5 ${mainCameraAspect == "tall" ? "h-[90%]" : mainCameraAspect == "wide" ? "w-full" : "w-[78%]"}`
: `w-full ${mainCameraAspect == "wide" ? "aspect-wide" : "aspect-video"}`
}
>
<DynamicVideoPlayer
@ -367,13 +380,18 @@ export function RecordingView({
{allCameras.map((cam) => {
if (cam !== mainCamera) {
return (
<div key={cam}>
<div
key={cam}
className={`${mainCameraAspect == "wide" ? "h-full flex-grow" : ""}`}
style={{
aspectRatio:
mainCameraAspect == "wide"
? undefined
: getCameraAspect(cam),
}}
>
<PreviewPlayer
className={
mainCameraAspect == "tall"
? "size-full"
: "size-full"
}
className="h-full"
camera={cam}
timeRange={currentTimeRange}
cameraPreviews={allPreviews ?? []}