node.js - 使用套接字IO的WebRTC RTCMultiConnection

标签 node.js sockets socket.io webrtc rtcmulticonnection

我使用io套接字开始了WebRTC的研发。我遵循了这个tutorial。从GitHub下载了此project,按照以下步骤安装了io套接字install socket io

现在,在运行index.html之后,单击“打开”或“加入广播”按钮,该按钮将被禁用,但什么也没有发生,并且控制台中也没有错误

WebRTC

index.html代码:

<input type="text" id="broadcast-id" placeholder="broadcast-id" value="room-xyz">
<select id="broadcast-options">
    <option>Audio+Video</option>
    <option title="Works only in Firefox.">Audio+Screen</option>
    <option>Audio</option>
    <option>Video</option>
    <option title="Screen capturing requries HTTPs. Please run this demo on HTTPs to make sure it can capture your screens.">Screen</option>
</select>
<button id="open-or-join">Open or Join Broadcast</button>
<hr>
<div id="videos-container"></div>

<script src="http://10.0.0.***:3000/socket.io/socket.io.js"></script>
<script src="https://cdn.webrtc-experiment.com/RTCMultiConnection.js"></script>
<script>
    var socket = io.connect('http://10.0.0.***');

    // using single socket for RTCMultiConnection signaling
    var onMessageCallbacks = {};
    socket.on('message', function(data) {
        if (data.sender == connection.userid) return;
            if (onMessageCallbacks[data.channel]) {
                onMessageCallbacks[data.channel](data.message);
            };
        });

    // initializing RTCMultiConnection constructor.
    function initRTCMultiConnection(userid) {
        var connection = new RTCMultiConnection();
        connection.body = document.getElementById('videos-container');
        connection.channel = connection.sessionid = connection.userid = userid || connection.userid;
        connection.sdpConstraints.mandatory = {
            OfferToReceiveAudio: false,
            OfferToReceiveVideo: true
        };
        // using socket.io for signaling
        connection.openSignalingChannel = function(config) {
            var channel = config.channel || this.channel;
            onMessageCallbacks[channel] = config.onmessage;
            if (config.onopen) setTimeout(config.onopen, 1000);
            return {
                send: function(message) {
                    socket.emit('message', {
                        sender: connection.userid,
                        channel: channel,
                        message: message
                    });
                },
                channel: channel
           };
      };
      connection.onMediaError = function(error) {
          alert(JSON.stringify(error));
      };
      return connection;
 }

 // this RTCMultiConnection object is used to connect with existing users
 var connection = initRTCMultiConnection();

 connection.getExternalIceServers = false;

 connection.onstream = function(event) {
     connection.body.appendChild(event.mediaElement);

     if (connection.isInitiator == false && !connection.broadcastingConnection) {
          // "connection.broadcastingConnection" global-level object is used
          // instead of using a closure object, i.e. "privateConnection"
          // because sometimes out of browser-specific bugs, browser 
          // can emit "onaddstream" event even if remote user didn't attach any stream.
          // such bugs happen often in chrome.
          // "connection.broadcastingConnection" prevents multiple initializations.

          // if current user is broadcast viewer
          // he should create a separate RTCMultiConnection object as well.
          // because node.js server can allot him other viewers for
          // remote-stream-broadcasting.
          connection.broadcastingConnection = initRTCMultiConnection(connection.userid);

          // to fix unexpected chrome/firefox bugs out of sendrecv/sendonly/etc. issues.
          connection.broadcastingConnection.onstream = function() {};

          connection.broadcastingConnection.session = connection.session;
          connection.broadcastingConnection.attachStreams.push(event.stream); // broadcast remote stream
          connection.broadcastingConnection.dontCaptureUserMedia = true;

          // forwarder should always use this!
          connection.broadcastingConnection.sdpConstraints.mandatory = {
               OfferToReceiveVideo: false,
               OfferToReceiveAudio: false
          };

          connection.broadcastingConnection.open({
               dontTransmit: true
          });
      }
 };

 // ask node.js server to look for a broadcast
 // if broadcast is available, simply join it. i.e. "join-broadcaster" event should be emitted.    
 // if broadcast is absent, simply create it. i.e. "start-broadcasting" event should be fired.
 document.getElementById('open-or-join').onclick = function() {
       var broadcastid = document.getElementById('broadcast-id').value;
       if (broadcastid.replace(/^\s+|\s+$/g, '').length <= 0) {
            alert('Please enter broadcast-id');
            document.getElementById('broadcast-id').focus();
            return;
       }

       this.disabled = true;

       connection.session = {
            video: document.getElementById('broadcast-options').value.indexOf('Video') !== -1,
            screen: document.getElementById('broadcast-options').value.indexOf('Screen') !== -1,
            audio: document.getElementById('broadcast-options').value.indexOf('Audio') !== -1,
            oneway: true
      };

      socket.emit('join-broadcast', {
          broadcastid: broadcastid,
          userid: connection.userid,
          typeOfStreams: connection.session
      });
};

// this event is emitted when a broadcast is already created.
socket.on('join-broadcaster', function(broadcaster, typeOfStreams) {
    connection.session = typeOfStreams;
    connection.channel = connection.sessionid = broadcaster.userid;

    connection.sdpConstraints.mandatory = {
        OfferToReceiveVideo: !!connection.session.video,
        OfferToReceiveAudio: !!connection.session.audio
    };

    connection.join({
        sessionid: broadcaster.userid,
        userid: broadcaster.userid,
        extra: {},
        session: connection.session
    });
});

// this event is emitted when a broadcast is absent.
socket.on('start-broadcasting', function(typeOfStreams) {
     // host i.e. sender should always use this!
     connection.sdpConstraints.mandatory = {
          OfferToReceiveVideo: false,
          OfferToReceiveAudio: false
     };
     connection.session = typeOfStreams;
     connection.open({
         dontTransmit: true
     });

     if (connection.broadcastingConnection) {
         // if new person is given the initiation/host/moderation control
         connection.broadcastingConnection.close();
         connection.broadcastingConnection = null;
     }
});

window.onbeforeunload = function() {
     // Firefox is weird!
     document.getElementById('open-or-join').disabled = false;
};
</script>

我是新手,这可能是什么问题?

最佳答案

我自己前一段时间也陷入同样的​​境地。我想实现某种与Muaz在其git repo中所做的算法类似的算法,但是在许多地方,我发现Muaz的此repo现在不再维护,已经过时了,我不得不从头开始。因此,我只是遵循Shane Tully的webRTC示例,并开始在其之上编写我的算法。
与muaz的算法一样,流是通过客户端中继的,但是对算法进行了修改以形成洪流链。实现的算法是here(git repo)-
and the algorithm is as shown in figure

高带宽和低带宽客户端被过滤,以便只有高带宽客户端充当流转发器。它在LAN和Internet上都很好用,还有很大的改进空间。

关于node.js - 使用套接字IO的WebRTC RTCMultiConnection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62042179/

相关文章:

javascript - 当使用socket.io发送JavaScript对象时,它是将其编码为JSON还是以二进制格式发送?

node.js - 在快速回复中使用特殊字符(元音变音)

c - fork 后选择阅读

javascript - 从 Node JS 中的数组获取条目

c++ - 如何使用 GoogleMock 设置模拟服务器

java - TCP/IP 通过 WLAN,权限被拒绝

node.js - socket.io中的默认pingTimeout和pingInterval是什么

node.js - 套接字 : disconnect client by socket id?

mysql - 如何在 Node.js 中使用 Sequelize for MySql 编写 mongoose 的对象 id 引用

mysql - Node.js MySQL NPM 错误 "Cannot switch to old mode now."