Fix current hour

This commit is contained in:
Nicolas Mowen 2024-03-28 16:39:52 -06:00
parent 223b6c19de
commit 9b72f2dedd
4 changed files with 56 additions and 71 deletions

View File

@ -12,8 +12,7 @@ import { Preview } from "@/types/preview";
import { PreviewPlayback } from "@/types/playback";
import { isCurrentHour } from "@/utils/dateUtil";
import { baseUrl } from "@/api/baseUrl";
import { isAndroid, isChrome, isMobile, isSafari } from "react-device-detect";
import { Skeleton } from "../ui/skeleton";
import { isAndroid, isChrome, isMobile } from "react-device-detect";
import { TimeRange } from "@/types/timeline";
type PreviewPlayerProps = {
@ -34,7 +33,6 @@ export default function PreviewPlayer({
cameraPreviews,
startTime,
isScrubbing,
forceAspect,
onControllerReady,
onClick,
}: PreviewPlayerProps) {
@ -62,7 +60,6 @@ export default function PreviewPlayer({
cameraPreviews={cameraPreviews}
startTime={startTime}
isScrubbing={isScrubbing}
forceAspect={forceAspect}
currentHourFrame={currentHourFrame}
onControllerReady={onControllerReady}
onClick={onClick}
@ -92,7 +89,6 @@ type PreviewVideoPlayerProps = {
cameraPreviews: Preview[];
startTime?: number;
isScrubbing: boolean;
forceAspect?: number;
currentHourFrame?: string;
onControllerReady: (controller: PreviewVideoController) => void;
onClick?: () => void;
@ -105,7 +101,6 @@ function PreviewVideoPlayer({
cameraPreviews,
startTime,
isScrubbing,
forceAspect,
currentHourFrame,
onControllerReady,
onClick,
@ -148,8 +143,6 @@ function PreviewVideoPlayer({
// initial state
const [loaded, setLoaded] = useState(false);
const [hasCanvas, setHasCanvas] = useState(false);
const initialPreview = useMemo(() => {
return cameraPreviews.find(
(preview) =>
@ -191,7 +184,6 @@ function PreviewVideoPlayer({
if (preview != currentPreview) {
setCurrentPreview(preview);
setLoaded(false);
}
controller.newPlayback({
@ -215,21 +207,20 @@ function PreviewVideoPlayer({
return;
}
if (canvasRef.current) {
const context = canvasRef.current.getContext("2d");
if (context) {
context.drawImage(previewRef.current, 0, 0, videoSize[0], videoSize[1]);
}
setHasCanvas(true);
if (!canvasRef.current && videoSize[0] > 0) {
const canvas = document.createElement("canvas");
canvas.width = videoSize[0];
canvas.height = videoSize[1];
canvasRef.current = canvas;
}
if (isSafari) {
setTimeout(() => previewRef.current?.load(), 100);
} else {
previewRef.current.load();
const context = canvasRef.current?.getContext("2d");
if (context) {
context.drawImage(previewRef.current, 0, 0, videoSize[0], videoSize[1]);
setCurrentHourFrame(canvasRef.current?.toDataURL("image/webp"));
}
// we only want this to change when current preview changes
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentPreview, previewRef]);
@ -237,26 +228,16 @@ function PreviewVideoPlayer({
return (
<div
className={`relative rounded-2xl bg-black overflow-hidden ${onClick ? "cursor-pointer" : ""} ${className ?? ""}`}
style={{
aspectRatio: forceAspect,
}}
onClick={onClick}
>
{currentHourFrame && (
<img
className="absolute size-full object-contain"
src={currentHourFrame}
/>
)}
<canvas
ref={canvasRef}
width={videoSize[0]}
height={videoSize[1]}
className={`h-full absolute left-1/2 -translate-x-1/2 ${!loaded && hasCanvas ? "" : "hidden"}`}
<img
className={`absolute size-full object-contain ${currentHourFrame ? "visible" : "invisible"}`}
src={currentHourFrame}
onLoad={() => previewRef.current?.load()}
/>
<video
ref={previewRef}
className="size-full"
className="absolute size-full"
preload="auto"
autoPlay
playsInline
@ -265,7 +246,6 @@ function PreviewVideoPlayer({
onSeeked={onPreviewSeeked}
onLoadedData={() => {
setCurrentHourFrame(undefined);
setLoaded(true);
if (controller) {
controller.previewReady();
@ -289,9 +269,6 @@ function PreviewVideoPlayer({
<source src={currentPreview.src} type={currentPreview.type} />
)}
</video>
{!loaded && !hasCanvas && !currentHourFrame && (
<Skeleton className="absolute inset-0" />
)}
{cameraPreviews && !currentPreview && (
<div className="absolute inset-0 text-white rounded-2xl flex justify-center items-center">
No Preview Found
@ -479,7 +456,7 @@ function PreviewFramesPlayer({
return (
<div
className={`relative w-full ${className ?? ""} ${onClick ? "cursor-pointer" : ""}`}
className={`relative ${className ?? ""} ${onClick ? "cursor-pointer" : ""}`}
onClick={onClick}
>
<img

View File

@ -9,7 +9,6 @@ import PreviewPlayer, { PreviewController } from "../PreviewPlayer";
import { DynamicVideoController } from "./DynamicVideoController";
import HlsVideoPlayer from "../HlsVideoPlayer";
import { TimeRange, Timeline } from "@/types/timeline";
import { isDesktop } from "react-device-detect";
/**
* Dynamically switches between video playback and scrubbing preview player.
@ -151,7 +150,7 @@ export default function DynamicVideoPlayer({
return (
<>
<HlsVideoPlayer
className={isDesktop ? `w-full ${className}` : "max-h-[50dvh]"}
className={className ?? ""}
videoRef={playerRef}
visible={!(isScrubbing || isLoading)}
currentSource={source}
@ -175,7 +174,7 @@ export default function DynamicVideoPlayer({
)}
</HlsVideoPlayer>
<PreviewPlayer
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${isDesktop ? `w-full ${className}` : "max-h-[50dvh]"}`}
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${className}`}
camera={camera}
timeRange={timeRange}
cameraPreviews={cameraPreviews}

View File

@ -127,8 +127,8 @@ export function getTimelineItemDescription(timelineItem: Timeline) {
* @returns timeRange chunked into individual hours
*/
export function getChunkedTimeDay(timeRange: TimeRange): TimeRange[] {
const endOfThisHour = new Date();
endOfThisHour.setHours(endOfThisHour.getHours() + 1, 0, 0, 0);
const endOfThisHour = new Date(timeRange.before * 1000);
endOfThisHour.setSeconds(0, 0);
const data: TimeRange[] = [];
const startDay = new Date(timeRange.after * 1000);
startDay.setMinutes(0, 0, 0);
@ -136,7 +136,7 @@ export function getChunkedTimeDay(timeRange: TimeRange): TimeRange[] {
let end = 0;
for (let i = 0; i < 24; i++) {
startDay.setHours(startDay.getHours() + 1);
startDay.setHours(startDay.getHours() + 1, 0, 0, 0);
if (startDay > endOfThisHour) {
break;
@ -150,6 +150,11 @@ export function getChunkedTimeDay(timeRange: TimeRange): TimeRange[] {
start = startDay.getTime() / 1000;
}
data.push({
after: start,
before: Math.floor(timeRange.before),
});
return data;
}

View File

@ -226,14 +226,14 @@ export function RecordingView({
}, [getCameraAspect, mainCamera]);
const grow = useMemo(() => {
if (isMobile) {
return "";
}
if (mainCameraAspect == "wide") {
return "w-full aspect-wide";
} else if (isDesktop && mainCameraAspect == "tall") {
return "h-full aspect-tall flex flex-col justify-center";
} else if (mainCameraAspect == "tall") {
if (isDesktop) {
return "h-full aspect-tall flex flex-col justify-center";
} else {
return "size-full";
}
} else {
return "w-full aspect-video";
}
@ -352,10 +352,11 @@ export function RecordingView({
: `w-full ${mainCameraAspect == "wide" ? "aspect-wide" : "aspect-video"}`
}
style={{
aspectRatio:
mainCameraAspect == "tall"
aspectRatio: isDesktop
? mainCameraAspect == "tall"
? getCameraAspect(mainCamera)
: undefined,
: undefined
: Math.max(1, getCameraAspect(mainCamera) ?? 0),
}}
>
<DynamicVideoPlayer
@ -381,35 +382,38 @@ export function RecordingView({
</div>
{isDesktop && (
<div
className={`flex gap-2 ${mainCameraAspect == "tall" ? "h-full w-[16%] flex-col overflow-y-auto" : "w-full justify-center overflow-x-auto"}`}
className={`flex gap-2 ${mainCameraAspect == "tall" ? "h-full w-[12%] flex-col justify-center overflow-y-auto" : "w-full h-[14%] justify-center items-center overflow-x-auto"} `}
>
{allCameras.map((cam) => {
if (cam !== mainCamera) {
const preview = (
if (cam == mainCamera) {
return;
}
return (
<div
key={cam}
className={
mainCameraAspect == "tall" ? undefined : "h-full"
}
style={{
aspectRatio: getCameraAspect(cam),
}}
>
<PreviewPlayer
key={cam}
className={`${mainCameraAspect == "wide" ? "flex-grow" : ""}`}
className="size-full"
camera={cam}
timeRange={currentTimeRange}
cameraPreviews={allPreviews ?? []}
startTime={startTime}
isScrubbing={scrubbing}
forceAspect={getCameraAspect(cam)}
onControllerReady={(controller) => {
previewRefs.current[cam] = controller;
controller.scrubToTimestamp(startTime);
}}
onClick={() => onSelectCamera(cam)}
/>
);
if (mainCameraAspect == "tall") {
return <div key={`${cam}-t`}>{preview}</div>;
}
return preview;
}
return null;
</div>
);
})}
</div>
)}