mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Fix jsmpeg player component (#10425)
* fix jsmpeg component * preserve aspect ratio * remove forcing of jsmpeg * full height only
This commit is contained in:
parent
9d01a7dc74
commit
79ca599ace
@ -1,8 +1,7 @@
|
|||||||
import { baseUrl } from "@/api/baseUrl";
|
import { baseUrl } from "@/api/baseUrl";
|
||||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
|
||||||
// @ts-expect-error we know this doesn't have types
|
// @ts-expect-error we know this doesn't have types
|
||||||
import JSMpeg from "@cycjimmy/jsmpeg-player";
|
import JSMpeg from "@cycjimmy/jsmpeg-player";
|
||||||
import { useEffect, useMemo, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
type JSMpegPlayerProps = {
|
type JSMpegPlayerProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -20,38 +19,6 @@ export default function JSMpegPlayer({
|
|||||||
const url = `${baseUrl.replace(/^http/, "ws")}live/jsmpeg/${camera}`;
|
const url = `${baseUrl.replace(/^http/, "ws")}live/jsmpeg/${camera}`;
|
||||||
const playerRef = useRef<HTMLDivElement | null>(null);
|
const playerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const [{ width: containerWidth, height: containerHeight }] =
|
|
||||||
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 (containerHeight < finalHeight) {
|
|
||||||
return containerHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (finalHeight > 0) {
|
|
||||||
return finalHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 100;
|
|
||||||
}, [availableWidth, aspectRatio, containerHeight, height]);
|
|
||||||
const scaledWidth = useMemo(
|
|
||||||
() => Math.ceil(scaledHeight * aspectRatio - scrollBarWidth),
|
|
||||||
[scaledHeight, aspectRatio, scrollBarWidth],
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!playerRef.current) {
|
if (!playerRef.current) {
|
||||||
@ -65,16 +32,6 @@ export default function JSMpegPlayer({
|
|||||||
{ protocols: [], audio: false, videoBufferSize: 1024 * 1024 * 4 },
|
{ protocols: [], audio: false, videoBufferSize: 1024 * 1024 * 4 },
|
||||||
);
|
);
|
||||||
|
|
||||||
const fullscreen = () => {
|
|
||||||
if (video.els.canvas.webkitRequestFullScreen) {
|
|
||||||
video.els.canvas.webkitRequestFullScreen();
|
|
||||||
} else {
|
|
||||||
video.els.canvas.mozRequestFullScreen();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
video.els.canvas.addEventListener("click", fullscreen);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (playerRef.current) {
|
if (playerRef.current) {
|
||||||
try {
|
try {
|
||||||
@ -90,11 +47,8 @@ export default function JSMpegPlayer({
|
|||||||
<div className={className} ref={containerRef}>
|
<div className={className} ref={containerRef}>
|
||||||
<div
|
<div
|
||||||
ref={playerRef}
|
ref={playerRef}
|
||||||
className={`jsmpeg`}
|
className="jsmpeg h-full"
|
||||||
style={{
|
style={{ aspectRatio: width / height }}
|
||||||
height: `${scaledHeight}px`,
|
|
||||||
width: `${scaledWidth}px`,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -125,7 +125,7 @@ export default function LivePlayer({
|
|||||||
} else if (liveMode == "jsmpeg") {
|
} else if (liveMode == "jsmpeg") {
|
||||||
player = (
|
player = (
|
||||||
<JSMpegPlayer
|
<JSMpegPlayer
|
||||||
className="w-full flex justify-center rounded-2xl overflow-hidden"
|
className="size-full flex justify-center rounded-2xl overflow-hidden"
|
||||||
camera={cameraConfig.name}
|
camera={cameraConfig.name}
|
||||||
width={cameraConfig.detect.width}
|
width={cameraConfig.detect.width}
|
||||||
height={cameraConfig.detect.height}
|
height={cameraConfig.detect.height}
|
||||||
@ -137,7 +137,7 @@ export default function LivePlayer({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`relative flex justify-center w-full outline cursor-pointer ${
|
className={`relative flex justify-center ${liveMode == "jsmpeg" ? "size-full" : "w-full"} outline cursor-pointer ${
|
||||||
activeTracking
|
activeTracking
|
||||||
? "outline-severity_alert outline-1 rounded-2xl shadow-[0_0_6px_2px] shadow-severity_alert"
|
? "outline-severity_alert outline-1 rounded-2xl shadow-[0_0_6px_2px] shadow-severity_alert"
|
||||||
: "outline-0 outline-background"
|
: "outline-0 outline-background"
|
||||||
|
Loading…
Reference in New Issue
Block a user