首页 > 解决方案 > WebRTC 使用 React:为什么远程视频没有播放?

问题描述

我有两种服务,一种是发送视频服务,另一种是接收视频服务。服务器只转发信息,将信息转发给对方。接收视频的服务有时可以接收视频,但大部分不能。不知道问题出在哪里,是发送视频的服务还是接收视频的服务。

呼叫者

import { useEffect, useRef, useState, useCallback } from "react";
import io from "socket.io-client";

function createPeerConnection() {
    const myPeerConnection = new RTCPeerConnection();
    return myPeerConnection;
}

async function setLocalStream(myPeerConnection, target) {
    console.log("setLocalStream");
    const webcamStream = await navigator.mediaDevices.getUserMedia({
        audio: true,
        video: true,
    });
    target.srcObject = webcamStream;
    webcamStream
        .getTracks()
        .forEach((track) =>
            myPeerConnection.addTransceiver(track, { streams: [webcamStream] })
        );
}

const App = () => {
    const ref = useRef();
    const [socket] = useState(io());
    useEffect(() => {
        socket.emit("init", "hello");
        socket.on("init", (res) => {
            console.log(res);
        });
    }, []);
    const handleNegotiationNeededEvent = useCallback(
        (myPeerConnection) => async () => {
            try {
                const offer = await myPeerConnection.createOffer();
                await myPeerConnection.setLocalDescription(offer);
                console.log(
                    "send video-offer",
                    myPeerConnection.localDescription
                );
                socket.emit("video-offer", myPeerConnection.localDescription);
            } catch (error) {
                console.error(error);
            }
        },
        [socket]
    );
    const handleICECandidateEvent = useCallback(
        (event) => {
            if (event.candidate) {
                console.log("send new-ice-candidate", event.candidate);
                socket.emit("new-ice-candidate", event.candidate);
            }
        },
        [socket]
    );

    useEffect(() => {
        const myPeerConnection = createPeerConnection();
        myPeerConnection.onicecandidate = handleICECandidateEvent;
        myPeerConnection.onnegotiationneeded = handleNegotiationNeededEvent(
            myPeerConnection
        );
        setLocalStream(myPeerConnection, ref.current);
        socket.on("video-answer", async (sdp) => {
            console.log("received video-answer", sdp);
            const desc = new RTCSessionDescription(sdp);
            try {
                await myPeerConnection.setRemoteDescription(desc);
            } catch (error) {
                console.error(error);
            }
        });
        socket.on("new-ice-candidate", async (c) => {
            console.log("received new-ice-candidate", c);
            const candidate = new RTCIceCandidate(c);
            try {
                await myPeerConnection.addIceCandidate(candidate);
            } catch (error) {
                console.error(error);
            }
        });
    }, []);
    return (
        <>
            <video style={{ width: "10px" }} ref={ref} autoPlay muted />
        </>
    );
};

export default App;

被调用者

import { useEffect, useRef, useState, useCallback } from "react";
import io from "socket.io-client";

function createPeerConnection() {
    const myPeerConnection = new RTCPeerConnection();
    return myPeerConnection;
}

const App = () => {
    const ref = useRef();
    const [socket] = useState(io());
    useEffect(() => {
        socket.emit("init", "hello");
        socket.on("init", (res) => {
            console.log(res);
        });
    }, []);

    const handleICECandidateEvent = useCallback(
        (event) => {
            if (event.candidate) {
                console.log("send new-ice-candidate", event.candidate);
                socket.emit("new-ice-candidate", event.candidate);
            }
        },
        [socket]
    );

    const handleTrackEvent = useCallback((event) => {
        ref.current.srcObject = event.streams[0];
    }, []);

    useEffect(() => {
        const myPeerConnection = createPeerConnection();
        myPeerConnection.onicecandidate = handleICECandidateEvent;
        myPeerConnection.ontrack = handleTrackEvent;
        socket.on("video-offer", async (sdp) => {
            console.log("received offer", sdp);
            const desc = new RTCSessionDescription(sdp);
            await myPeerConnection.setRemoteDescription(desc);
            await myPeerConnection.setLocalDescription(
                await myPeerConnection.createAnswer()
            );
            console.log("send answer", myPeerConnection.localDescription);
            socket.emit("video-answer", myPeerConnection.localDescription);
        });
        socket.on("new-ice-candidate", async (c) => {
            console.log("received new-ice-candidate", c);
            const candidate = new RTCIceCandidate(c);
            try {
                await myPeerConnection.addIceCandidate(candidate);
            } catch (error) {
                console.error(error);
            }
        });
    }, []);
    return (
        <>
            <video style={{ width: "20px" }} ref={ref} autoPlay />
        </>
    );
};

export default App;

标签: reactjswebrtc

解决方案


推荐阅读