如何在APIRTC上为离子平台静音和取消静音视频/音频?

时间:2020-06-11 14:21:54

标签: ionic-framework webrtc videocall

我已经在Ionic平台上实现了视频通话集成,我可以通话,但不能使音频和视频流静音。为了获得本地流,我使用了apiRTC.getLocalStreams(),但没有getLocalStreams方法。 我使用了localStraem.muteAudio(),this.webRTCClient.toggleAudioMute(this.callId)。 这里也有同样的错误静音音频不是一种方法。可以帮我解决这个问题吗?

谢谢。

这里是我的代码

declare var iosrtc;

declare var apiRTC;
declare var apiCC;

const STATE_WAIT = "wait";
const STATE_INCALL = "incall";

const LABEL_CALL = "Call";
const LABEL_HANGOUT = "Hangout";

const COLOR_CALL = "#5cb85c";
const COLOR_HANGOUT = "#d9534f";

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
});

export class HomePage {

  distantNumber: any;
  webRTCClient: any;
  infoLabel: any;
  buttonLabel: any;
  buttonColor: any;
  state: any;
  localStraem;
  callId;

  isMute;

  constructor(public navCtrl: NavController, public alertCtrl: AlertController, public platform: Platform, public nativeAudio: NativeAudio) {

    this.isMute = false;


    this.incomingCallHandler = this.incomingCallHandler.bind(this);

    this.userMediaErrorHandler = this.userMediaErrorHandler.bind(this);

    this.remoteStreamAddedHandler = this.remoteStreamAddedHandler.bind(this);

    this.hangupHandler = this.hangupHandler.bind(this);

    this.refreshVideoView = this.refreshVideoView.bind(this);

    this.sessionReadyHandler = this.sessionReadyHandler.bind(this);

    this.userMediaSuccessHandler = this.userMediaSuccessHandler.bind(this);


    apiRTC.init({
      onReady: this.sessionReadyHandler,
      apiKey: "My APIKey",



    });

    this.nativeAudio.preloadComplex('uniqueI1', 'assets/tone.mp3', 1, 1, 0).then((succ) => {
      console.log("suu..........", succ)
    }, (err) => {
      console.log("err..........", err)
    });

    this.infoLabel = "Registration Ongoing...";
    this.buttonLabel = LABEL_CALL;
    this.buttonColor = COLOR_CALL;
    this.state = STATE_WAIT;
  }

  /**
   * Call Action
   */
  pushCall(event) {
    console.log("Push, callState=" + this.state);
    if (this.distantNumber && this.state == STATE_WAIT) {
      setTimeout(this.refreshVideoView, 4000);
      this.webRTCClient.call(this.distantNumber);
    } else if (this.state == STATE_INCALL) {
      this.state = STATE_WAIT;
      this.buttonColor = COLOR_CALL;
      this.buttonLabel = LABEL_CALL;
      this.webRTCClient.hangUp();
    }
  }

  sessionReadyHandler(e) {

    console.log("sessionReadyHandler");
    apiRTC.addEventListener("incomingCall", this.incomingCallHandler);
    apiRTC.addEventListener("userMediaError", this.userMediaErrorHandler);
    apiRTC.addEventListener("remoteStreamAdded", this.remoteStreamAddedHandler);
    apiRTC.addEventListener("userMediaSuccess", this.userMediaSuccessHandler);
    apiRTC.addEventListener("hangup", this.hangupHandler);
    this.webRTCClient = apiCC.session.createWebRTCClient({});

    this.infoLabel = "Your local ID : " + apiCC.session.apiCCId;
    this.callId = apiCC.session.apiCCId;
    this.localStraem= this.webRTCClient.getLocalStreams()   // getting here error like getLocalStreams is not a method
    // this.localStraem= apiRTC.getLocalStreams()   // getting here also same error 
  }

  refreshVideoView() {
    if (this.platform.is('ios')) {
      console.log("REFRESH");
      iosrtc.refreshVideos();
    }
  }

  incomingCallHandler(e) {
    console.log("incomingCallHandler");
    this.state = STATE_INCALL;
    this.buttonColor = COLOR_HANGOUT;
    this.buttonLabel = LABEL_HANGOUT;
    setTimeout(this.refreshVideoView, 2000);
  }

  hangupHandler(e) {
    console.log("hangupHandler");
    this.state = STATE_WAIT;
    this.buttonColor = COLOR_CALL;
    this.buttonLabel = LABEL_CALL;
    this.initMediaElementState(e.detail.callId);
  }
  ;
  userMediaSuccessHandler(e) {
    console.log("userMediaSuccessHandler", e);

    console.log('loca..........' + JSON.stringify(e.detail.stream))
    this.webRTCClient.addStreamInDiv(
      e.detail.stream,
      e.detail.callType,
      "mini",
      'miniElt-' + e.detail.callId,
      { width: "200px", height: "200px" },
      false

    );
  }

