我正在开发一个实时媒体播放器 React 应用程序,它可以在浏览器(特别是 Firefox)中交替显示全屏和元素。
我特别关心的是记忆。应用程序永远不会在窗口中重新加载,并且每次播放要随后续加载进行流式传输的视频后,我都会看到内存配置文件的大小会跳跃,并且永远不会回落到基线。
您可以通过打开开发人员工具 (f12) 并打开“内存”选项卡、拍摄快照并切换到聚合视图来观察“源”和“视频”内存组。
我已尝试遵循此stack post中的解决方案,但无济于事。
但是要理解的主要两个组成部分是
MediaPlayer
和 VideoPlayer
媒体播放器:
import { useEffect, useState } from "react";
import "./MediaStyles.css";
import ImagePlayer from "./ImagePlayer";
import VideoPlayer from "./VideoPlayer";
const MediaPlayer = () => {
const [mediaSwap, setMediaSwap] = useState<boolean>(false);
useEffect(() => {
const interval = setInterval(() => {
setMediaSwap((swap: boolean) => !swap);
}, 5000);
return () => clearInterval(interval);
}, [mediaSwap]);
return (
<>
<div className="fullscreen-container">
<div className="media-container">
{mediaSwap ? <VideoPlayer /> : <ImagePlayer />}
</div>
</div>
</>
);
};
export default MediaPlayer;
视频播放器:
import { useEffect, useRef, useState } from "react";
const VideoPlayer = () => {
const videoRef = useRef<HTMLVideoElement | null>(null);
useEffect(() => {
if (videoRef.current) {
console.log("current mounted removal");
videoRef.current.pause();
videoRef.current.removeAttribute("src");
videoRef.current.load();
}
return () => {
if (videoRef.current) {
console.log("current unmounted removal");
videoRef.current.pause();
videoRef.current.removeAttribute("src");
videoRef.current.load();
}
};
}, [videoRef.current]);
return (
<div>
<video id="spotlight video" ref={videoRef} autoPlay muted playsInline>
<source src="https://ibcdigitalsignageblob.blob.core.windows.net/fe3c4826-4e72-4cd4-a938-382d67a8badf/assets/2023-09-19_02_10_55_4kvid.mp4" />
</video>
</div>
);
};
export default VideoPlayer;
当 useEffect 清理函数运行时,引用值
videoRef.current
可能会发生变化。将 videoRef.current
复制到 useEffect 内的变量,并在清理函数中使用该变量。
src/VideoPlayer.tsx
const VideoPlayer = () => {
const videoRef = useRef<HTMLVideoElement | null>(null);
useEffect(() => {
const videoRefCurrent = videoRef.current; // <--- Here
if (videoRefCurrent) {
console.log("current mounted removal");
videoRefCurrent.pause();
videoRefCurrent.removeAttribute("src");
videoRefCurrent.load();
}
return () => {
if (videoRefCurrent) {
console.log("current unmounted removal");
videoRefCurrent.pause();
videoRefCurrent.removeAttribute("src");
videoRefCurrent.load();
}
};
}, []);
return (
<div>
<video id="spotlight video" ref={videoRef} autoPlay muted playsInline>
<source src="https://ibcdigitalsignageblob.blob.core.windows.net/fe3c4826-4e72-4cd4-a938-382d67a8badf/assets/2023-09-19_02_10_55_4kvid.mp4" />
</video>
</div>
);
};