首页 > 解决方案 > 如何通过 Web 套接字发送实时视频的图像并将其存储在 React 状态变量中?

问题描述

我正在使用Reactsocket.io构建一个聊天室,人们可以在其中直播视频。

我有一个带有直播流的视频播放器,我想通过 socket.io 传递。当流从客户端传递到服务器并返回到客户端时,我想将它作为数组中的一个项目存储在状态变量中,这样我就可以向用户显示所有实时流。

现在我只是想在 a 上绘制流的图像<canvas>并发出它。

我通过当前用户流定义每个流,使用他们的user.username.

流.js

function Stream(props) {

    const refVideo = useRef();
    const refCanvas = useRef();

    const [streams, setStreams] = useState([]);

    function startStream() {
        navigator.mediaDevices.getUserMedia({
            video: true,
            audio: true
        }).then((stream) => {
            // set source of video to stream
            refVideo.current.srcObject = stream;

            // define canvas context
            const context = refCanvas.current.getContext('2d');

            // emit canvas as data url every 100 milliseconds
            const interval = setInterval(() => {
                // draw image
                context.drawImage(refVideo.current, 0, 0, context.width, context.height);

                // define stream by username
                const streamObj = {
                    image: refCanvas.current.toDataURL('image/jpeg'),
                    username: props.user.username,
                };

                // send stream to server
                socket.emit('stream', streamObj);
            }, 100);
        });
    }

    useEffect(() => {
        // when stream is received from server
        socket.on('stream', function(data) {

            // find stream by username
            const foundStream = streams.find((stream) => {
                return stream.username === data.username;
            });

            // ONLY if stream was not found, add it to state
            if(!foundStream) {
                setStreams((streams) => [...streams, data]);
            }
        });
    }, []);

    return (
        <video ref={refVideo} />
        <canvas ref={refCanvas} />
    );
}

服务器.js

socket.on('stream', function(data) {
  // send stream back to room
  io.to(room).emit('stream', data);
});

我的流显示在 中,<video>并且对象通过套接字发送到服务器并返回到客户端,但由于某种原因,我的流每次streams都被添加到我的状态数组中(每 100 毫秒间隔)。

我使用 来检查流是否已经在数组中foundStream,所以我不确定为什么会这样。我错过了什么吗?

标签: reactjssocket.iogetusermediareact-state-management

解决方案


这是正常的。发送给所有人,包括发送者,你应该使用 broadcast.emit 发送给除了发送者本身之外的所有人。


推荐阅读