  userMediaErrorHandler(e) {
  }

  muteAudio() {
    this.localStraem.muteAudio();     // here mute audio not a method error
    console.log('cal......id............' + this.callId)
    // this.webRTCClient.toggleAudioMute(this.callId)  

    // this.localStraem.getAudioTracks()[0].stop();
    //   this.localStraem.getTracks().forEach((track) => {
    //     track.stop();
    // });
  }

  unmuteAudio() {
    // this.localStraem.unmuteAudio();
    this.localStraem.getTracks().forEach((track) => {
      track.start();
    });
  }



  remoteStreamAddedHandler(e) {
    console.log('mute..........' + this.isMute)

    console.log("remoteStreamAddedHandler", e);
    this.state = STATE_INCALL;
    this.buttonColor = COLOR_HANGOUT;
    this.buttonLabel = LABEL_HANGOUT;
    this.webRTCClient.addStreamInDiv(
      e.detail.stream,
      e.detail.callType,
      "remote",
      'remoteElt-' + e.detail.callId,
      { width: "200px", height: "200px" },
      this.isMute
    );
    setTimeout(this.refreshVideoView, 1000);
  }

  initMediaElementState(callId) {
    this.webRTCClient.removeElementFromDiv('mini', 'miniElt-' + callId);
    this.webRTCClient.removeElementFromDiv('remote', 'remoteElt-' + callId);
  }
}

2 个答案:

答案 0 :(得分:0)

首先,我将确保声明的“ apiRTC” var不是未定义的,并且您知道如何导入已定义的变量。

然后,确保首先执行apiRTC的init方法-将代码块移至声明apiRTC var的位置:

declare var apiRTC;

apiRTC.init({
      onReady: this.sessionReadyHandler,
      apiKey: "My APIKey",
});

注意:当前在您的代码中,您尝试在apiRTC初始化之前使用它。

然后,我将您的方法sessionReadyHandler拆分为内部,实际上您正在初始化this.localStream(straem?)。

代码将是这样,其中包含我的注释:

declare var iosrtc;
declare var apiRTC;

apiRTC.init({
    onReady: this.sessionReadyHandler,
    apiKey: "My APIKey",
});

console.log(apiRTC) // should return defined here

declare var apiCC;

const STATE_WAIT = "wait";
const STATE_INCALL = "incall";

const LABEL_CALL = "Call";
const LABEL_HANGOUT = "Hangout";

const COLOR_CALL = "#5cb85c";
const COLOR_HANGOUT = "#d9534f";

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
}) // get rid of ; here
export class HomePage {

  distantNumber; // no point using type 'any' here
  webRTCClient;
  infoLabel;
  buttonLabel;
  buttonColor;
  state;
  localStraem;
  callId;
  isMute;

  constructor(public navCtrl: NavController, public alertCtrl: AlertController, public platform: Platform, public nativeAudio: NativeAudio) {

    // initialize handlers inside ngOnInit hook and you do not need binding 'this' here:
    /* this.incomingCallHandler = this.incomingCallHandler.bind(this);
    this.userMediaErrorHandler = this.userMediaErrorHandler.bind(this);
    this.remoteStreamAddedHandler = this.remoteStreamAddedHandler.bind(this);
    this.hangupHandler = this.hangupHandler.bind(this);
    this.refreshVideoView = this.refreshVideoView.bind(this);
    this.sessionReadyHandler = this.sessionReadyHandler.bind(this);
    this.userMediaSuccessHandler = this.userMediaSuccessHandler.bind(this); */

  };

  ngOnInit() {

    this.nativeAudio.preloadComplex('uniqueI1', 'assets/tone.mp3', 1, 1, 0).then((succ) => {
        console.log("suu..........", succ)
    }, (err) => {
        console.log("err..........", err)
    });
    this.isMute = false;
    this.infoLabel = "Registration Ongoing...";
    this.buttonLabel = LABEL_CALL;
    this.buttonColor = COLOR_CALL;
    this.state = STATE_WAIT;

    // moved here from sessionReadyHandler:
    this.webRTCClient = apiCC.session.createWebRTCClient({});
    this.infoLabel = "Your local ID : " + apiCC.session.apiCCId;
    this.callId = apiCC.session.apiCCId;
    this.localStraem= this.webRTCClient.getLocalStreams()   // should work now;
    // this.localStraem= apiRTC.getLocalStreams()   // same
    this.sessionReadyHandler() // init listeners, you also might want to remove listeners inside onDestroy hook
  };

