Fix jsmpeg

This commit is contained in:
Nick Mowen 2023-12-17 14:15:53 -07:00
parent aabfe5f615
commit 9e00f4a7f5
2 changed files with 54 additions and 12 deletions

View File

@ -1,5 +1,5 @@
import WebRtcPlayer from "./WebRTCPlayer";
import { BirdseyeConfig, CameraConfig } from "@/types/frigateConfig";
import { BirdseyeConfig } from "@/types/frigateConfig";
import ActivityIndicator from "../ui/activity-indicator";
import JSMpegPlayer from "./JSMpegPlayer";

View File

@ -1,6 +1,8 @@
import { baseUrl } from "@/api/baseUrl";
import { useResizeObserver } from "@/hooks/resize-observer";
// @ts-ignore we know this doesn't have types
import JSMpeg from "@cycjimmy/jsmpeg-player";
import { useEffect, useRef } from "react";
import { useEffect, useMemo, useRef } from "react";
type JSMpegPlayerProps = {
camera: string;
@ -13,10 +15,43 @@ export default function JSMpegPlayer({
width,
height,
}: JSMpegPlayerProps) {
const playerRef = useRef<HTMLDivElement | null>(null);
const url = `${baseUrl.replace(/^http/, "ws")}live/jsmpeg/${camera}`;
const playerRef = useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const [{ width: containerWidth }] = useResizeObserver(containerRef);
// Add scrollbar width (when visible) to the available observer width to eliminate screen juddering.
// https://github.com/blakeblackshear/frigate/issues/1657
let scrollBarWidth = 0;
if (window.innerWidth && document.body.offsetWidth) {
scrollBarWidth = window.innerWidth - document.body.offsetWidth;
}
const availableWidth = scrollBarWidth
? containerWidth + scrollBarWidth
: containerWidth;
const aspectRatio = width / height;
const scaledHeight = useMemo(() => {
const scaledHeight = Math.floor(availableWidth / aspectRatio);
const finalHeight = Math.min(scaledHeight, height);
if (finalHeight > 0) {
return finalHeight;
}
return 100;
}, [availableWidth, aspectRatio, height]);
const scaledWidth = useMemo(
() => Math.ceil(scaledHeight * aspectRatio - scrollBarWidth),
[scaledHeight, aspectRatio, scrollBarWidth]
);
useEffect(() => {
if (!playerRef.current) {
return;
}
console.log("player ref exists and creating video");
const video = new JSMpeg.VideoElement(
playerRef.current,
url,
@ -35,18 +70,25 @@ export default function JSMpegPlayer({
video.els.canvas.addEventListener("click", fullscreen);
return () => {
video.destroy();
if (playerRef.current) {
try {
video.destroy();
} catch (e) {}
playerRef.current = null;
}
};
}, [url]);
return (
<div
ref={playerRef}
className="jsmpeg"
style={{
maxHeight: `${height}px`,
maxWidth: `${width} px`,
}}
/>
<div ref={containerRef}>
<div
ref={playerRef}
className={`jsmpeg`}
style={{
height: `${scaledHeight}px`,
width: `${scaledWidth} px`,
}}
/>
</div>
);
}