feat(plex): stats-for-nerds debug overlay (E6 S2)
Add a toggleable stats overlay to the Plex player: active mode (direct/remux/transcode), transport, resolution, codec, bitrate, HLS level, dropped frames, buffer-ahead, session offset and position — sampled once a second off the live videoRef + hlsRef (no data layer). Non-modal corner panel, aria-live polite, dismissable; toggled with 'd', a gauge control-bar button, or its X. Number-crunching lives in a pure, unit-tested plexStats module. Doubles as the S1 transcode-verification surface. i18n HU/EN.
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
ArrowLeft,
|
||||
Clock,
|
||||
Download,
|
||||
Gauge,
|
||||
Info,
|
||||
Keyboard,
|
||||
Languages,
|
||||
@@ -40,6 +41,7 @@ import {
|
||||
} from "../lib/plexPlayerPrefs";
|
||||
import { Ctrl, PanelHead, Skip10 } from "./plexPlayerControls";
|
||||
import { PlexPlayerSettings } from "./PlexPlayerSettings";
|
||||
import { PlexStatsOverlay } from "./PlexStatsOverlay";
|
||||
import {
|
||||
useAutoSkip,
|
||||
useControlsVisibility,
|
||||
@@ -171,6 +173,10 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
const [infoOpen, setInfoOpen] = useState(false);
|
||||
const infoOpenRef = useRef(false);
|
||||
infoOpenRef.current = infoOpen;
|
||||
// "D" toggles the stats-for-nerds debug overlay (active mode, codec, dropped frames, buffer…).
|
||||
const [statsOpen, setStatsOpen] = useState(false);
|
||||
const statsOpenRef = useRef(false);
|
||||
statsOpenRef.current = statsOpen;
|
||||
const now = useWallClock();
|
||||
|
||||
durationRef.current = duration;
|
||||
@@ -533,6 +539,7 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
setTracksOpen(false);
|
||||
} else if (helpOpenRef.current) setHelpOpen(false);
|
||||
else if (infoOpenRef.current) setInfoOpen(false);
|
||||
else if (statsOpenRef.current) setStatsOpen(false);
|
||||
else onClose();
|
||||
}, [onClose]);
|
||||
|
||||
@@ -618,6 +625,10 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
case "I":
|
||||
setInfoOpen((v) => !v);
|
||||
break;
|
||||
case "d":
|
||||
case "D":
|
||||
setStatsOpen((v) => !v);
|
||||
break;
|
||||
case "Backspace":
|
||||
// HTPC-style "stop & back to the feed" — mirrors the mouse Back button (shared cascade).
|
||||
e.preventDefault();
|
||||
@@ -639,6 +650,7 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
setTracksOpen(false);
|
||||
} else if (helpOpenRef.current) setHelpOpen(false);
|
||||
else if (infoOpenRef.current) setInfoOpen(false);
|
||||
else if (statsOpenRef.current) setStatsOpen(false);
|
||||
else if (!fullscreenElement()) onClose();
|
||||
break;
|
||||
}
|
||||
@@ -1124,6 +1136,9 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<Ctrl label={t("plex.player.stats.title")} onClick={() => setStatsOpen((v) => !v)}>
|
||||
<Gauge className="w-5 h-5" />
|
||||
</Ctrl>
|
||||
<Ctrl label={t("plex.player.infoBtn")} onClick={() => setInfoOpen((v) => !v)}>
|
||||
<Info className="w-5 h-5" />
|
||||
</Ctrl>
|
||||
@@ -1140,6 +1155,20 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats-for-nerds debug overlay (toggle with "d" or the gauge button). Non-modal corner panel —
|
||||
the video keeps playing and stays interactive behind it. */}
|
||||
{statsOpen && (
|
||||
<PlexStatsOverlay
|
||||
videoRef={videoRef}
|
||||
hlsRef={hlsRef}
|
||||
playable={detail?.playable ?? ""}
|
||||
sessionStartRef={sessionStartRef}
|
||||
absRef={absRef}
|
||||
durationRef={durationRef}
|
||||
onClose={() => setStatsOpen(false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Keyboard-shortcut cheat sheet (toggle with "h" or the keyboard button). */}
|
||||
{helpOpen && (
|
||||
<div
|
||||
@@ -1180,6 +1209,7 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
[["S"], "plex.player.keys.subtitle"],
|
||||
[["F"], "plex.player.keys.fullscreen"],
|
||||
[["I"], "plex.player.keys.info"],
|
||||
[["D"], "plex.player.keys.stats"],
|
||||
[["⌫", "Esc"], "plex.player.keys.back"],
|
||||
[["H"], "plex.player.keys.help"],
|
||||
] as [string[], string][]
|
||||
|
||||
Reference in New Issue
Block a user