2016-06-25 12 views
1

Ich entwickle eine Web-Plattform mit WebRTC, um eine Peer-to-Peer-Video-Konversation für Interviews zu erstellen. Die Kommunikation wird mit ASP.NET SignalR hergestellt. Hier ist die Javascript für den Verbindungsaufbau:WebRTC Firefox: Nicht genug Argumente zu RTCPeerConnection.setLocalDescription

function initInterview() { 
       //Gets user's media 

       navigator.getUserMedia({ video: true, audio: true }, function (stream) { 
        // Display local stream to the user 
        var localMediaElem = document.querySelector('video#me'); 
        localMediaElem.volume = 0.0; 
        localMediaElem.srcObject = stream; 

        // Assign stream 
        _myMediaStream = stream; 

        showUI(true); 

        console.log("Added local media stream"); 

        // No startInterview call (waiting for interviewee to create offer) 
       }, function (event) { 
        // Something failed 
        console.log(event); 
       }); 
      }; 

      function _createConnection() { 
       console.log('Creating RTCPeerConnection...'); 

       // Create a new PeerConnection 
       var connection = new RTCPeerConnection(null); // null = no ICE servers 

       // A new ICE candidate was found 
       connection.onicecandidate = function (event) { 
        if (event.candidate) { 
         // Let's send it to our peer via SignalR 
         interview.server.send(interviewGuid, JSON.stringify({ "candidate": event.candidate })); 
        } 
       }; 

       // New remote media stream was added 
       connection.onaddstream = function (event) { 
        // Get other video element 
        var newVideoElement = document.querySelector('video#other'); 

        // Attach the stream to the Video element via adapter.js 
        newVideoElement.srcObject = event.stream; 
       }; 

       return connection; 
      } 

      // Callback that receives notifications from the SignalR server 
      interview.client.newMessage = function (data) { 
       console.log("Received message"); 
       console.log(data); 
       var message = JSON.parse(data), 
        connection = _myConnection || _createConnection(null); 

       // An SDP message contains connection and media information, and is either an 'offer' or an 'answer' 
       if (message.sdp) { 
        console.log("Received session description"); 
        connection.setRemoteDescription(new RTCSessionDescription(message.sdp), function() { 
         console.log("Description:"); 
         console.log(connection.remoteDescription); 
         if (connection.remoteDescription.type == 'offer') { 
          console.log('received offer, sending answer...'); 

          // Add our stream to the connection to be shared 
          connection.addStream(_myMediaStream); 

          // Create an SDP response 
          connection.createAnswer(function (desc) { 
           // Which becomes our local session description 
           connection.setLocalDescription(desc, function() { 
            // And send it to the originator, where it will become their RemoteDescription 
            interview.server.send(interviewGuid, JSON.stringify({ 'sdp': connection.localDescription })); 
           }); 
          }, function (error) { console.log('Error creating session description: ' + error); }); 
         } else if (connection.remoteDescription.type == 'answer') { 
          console.log('got an answer'); 
         } 
        }); 
       } else if (message.candidate) { 
        console.log('adding ice candidate...'); 
        connection.addIceCandidate(new RTCIceCandidate(message.candidate)); 
       } 

       _myConnection = connection; 
      }; 




      function startInterview() { 
       console.log("Starting interview"); 

       _myConnection = _myConnection || _createConnection(null); 

       // Add our stream to the peer connection 
       _myConnection.addStream(_myMediaStream); 

       // Create an offer to send our peer 
       _myConnection.createOffer(function (desc) { 
        // Set the generated SDP to be our local session description 
        console.log(desc); 
        _myConnection.setLocalDescription(desc, function() { 
         // And send it to our peer, where it will become their RemoteDescription 
         interview.server.send(interviewGuid, JSON.stringify({ "sdp": desc })); 
        }); 
       }, function (error) { console.log('Error creating session description: ' + error); }); 
      }; 

Der Interviewte schafft ein Angebot auf folgende Weise:

 function initInterview() { 
       //Gets user's media 

       navigator.getUserMedia({ video: true, audio: true }, function (stream) { 
        // Display local stream to the user 
        var localMediaElem = document.querySelector('video#me'); 
        localMediaElem.volume = 0.0; 
        localMediaElem.srcObject = stream; 

        // Assign stream 
        _myMediaStream = stream; 

        showUI(true); 

        console.log("Added local media stream"); 

        // Create offer for interviewer 
        startInterview(); 
       }, function (event) { 
        // Something failed 
        console.log(event); 
       }); 
      }; 

