Improve autoplay performance

This commit is contained in:
Nick Mowen 2023-12-15 07:23:38 -07:00
parent 4dade5e680
commit de689d6f56

View File

@ -1,7 +1,7 @@
import { FrigateConfig } from "@/types/frigateConfig"; import { FrigateConfig } from "@/types/frigateConfig";
import VideoPlayer from "./VideoPlayer"; import VideoPlayer from "./VideoPlayer";
import useSWR from "swr"; import useSWR from "swr";
import { useCallback, useRef } from "react"; import { useCallback, useRef, useState } from "react";
import { useApiHost } from "@/api"; import { useApiHost } from "@/api";
import Player from "video.js/dist/types/player"; import Player from "video.js/dist/types/player";
import { AspectRatio } from "../ui/aspect-ratio"; import { AspectRatio } from "../ui/aspect-ratio";
@ -33,6 +33,8 @@ export default function PreviewThumbnailPlayer({
const playerRef = useRef<Player | null>(null); const playerRef = useRef<Player | null>(null);
const apiHost = useApiHost(); const apiHost = useApiHost();
const [visible, setVisible] = useState(false);
const onPlayback = useCallback( const onPlayback = useCallback(
(isHovered: Boolean) => { (isHovered: Boolean) => {
if (!relevantPreview || !playerRef.current) { if (!relevantPreview || !playerRef.current) {
@ -52,7 +54,7 @@ export default function PreviewThumbnailPlayer({
const observer = useRef<IntersectionObserver | null>(); const observer = useRef<IntersectionObserver | null>();
const inViewRef = useCallback( const inViewRef = useCallback(
(node: HTMLElement | null) => { (node: HTMLElement | null) => {
if (!shouldAutoPlay || observer.current) { if (observer.current) {
return; return;
} }
@ -60,12 +62,22 @@ export default function PreviewThumbnailPlayer({
observer.current = new IntersectionObserver( observer.current = new IntersectionObserver(
(entries) => { (entries) => {
if (entries[0].isIntersecting) { if (entries[0].isIntersecting) {
if (entries[0].intersectionRatio == 1.0) {
if (shouldAutoPlay) {
onPlayback(true); onPlayback(true);
}
} else { } else {
setVisible(true);
}
} else {
if (shouldAutoPlay) {
onPlayback(false); onPlayback(false);
} }
setVisible(false);
}
}, },
{ threshold: 1.0 } { threshold: [0.0, 1.0], rootMargin: "25% 0% 25% 0%" }
); );
if (node) observer.current.observe(node); if (node) observer.current.observe(node);
} catch (e) { } catch (e) {
@ -75,44 +87,27 @@ export default function PreviewThumbnailPlayer({
[observer, onPlayback] [observer, onPlayback]
); );
if (!relevantPreview) { let content;
if (!relevantPreview || !visible) {
if (isCurrentHour(startTs)) { if (isCurrentHour(startTs)) {
return ( content = (
<AspectRatio
ratio={16 / 9}
className="bg-black flex justify-center items-center"
>
<img <img
className={`${getPreviewWidth(camera, config)}`} className={`${getPreviewWidth(camera, config)}`}
loading="lazy" loading="lazy"
src={`${apiHost}api/preview/${camera}/${startTs}/thumbnail.jpg`} src={`${apiHost}api/preview/${camera}/${startTs}/thumbnail.jpg`}
/> />
</AspectRatio>
); );
} }
return ( content = (
<AspectRatio
ratio={16 / 9}
className="bg-black flex justify-center items-center"
>
<img <img
className="w-[160px]" className="w-[160px]"
loading="lazy" loading="lazy"
src={`${apiHost}api/events/${eventId}/thumbnail.jpg`} src={`${apiHost}api/events/${eventId}/thumbnail.jpg`}
/> />
</AspectRatio>
); );
} } else {
content = (
return (
<AspectRatio
ref={shouldAutoPlay ? inViewRef : null}
ratio={16 / 9}
className="bg-black flex justify-center items-center"
onMouseEnter={() => onPlayback(true)}
onMouseLeave={() => onPlayback(false)}
>
<div className={`${getPreviewWidth(camera, config)}`}> <div className={`${getPreviewWidth(camera, config)}`}>
<VideoPlayer <VideoPlayer
options={{ options={{
@ -139,6 +134,18 @@ export default function PreviewThumbnailPlayer({
}} }}
/> />
</div> </div>
);
}
return (
<AspectRatio
ref={inViewRef}
ratio={16 / 9}
className="bg-black flex justify-center items-center"
onMouseEnter={() => onPlayback(true)}
onMouseLeave={() => onPlayback(false)}
>
{content}
</AspectRatio> </AspectRatio>
); );
} }