0

我正在尝试启动从本机客户端到 Web 浏览器的桌面屏幕流式传输。当我开始连接时,sdp 交换正常并且媒体流按它应该开始。但是数据通道会立即触发“关闭”事件。据我了解,数据通道应该在 sdp 交换之前创建,并且我将协商设置为 false。所以它应该自动通知其他对等方这个通道并启动数据通道。但这不是我的情况。

我尝试了许多不同的方法,例如使用选项设置数据通道或使用或不使用选项的对等连接。

我错过了什么吗?

以下是来自 Web 浏览器的启动器代码。

var pcConstraints = {};

var servers = {
//iceTransportPolicy: 'relay', // force turn
iceServers:
         [
             { url: 'stun:stun.l.google.com:19302' },
             { url: 'stun:stun.stunprotocol.org:3478' },
             { url: 'stun:stun.anyfirewall.com:3478' }
         ]
  };

   var offerOptions = {
   offerToReceiveAudio: 0,
   offerToReceiveVideo: 1,
   trickle: false
  };

  function startStream() {
   console.log("startStream...");

remotestream = new RTCPeerConnection(servers, pcConstraints);

if (localstream) {
    remotestream.addStream(localstream);
}


// optional data channel
dataChannel = remotestream.createDataChannel('testchannel', {});
setDataChannel(dataChannel);

remotestream.onaddstream = function (e) {
    try {
        console.log("remote media connection success!");

        var vid2 = document.getElementById('vid2');
        vid2.srcObject = e.stream;
        vid2.onloadedmetadata = function (e) {
            vid2.play();
        };




        var t = setInterval(function () {
            if (!remotestream) {
                clearInterval(t);
            }
            else {
                Promise.all([
                    remotestream.getStats(null).then(function (o) {

                        var rcv = null;
                        var snd = null;

                        o.forEach(function (s) {
                            if ((s.type == "inbound-rtp" && s.mediaType == "video" && !s.isRemote) ||
                               (s.type == "ssrc" && s.mediaType == "video" && s.id.indexOf("recv") >= 0))
                            {
                                rcv = s;

                            }
                            else if((s.type == "outbound-rtp" && s.mediaType == "video" && !s.isRemote) ||
                                    (s.type == "ssrc" && s.mediaType == "video" && s.id.indexOf("send") >= 0))
                            {
                                snd = s;
                            }
                        });

                        return dumpStat(rcv, snd);
                    })

                ]).then(function (s) {
                    statsdiv.innerHTML = "<small>" + s + "</small>";
                });
            }
        }, 100);

    } catch (ex) {
        console.log("Failed to connect to remote media!", ex);
        socket.close();
    }
};
remotestream.onicecandidate = function (event) {
    if (event.candidate) {

        var ice = parseIce(event.candidate.candidate);
        if (ice && ice.component_id == 1           // skip RTCP
                //&& ice.type == 'relay'           // force turn
                && ice.localIP.indexOf(":") < 0) { // skip IP6

            console.log('onicecandidate[local]: ' + event.candidate.candidate);
            var obj = JSON.stringify({
                "command": "onicecandidate",
                "candidate": event.candidate
            });
            send(obj);
            localIce.push(ice);
        }
        else {
            console.log('onicecandidate[local skip]: ' + event.candidate.candidate);
        }
    }
    else {
        console.log('onicecandidate: complete.')

        if (remoteAnswer) {

            // fill empty pairs using last remote ice
            //for (var i = 0, lenl = localIce.length; i < lenl; i++) {
            //    if (i >= remoteIce.length) {
            //        var c = remoteIce[remoteIce.length - 1];

            //        var ice = parseIce(c.candidate);
            //        ice.foundation += i;
            //        c.candidate = stringifyIce(ice);

            //        remotestream.addIceCandidate(c);
            //    }
            //}
        }
    }
};
remotestream.createOffer(function (desc) {
    console.log('createOffer: ' + desc.sdp);

    remotestream.setLocalDescription(desc, function () {
        var obj = JSON.stringify({
            "command": "offer",
            "desc": desc
        });
        send(obj);
    },
    function (errorInformation) {
        console.log('setLocalDescription error: ' + errorInformation);


    });
},
    function (error) {
        alert(error);

},
offerOptions);
 }


function setDataChannel(dc) {

dc.onerror = function (error) {
    alert("DataChannel Error:", error);
  };
dc.onmessage = function (event) {
    alert("DataChannel Message:", event.data);
  };
dc.onopen = function () {
    dataChannel.send("Hello World!");
};
dc.onclose = function (error) {

    alert("DataChannel is Closed");
    alert(error.data)
};
 }
4

0 回答 0