  /**
   * Call Action
   */
  pushCall(event) {
    console.log("Push, callState=" + this.state);
    if (this.distantNumber && this.state == STATE_WAIT) {
      setTimeout(this.refreshVideoView, 4000);
      this.webRTCClient.call(this.distantNumber);
    } else if (this.state == STATE_INCALL) {
      this.state = STATE_WAIT;
      this.buttonColor = COLOR_CALL;
      this.buttonLabel = LABEL_CALL;
      this.webRTCClient.hangUp();
    }
  }

  sessionReadyHandler() { // event argument is not used here

    console.log("sessionReadyHandler");
    apiRTC.addEventListener("incomingCall", this.incomingCallHandler);
    apiRTC.addEventListener("userMediaError", this.userMediaErrorHandler);
    apiRTC.addEventListener("remoteStreamAdded", this.remoteStreamAddedHandler);
    apiRTC.addEventListener("userMediaSuccess", this.userMediaSuccessHandler);
    apiRTC.addEventListener("hangup", this.hangupHandler);

  }

  refreshVideoView() {
    if (this.platform.is('ios')) {
      console.log("REFRESH");
      iosrtc.refreshVideos();
    }
  }

  incomingCallHandler(e) {
    console.log("incomingCallHandler");
    this.state = STATE_INCALL;
    this.buttonColor = COLOR_HANGOUT;
    this.buttonLabel = LABEL_HANGOUT;
    setTimeout(this.refreshVideoView, 2000);
  }

  hangupHandler(e) {
    console.log("hangupHandler");
    this.state = STATE_WAIT;
    this.buttonColor = COLOR_CALL;
    this.buttonLabel = LABEL_CALL;
    this.initMediaElementState(e.detail.callId);
  }
  ;
  userMediaSuccessHandler(e) {
    console.log("userMediaSuccessHandler", e);

    console.log('loca..........' + JSON.stringify(e.detail.stream))
    this.webRTCClient.addStreamInDiv(
      e.detail.stream,
      e.detail.callType,
      "mini",
      'miniElt-' + e.detail.callId,
      { width: "200px", height: "200px" },
      false

    );
  }

  userMediaErrorHandler(e) {
  }

  muteAudio() {
    this.localStraem.muteAudio();     // here mute audio not a method error
    console.log('cal......id............' + this.callId)
    // this.webRTCClient.toggleAudioMute(this.callId)  

    // this.localStraem.getAudioTracks()[0].stop();
    //   this.localStraem.getTracks().forEach((track) => {
    //     track.stop();
    // });
  }

  unmuteAudio() {
    // this.localStraem.unmuteAudio();
    this.localStraem.getTracks().forEach((track) => {
      track.start();
    });
  }



  remoteStreamAddedHandler(e) {
    console.log('mute..........' + this.isMute)

    console.log("remoteStreamAddedHandler", e);
    this.state = STATE_INCALL;
    this.buttonColor = COLOR_HANGOUT;
    this.buttonLabel = LABEL_HANGOUT;
    this.webRTCClient.addStreamInDiv(
      e.detail.stream,
      e.detail.callType,
      "remote",
      'remoteElt-' + e.detail.callId,
      { width: "200px", height: "200px" },
      this.isMute
    );
    setTimeout(this.refreshVideoView, 1000);
  }

  initMediaElementState(callId) {
    this.webRTCClient.removeElementFromDiv('mini', 'miniElt-' + callId);
    this.webRTCClient.removeElementFromDiv('remote', 'remoteElt-' + callId);
  }
}

也不确定为什么要在构造函数中使用“ bind(this)”。在构造函数中,“ this”没有值。它替代了新对象(在您的情况下为Homepage类)。创建新对象时,“ this”的值将成为新对象。

答案 1 :(得分:0)

获得静音选项的答案,此处为代码 只需将上述代码中的 userMediaSuccessHandler 方法替换为 userMediaSuccessHandler

userMediaSuccessHandler(e) {
    console.log("userMediaSuccessHandler", e);
    this.webRTCClient.addStreamInDiv(
      e.detail.stream,
      e.detail.callType,
      "mini",
      'miniElt-' + e.detail.callId,
      { width: "128px", height: "96px" },
      true
    );

    this.myStreemAudio = e.detail.stream;

  }

  myStreemAudio;
  isMute = false;
  muteCall(val) {

  if (val == 0) {
      this.myStreemAudio.getAudioTracks()[0].enabled = false;
    } else {
      this.myStreemAudio.getAudioTracks()[0].enabled = true;
    }

    console.log('de.........' + val)
  }


  muteVideo(val) {
    if (val == 0) {
      this.myStreemAudio.getVideoTracks()[0].enabled = false;
    } else {
      this.myStreemAudio.getVideoTracks()[0].enabled = true;
    }
  }