0

我正在尝试遵循 RTCPeerConnection API 上的教程,该教程可以在浏览器之间共享声音、图像和数据。

这是有效的代码:

function call() {
  callButton.disabled = true;
  hangupButton.disabled = false;
  trace("Starting call");

  if (localStream.getVideoTracks().length > 0) {
    trace('Using video device: ' + localStream.getVideoTracks()[0].label);
  }
  if (localStream.getAudioTracks().length > 0) {
    trace('Using audio device: ' + localStream.getAudioTracks()[0].label);
  } 

  var servers = null;

  localPeerConnection = new mozRTCPeerConnection(servers);
  console.log(localPeerConnection);
  trace("Created local peer connection object localPeerConnection");
  localPeerConnection.onicecandidate = gotLocalIceCandidate;

  remotePeerConnection = new mozRTCPeerConnection(servers);
  trace("Created remote peer connection object remotePeerConnection");
  remotePeerConnection.onicecandidate = gotRemoteIceCandidate;
  remotePeerConnection.onaddstream = gotRemoteStream;

  localPeerConnection.addStream(localStream);
  trace("Added localStream to localPeerConnection");
  localPeerConnection.createOffer(gotLocalDescription);
}

这是我的代码不起作用:

Visio.prototype.call = function(visio){
    callButton.disabled = true;
    hangupButton.disabled = false;
    console.log("Starting call...");
    if (visio.localStream.getVideoTracks().length > 0) {
        visio.trace('Using video device: ' + visio.localStream.getVideoTracks()[0].label);
    }
    if (visio.localStream.getAudioTracks().length > 0) {
        visio.trace('Using audio device: ' + visio.localStream.getAudioTracks()[0].label);
    }

    var servers = null;
    visio.localPeerConnection = new RTCPeerConnection(servers);
    console.log(visio.localPeerConnection );
    console.log("Created local peer connection object localPeerConnection");
    visio.localPeerConnection.onicecandidate = visio.gotLocalIceCandidate;

    visio.remotePeerConnection = new RTCPeerConnection(servers);
    console.log("Created remote peer connection object remotePeerConnection");
    visio.remotePeerConnection.onicecandidate = visio.gotRemoteIceCandidate;
    visio.remotePeerConnection.onaddstream = visio.gotRemoteStream;

    visio.localPeerConnection.addStream(visio.localStream);
    console.log("Added localStream to localPeerConnection");
    visio.localPeerConnection.createOffer(visio.gotLocalDescription);
};

我对call方法的调用:

callButton.onclick = function(){that.call(that);};

正如标题中所说,事件:onicecandidate 和 onaddstream 从未触发。我不知道为什么。

任何想法?