Es funktioniert perfekt, wenn wir Google Chrome verwenden, aber wenn wir Firefox verwenden wir bekommen der folgende Fehler:

Started SignalR hub b39c24ad-bd2d-42bf-829a-176bda8e3905:224:21 

Added local media stream b39c24ad-bd2d-42bf-829a-176bda8e3905:344:25 

Starting interview b39c24ad-bd2d-42bf-829a-176bda8e3905:355:21 
Creating RTCPeerConnection... b39c24ad-bd2d-42bf-829a-176bda8e3905:265:21 
onaddstream is deprecated! Use peerConnection.ontrack instead. 
RTCSessionDescription { type: "offer", sdp: "v=0 o=mozilla...THIS_IS_SDPARTA-47.…" } b39c24ad-bd2d-42bf-829a-176bda8e3905:365:25 
Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21 
"{"sdp":{"type":"offer","sdp":"v=[...]a0f1\r\n"}}" b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21 

Received session description b39c24ad-bd2d-42bf-829a-176bda8e3905:299:25 

Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21 

{"candidate":{"candidate":"candidate:2880323124 2 udp 2122260222 192.168.1.116 43234 typ host generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"audio","sdpMLineIndex":0}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21 

adding ice candidate... b39c24ad-bd2d-42bf-829a-176bda8e3905:322:25 

Received message b39c24ad-bd2d-42bf-829a-176bda8e3905:292:21 

{"candidate":{"candidate":"candidate:2880323124 1 udp 2122260223 192.168.1.116 56886 typ host generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"audio","sdpMLineIndex":0}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21 

[...] 

{"candidate":{"candidate":"candidate:3844981444 2 tcp 1518280446 192.168.1.116 9 typ host tcptype active generation 0 ufrag bg8D7wuLUvtu/QjB network-id 1","sdpMid":"video","sdpMLineIndex":1}} b39c24ad-bd2d-42bf-829a-176bda8e3905:293:21 

adding ice candidate... b39c24ad-bd2d-42bf-829a-176bda8e3905:322:25 

TypeError: Not enough arguments to RTCPeerConnection.setLocalDescription. 

Antwort

0

setLocalDescription kann fehlschlagen, und takes three arguments: die Beschreibung, ein Erfolg Rückruf, und ein Fehler CALLB ack. Sie vermissen das letztere. Chrome ist falsch.

Beachten Sie, dass diese alte API ist seit dem mit a modern one ersetzt worden, die promises stattdessen zurückgibt:

 if (message.sdp) { 
      connection.setRemoteDescription(message.sdp).then(() => { 
       if (connection.remoteDescription.type == 'answer') { 
        return; 
       } 
       connection.addStream(_myMediaStream); 
       return connection.createAnswer() 
        .then(desc => connection.setLocalDescription(desc)) 
        .then(() => interview.server.send(interviewGuid, 
         JSON.stringify({ 'sdp': connection.localDescription }))); 
      }) 
      .catch(error => console.log('Error: ' + error)); 
     } else if (message.candidate) { 
      connection.addIceCandidate(message.candidate)) 
      .catch(error => console.error(error)); 
     } 

Zugriff es in älteren Browsern adapter.js, die offizielle WebRTC polyfill.

+0

Dieser Code wird verwendet und verändert die connection.onicecandidate es funktioniert: 'interview.server.send (interviewGuid, JSON.stringify ({ "sdpMLineIndex": event.label "Kandidat": event.candidate})); ' – Zomtorg

+0

@Zomtorg Hmm, [sdpMLineIndex] (http://w3c.github.io/webrtc-pc/#dom-rtcicecandidate-sdpmlineindex) ist normalerweise eine Eigenschaft von' event.candidate' selbst und ist eine Zahl . Ich nehme an, Sie können das, was Sie möchten, für die Signalisierung stringifizieren, aber es ist ein merkwürdiger Name, den Sie verwenden können, und hat im Browser AFAIK keine besondere Bedeutung. – jib