无法通过 WebRTC 听到 MediaStream

Posted

技术标签:

【中文标题】无法通过 WebRTC 听到 MediaStream【英文标题】:Can't hear MediaStream through WebRTC 【发布时间】:2021-12-20 16:20:13 【问题描述】:

我正在尝试使用 WebRTC 和用于交换报价的 WebSocket 进行语音聊天。

首先我创建我的 RTCPeerConection

const pc = new RTCPeerConnection(configuration);

然后我将这个函数作为navigator.getUserMedia的成功回调

let localStream: MediaStream;
export function setupRtc(stream: MediaStream) 
    localStream = stream;
    // add local media stream tracks to the connection
    console.log("adding tracks");
    console.log("localStream.getTracks()", localStream.getTracks());
    localStream.getTracks().forEach((track: MediaStreamTrack) => 
        pc.addTrack(track, localStream);
        console.log("added track ", track);
    );
    console.log("done adding tracks");

    // handle pcs tracks
    let remoteStream = new MediaStream();
    pc.ontrack = function(event: RTCTrackEvent) 
        console.log("ontrack", event);
        //add audio Tag
        event.streams[0].getTracks().forEach((track) => 
            remoteStream.addTrack(track);
        );
    
    let remoteAudio = <htmlMediaElement> document.getElementById('remoteAudio');
    remoteAudio.srcObject = remoteStream;

来电者这样发送他的报价:

async function sendOffer(connectionId: string) 
    console.log("SENDING OFFER...");
    //create offer desc
    let sessionDesc: RTCSessionDescriptionInit = await pc.createOffer();
    await pc.setLocalDescription(sessionDesc);
    //send offer
    socket.send(JSON.stringify(
        
            type: "signaling_offer",
            desc: 
                sdp: sessionDesc.sdp,
                type: sessionDesc.type
            ,
            connectionId: connectionId
        
    ));
    console.log("SEND OFFER");

connectionId 是 Caller 和 Callee 都有的 id。

在 WebSocket 服务器将要约转发给被调用者后,他使用此函数回答:

function sendAnswer(connectionId: string, offer: RTCSessionDescriptionInit) 
    console.log("SENDING ANSWER...");
    pc.setRemoteDescription(new RTCSessionDescription(offer)).then(async () => 
        const answerDesc = await pc.createAnswer();
        await pc.setLocalDescription(answerDesc);
        //send answer
        socket.send(JSON.stringify(
            
                type: "signaling_answer",
                desc: 
                    sdp: answerDesc.sdp,
                    type: answerDesc.type
                ,
                connectionId: connectionId
            
        ));
        console.log("SEND ANSWER!");
    );

在 WebSocket 服务器再次转发之后,调用者使用以下方式处理答案:

function handleAnswered(connectionId: string, answer: RTCSessionDescriptionInit) 
    console.log("HANDLING ANSWER...");
    pc.setRemoteDescription(new RTCSessionDescription(answer));
    console.log("HANDLED ANSWER!");

在教程和说明中,我遵循了音频元素然后似乎播放音频我的仍然看起来像没有源的音频元素: audio element that's not playing

Caller 和 Callee 都添加了曲目和流,并收到了一些。我还附上了他们的控制台输出:

来电者: caller console

被调用者: callee console

【问题讨论】:

【参考方案1】:

结果我完全错过了一步。 Caller 和 Callee 都需要交换他们的候选冰。所以我添加了以下代码:

    pc.onicecandidate = event => 
        if(event.candidate != undefined) 
            let candidateInit: RTCIceCandidateInit = event.candidate.toJSON();
            //send candidate
            socket.send(JSON.stringify(
                
                    type: "signaling_add_candidate",
                    candidate: candidateInit,
                    connectionId: connectionId
                
            ));
            console.log("send candidate from caller", event.candidate);
        
    ;

服务器将该候选人转发给另一方。所以从调用者到被调用者并形成被调用者到调用者。 然后将另一侧的转发候选人添加到 PeerConnection 我添加了以下代码:

function handleNewCandidate(connectionId: string, candidateInit: RTCIceCandidateInit) 
    pc.addIceCandidate(new RTCIceCandidate(candidateInit));

【讨论】:

以上是关于无法通过 WebRTC 听到 MediaStream的主要内容,如果未能解决你的问题,请参考以下文章

AVAudioPlayer 在进行 WebRTC 音频通话时以非常低的音量播放声音

WebRTC Chrome 麦克风无法正常工作

如何处理C++编译webrtc无法成功获取sdp的问题?

iOS 上的 webRTC:无法发送 SDP 应答,RTCPeerConnection.setRemoteDescription() 失败

在无法访问 Internet 的本地网络中使用 WebRTC 运行应用程序

为何一直推荐WebRTC