简体   繁体   English

为什么这个无法启动的javascript事件?

[英]Why this javascript event that does not start?

I'm trying to follow a tutorial on RTCPeerConnection API that enables the sharing of sound, image, data between browsers. 我正在尝试遵循有关RTCPeerConnection API的教程,该教程支持在浏览器之间共享声音,图像和数据。

Here is the code that works: 这是有效的代码:

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);
}

Here is my code that does not work: 这是我的代码不起作用:

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);
};

with my call to the call method : 我对call方法的call

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

As said in the title, the events : onicecandidate and onaddstream never triggered. 如标题中所述,事件:onicecandidate和onaddstream从未触发。 I do not know why. 我不知道为什么。

Any idea? 任何想法?


Ok , i modified my function. 好的,我修改了我的功能。 But it doesn't works anymore :( 但是它不再起作用了:(

This is the full code : 这是完整的代码:

Visio.js 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;
};

And cam.js 和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);
};

Maybe it can help you :). 也许可以帮助您:)。

When you build a constructor function, 当您构建构造函数时,

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

and add a prototype function, 并添加一个原型函数

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

you can use it like this: 您可以像这样使用它:

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

Now inside your prototype function this is the object o instanceof Visio . 现在,你的原型函数内部this是对象o的instanceof Visio

You are confusingly using the function name call . 您在使用函数名call感到困惑。 This name is also used by a Function.prototype.call function, with which you can override this . Function.prototype.call函数也使用此名称,您可以使用它覆盖this
Example: 例:

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

Now when using Function.prototype.call , you see console log printing the string "Hello World", because this === 'Hello World' : 现在,当使用Function.prototype.call ,您会看到控制台日志打印字符串“ Hello World”,因为this === 'Hello World'

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

So coming back to your code, you most likely have to rewrite it to: 因此,回到您的代码,您很可能必须将其重写为:

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);
};

And use it like this: 并像这样使用它:

var theVisio = new Visio();

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

Or if you defined it like this inside the constructor: 或者,如果您在构造函数中这样定义它:

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

And with this said, please respect the names call and apply because understanding operator this isn't the easiest thing in javaScript! 而与此说,请尊重名字callapply ,因为理解运营商this不是在JavaScript中最容易的事! ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM