Stream WebRTC-如何在RTPeerConnection内的getUserMedia和getDisplayMedia曲目之间切换

Stream WebRTC-如何在RTPeerConnection内的getUserMedia和getDisplayMedia曲目之间切换,stream,webrtc,getusermedia,Stream,Webrtc,Getusermedia,我正在尝试开发一个应用程序,用户可以通过WebRTC技术互相视频通话并共享屏幕。我已经成功地使用了视频通话或屏幕共享应用程序,现在我正在尝试使它能够在同一RTPeerConnection内的通话过程中在getUserMedia和getDisplayMedia之间切换,但它不起作用 这就是我认为它可以工作的方式: function onLogin(success) { var configuration = { offerToReceiv

我正在尝试开发一个应用程序,用户可以通过WebRTC技术互相视频通话并共享屏幕。我已经成功地使用了视频通话或屏幕共享应用程序,现在我正在尝试使它能够在同一RTPeerConnection内的通话过程中在getUserMedia和getDisplayMedia之间切换,但它不起作用

这就是我认为它可以工作的方式:

            function onLogin(success) { 

                var configuration = { offerToReceiveAudio: true, offerToReceiveVideo: true, "iceServers" : [ { "url" : "stun:stun.1.google.com:19302" } ] }; 

                myConnection = window.RTCPeerConnection ? new RTCPeerConnection(configuration, { optional: [] }) : new RTCPeerConnection(configuration, { optional: [] }); 

                myConnection.onicecandidate = function (event) { 
                    console.log("onicecandidate");
                    if (event.candidate) send({ type: "candidate", candidate: event.candidate });
                };
                
                myConnection.ontrack=function(e){
                    try{remoteVideo.src = window.webkitURL?window.webkitURL.createObjectURL(e.streams[0]):window.URL.createObjectURL(e.streams[0])}
                    catch(err){remoteVideo.srcObject=e.streams[0]}
                }
                
                myConnection.ondatachannel=openDataChannel
                openDataChannel();
                
                startAVStream();
                //startSStream()
            };

            function startAVStream(enable){
                if(sStream)sStream.getTracks().forEach( function (track) {
                            try{myConnection.removeTrack( track, sStream );}
                            catch(e){}
                        } );
                        
                navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(s => {
                    if(!avStream){
                        avStream = s;
                        avStream.getTracks().forEach( function (track) {
                            myConnection.addTrack( track, avStream );
                        } );
                    }
                }, function (error) { console.log(error); }); 
            }
            
            function startSStream(enable){
                if(avStream)avStream.getTracks().forEach( function (track) {
                            try{myConnection.removeTrack( track, avStream );}
                            catch(e){}
                        } );
                        
                navigator.mediaDevices.getDisplayMedia({ video: true }).then(s => {
                    if(!sStream){
                        sStream = s;
                        sStream.getTracks().forEach( function (track) {
                            myConnection.addTrack( track, sStream );
                        } );
                    }
                }, function (error) { console.log(error); }); 
            }
有谁能告诉我如何在同一个RTPeerConnection内的曲目之间切换,或者我应该创建两个单独的RTPeerConnection-一个用于视频/音频流,另一个用于屏幕共享


感谢您的帮助!谢谢

您可以使用
RTCRtpSender.replaceTrack
拼接屏幕捕获曲目。这不需要重新协商,因此延迟非常低

let newstream = navigator.mediaDevices.getDisplayMedia({});
let newtrack = newstream.getTracks()[1];
if(newtrack.kind !== 'video')
    throw new Error('Eek!?');
pc.getSenders().forEach(async s => {
    if(s.track && s.track.kind === 'video')
        await s.replaceTrack(newtrack);
});

s.track
不为
null
的测试处理以前调用
replaceTrack(…,null)

的情况,您可以使用
RTCRtpSender.replaceTrack
拼接屏幕捕获轨迹。这不需要重新协商,因此延迟非常低

let newstream = navigator.mediaDevices.getDisplayMedia({});
let newtrack = newstream.getTracks()[1];
if(newtrack.kind !== 'video')
    throw new Error('Eek!?');
pc.getSenders().forEach(async s => {
    if(s.track && s.track.kind === 'video')
        await s.replaceTrack(newtrack);
});

s.track
不为
null
的测试处理以前调用
replaceTrack(…,null)
的情况!它起作用了!谢谢!但现在我有另一个问题——当我只使用音频流时,我该怎么做?因为当我尝试添加getDisplayMedia stream时,它会给我一个错误。只需将出现的
视频
替换为
音频
。我不确定我是否理解你的意思:(哪一个流是纯音频流?如果你想替换音频曲目,请按上述操作,但使用“音频”而不是“视频”。如果你想将视频曲目添加到纯音频流,你需要在pc上调用
addTrack
,这需要重新协商。是的!它可以工作!非常感谢!但现在我有另一个问题-ejat do当我只使用音频流时,我会这样做?因为当我尝试添加getDisplayMedia stream时,它会给我一个错误。只需将两个出现的
视频
替换为
音频
。我不确定我是否理解你的意思:(哪一个流是纯音频流?如果要替换音频曲目,请执行与上面相同的操作,但使用“音频”而不是“视频”。如果要将视频曲目添加到纯音频流,您需要在pc上调用
addTrack
,这需要重新协商。