好的,我修改了我的功能。但它不再起作用了:(

这是完整的代码:

Visio.js

if(mozRTCPeerConnection){
    RTCPeerConnection = mozRTCPeerConnection;
}else if(webkitRTCPeerConnection){
    RTCPeerConnection = webkitRTCPeerConnection;
} else if(oRTCPeerConnection) {
    RTCPeerConnection = oRTCPeerConnection;
} else {
    alert("Votre navigateur ne supporte pas l'API RTCPeerConnection");
}
$(document).ready(function(){
    new Visio(); 
});

function Visio() {
    this.localStream, this.localPeerConnection, this.remotePeerConnection;
    this.cam = new Cam();
    //var localVideo = document.getElementById("localVideo");
    var remoteVideo = document.getElementById("remoteVideo");
    var startButton = document.getElementById("startButton");
    var callButton = document.getElementById("callButton");
    var hangupButton = document.getElementById("hangupButton");
    startButton.disabled = false;
    callButton.disabled = true;
    hangupButton.disabled = true;
    var that = this;
    startButton.onclick = function(){that.start();};
    callButton.onclick = function () { that.startCall(); };
    hangupButton.onclick = function(){that.hangup();};


};

Visio.prototype.trace = function(text) {
    console.log((performance.now() / 1000).toFixed(3) + ": " + text);
};


Visio.prototype.start = function(){
    startButton.disabled = true;
    this.cam.start();
    //Waiting for stream.
    var that = this;
    var id = setInterval(function(){
        console.log("Getting Stream...");
        that.localStream = that.cam.stream;
        if(that.localStream !== null){
            console.log("Stream Ok!");
            callButton.disabled = false;
            clearInterval(id);
        }
    },500);
};

Visio.prototype.startCall = function () {
    callButton.disabled = true;
    hangupButton.disabled = false;
    console.log("Starting call...");
    if (this.localStream.getVideoTracks().length > 0) {
        this.trace('Using video device: ' + this.localStream.getVideoTracks()[0].label);
    }
    if (this.localStream.getAudioTracks().length > 0) {
        this.trace('Using audio device: ' + this.localStream.getAudioTracks()[0].label);
    }

    var servers = null;
    this.localPeerConnection = new RTCPeerConnection(servers);
    console.log("Created local peer connection object localPeerConnection");
    this.localPeerConnection.onicecandidate = this.gotLocalIceCandidate;

    this.remotePeerConnection = new RTCPeerConnection(servers);
    console.log("Created remote peer connection object remotePeerConnection");
    this.remotePeerConnection.onicecandidate = this.gotRemoteIceCandidate;
    this.remotePeerConnection.onaddstream = this.gotRemoteStream;

    this.localPeerConnection.addStream(this.localStream);
    console.log("Added localStream to localPeerConnection");
    this.localPeerConnection.createOffer(this.gotLocalDescription);
};

Visio.prototype.gotLocalDescription = function(description){
    this.localPeerConnection.setLocalDescription(description);
    console.log("Offer from localPeerConnection: \n" + description.sdp);
    this.remotePeerConnection.setRemoteDescription(description);

    this.remotePeerConnection.createAnswer(this.gotRemoteDescription);
}; 

Visio.prototype.gotRemoteDescription = function(description){
  this.remotePeerConnection.setLocalDescription(description);
  console.log("Answer from remotePeerConnection: \n" + description.sdp);
  this.localPeerConnection.setRemoteDescription(description);
};

Visio.prototype.gotRemoteStream = function(event){
  remoteVideo.src = URL.createObjectURL(event.stream);
  trace("Received remote stream");
};

Visio.prototype.gotLocalIceCandidate = function(event){
  if (event.candidate) {
    remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    trace("Local ICE candidate: \n" + event.candidate.candidate);
  }
};

Visio.prototype.gotRemoteIceCandidate = function(event){
  if (event.candidate) {
    localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    trace("Remote ICE candidate: \n " + event.candidate.candidate);
  }
};

Visio.prototype.hangup = function() {
  console.log("Ending call");
  this.localPeerConnection.close();
  this.remotePeerConnection.close();
  this.localPeerConnection = null;
  this.remotePeerConnection = null;
  hangupButton.disabled = true;
  callButton.disabled = false;
};

和 cam.js

/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
function Cam(){
    this.video = null;
    this.stream = null;
    navigator.getUserMedia ||
            (navigator.getUserMedia = navigator.mozGetUserMedia ||
            navigator.webkitGetUserMedia || navigator.msGetUserMedia);
    if (!navigator.getUserMedia) {
        alert('getUserMedia is not supported in this browser.');
    }
};

Cam.prototype.start = function(){
    var that = this;
    navigator.getUserMedia({
        video: true, 
        audio: true
    }, function(stream){that.onSuccess(stream);}, that.onError);
};

Cam.prototype.stop = function(){
    this.stopVideo();
    this.stopSound();
};

Cam.prototype.startSound = function(){

};

Cam.prototype.stopSound = function(){

};

Cam.prototype.startVideo = function(){

};

Cam.prototype.stopVideo = function(){

};

Cam.prototype.onSuccess = function(stream){
    var source = document.getElementById('localVideo');
    var videoSource = null;
    this.stream = stream;
    if (window.webkitURL) {
      videoSource = window.webkitURL.createObjectURL(stream);
    } else {
      videoSource = window.URL.createObjectURL(stream);
    }
    this.stream = stream;
    source.autoplay = true;
    source.src = videoSource;
    this.video = source;
};

Cam.prototype.onError = function(err) {
    alert('There has been a problem retrieving the streams - did you allow access?' + err);
};

也许它可以帮助你:)。

4

1 回答 1

0

当你构建一个构造函数时,

var Visio = function () {
    // constructor
};

并添加一个原型函数,

Visio.prototype.startCall = function () {
   // this === the new Visio object
};

你可以像这样使用它:

var o = new Visio();
o.startCall();

现在在您的原型函数内部this是对象oinstanceof Visio

您在使用函数 name 时感到困惑call。这个名字也被一个Function.prototype.call函数使用,你可以用它覆盖this.
例子:

Visio.prototype.myThisOverride = function () {
    console.log(this);
};

现在使用时Function.prototype.call,您会看到控制台日志打印字符串“Hello World”,因为this === 'Hello World'

var o = new Visio();
o.myThisOverride.call("Hello World");

因此,回到您的代码,您很可能必须将其重写为:

Visio.prototype.startCall = function () {
    callButton.disabled = true;
    hangupButton.disabled = false;
    console.log("Starting call...");
    if (this.localStream.getVideoTracks().length > 0) {
        this.trace('Using video device: ' + this.localStream.getVideoTracks()[0].label);
    }
    if (this.localStream.getAudioTracks().length > 0) {
        this.trace('Using audio device: ' + this.localStream.getAudioTracks()[0].label);
    }

    var servers = null;
    this.localPeerConnection = new RTCPeerConnection(servers);
    console.log(this.localPeerConnection );
    console.log("Created local peer connection object localPeerConnection");
    this.localPeerConnection.onicecandidate = this.gotLocalIceCandidate;

    this.remotePeerConnection = new RTCPeerConnection(servers);
    console.log("Created remote peer connection object remotePeerConnection");
    this.remotePeerConnection.onicecandidate = this.gotRemoteIceCandidate;
    this.remotePeerConnection.onaddstream = this.gotRemoteStream;

    this.localPeerConnection.addStream(this.localStream);
    console.log("Added localStream to localPeerConnection");
    this.localPeerConnection.createOffer(this.gotLocalDescription);
};

并像这样使用它:

var theVisio = new Visio();

callButton.onclick = function () { theVisio.startCall(); };
// which is the same as
callButton.onclick = function () { theVisio.startCall.call(theVisio); };

或者,如果您在构造函数中这样定义它:

var that = this;
callButton.onclick = function () { that.startCall(); };
// which is the same as
callButton.onclick = function () { that.startCall.call(that); };

话虽如此,请尊重名称callapply因为理解运算符this并不是 JavaScript 中最简单的事情!;)

于 2013-08-05T20:21:50.960 回答