0

I have implemented video call integration on the Ionic platform, I am able to call, but I can not mute audio and video streamings. For getting local stream I used apiRTC.getLocalStreams() but getting getLocalStreams is not a method.For mute audio I used localStraem.muteAudio(), this.webRTCClient.toggleAudioMute(this.callId). here also the same error mute audio is not a method. can one help me to fix this issue?

thankyou.

here my code

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);
  }
}
TestOSI
  • 13
  • 3

2 Answers2

0

First, I would make sure declared "apiRTC" var is not undefined and that you know how to import it such that is defined.

Then, make sure the init method for apiRTC is executed first - move this code block up to where you declared apiRTC var:

declare var apiRTC;

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

Note: currently in your code you attempt to use apiRTC before it has initialized.

Then, I would split your method sessionReadyHandler as inside of it you are in fact initializing this.localStream (straem?).

Code would be something like this with my comments inside:

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

Also unsure why you tried to use "bind(this)" inside constructor. In a constructor function 'this' does not have a value. It is a substitute for the new object (Homepage class in your case). The value of 'this' will become the new object when a new object is created.

Sergey Rudenko
  • 8,809
  • 2
  • 24
  • 51
  • Everything working fine for me, with above code except localstream and mute options. please go through this link, so you will get more clarity and then answer me FYI:https://github.com/apizee/ApiRTC-ionic thank you – TestOSI Jun 12 '20 at 04:10
  • I tried your code, but not working. getting error like TypeError: Cannot read property 'createWebRTCClient' of null – TestOSI Jun 12 '20 at 04:27
0

Got an answer for mute options, here the code just replace userMediaSuccessHandler with following userMediaSuccessHandler method in above code

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;
    }
  }
TestOSI
  • 13
  • 3