我们展示的是一个使用html img标签的mjpeg视频流。为此,我们有多种实现,具体取决于视频流的提供商。
流媒体视频运行良好。切换流媒体也可以。但切换到不同类型的流媒体就不行了。此时,当前流媒体不会关闭,第二个流媒体会打开。经过几次这样的切换后,无法再发出http请求,浏览器选项卡会冻结。
我可以用下面的代码重现它:
interface StreamProps {
mjpegUrl: string;
}
export const StreamType1: React.FC<StreamProps> = ({ mjpegUrl }) => {
return <img src={mjpegUrl} />;
};
export const StreamType2: React.FC<StreamProps> = ({ mjpegUrl }) => {
return <img src={mjpegUrl} />;
};
interface Props {
}
export const VideoStream: React.FC<Props> = () => {
const [toggle, setToggle] = useState(true);
return (
<div>
<button onClick={() => setToggle((current) => !current)}>
Switch!
</button>
{toggle
? <StreamType1 mjpegUrl="http://localhost/stream1" />
: <StreamType2 mjpegUrl="http://localhost/stream2" />}
</div>
);
};
需要注意的一点是,如果我对这两者使用相同的流类型,这个问题就不会发生。类似于更新mjpegUrl
属性。
{toggle
? <StreamType1 mjpegUrl="http://localhost/stream1" />
: <StreamType1 mjpegUrl="http://localhost/stream2" />}
为什么会发生这种情况?如何解决?
2条答案
按热度按时间kqlmhetl1#
我想我知道了。
更新
img
的src
属性将停止当前请求并发送一个新请求。这就是为什么更新同一个组件没有问题的原因。当使用同一类型的不同组件时,React足够智能,可以重用现有组件,这意味着
src
属性会被更新,请求也会停止。当使用不同类型的不同组件时,React无法重用该组件。因此,
img
的src
属性不会更新,当前请求也不会停止。要解决此问题,可以使用两步更新。首先更新现有组件并设置一个空字符串。然后更新为新组件和值。困难在于,当您有一个很深的组件树,其中一个组件被替换或删除时,您仍然有一个打开的连接。
最后,我的解决方案基于https://stackoverflow.com/a/52328525/9271844。
j8yoct9x2#
stop()将结束所有当前的流。将它放在useEffect钩子中,以便在离开页面时停止流。