2
init: function(config){
    var that = this;

    that.CONFIG = config;

    that.video = Twilio.Video;
    that.CONFIG.videoCall = true;
    that.CONFIG.audioCall =true;
    that.CONFIG.audioCallTrackCount =0;
    that.CONFIG.videoCallTrackCount =0;
    //alert message instance
    that.ALERT_MESSAGES = Object.create(AlertMessage).init();

    //ajaxing instance
    that.AJAXING = Object.create(Ajaxing);
    $(".fullscreen-btn").addClass('hide');
    window.videoCallObject = that;
    that.cachePageConstants();
    //that.getTwilioTokenFromRestAPI();

    return that;
},

cachePageConstants: function(){
   var that = this;
    $("#buttonCall").on("click", function(e){
       e.preventDefault();
       console.log("video button clicked");
        $("#buttonCall").hide();
        $("#audioCall").hide();
        $("#buttonCallEnd").show();
        $(".mute-btns").removeClass('hide');
        document.getElementById('connecting').innerHTML = '<span style="color:#69C4CB;"><img src="/resources/css/images/refresh_gif.gif" />Calling...</span>';
      that.CONFIG.videoCall =true;
      that.getTwilioTokenFromRestAPI();
    });
    $("#audioCall").on("click", function(e){
       e.preventDefault();
       console.log("Audio button clicked");
        $("#buttonCall").hide();
        $("#audioCall").hide();
        $("#buttonCallEnd").show();
        $(".mute-btns").removeClass('hide');
        document.getElementById('connecting').innerHTML = '<span style="color:#69C4CB;"><img src="/resources/css/images/refresh_gif.gif" />Calling...</span>';
      that.CONFIG.videoCall = false;
      that.CONFIG.audioCall =true;
      that.getTwilioTokenFromRestAPI();
    });

    $("#buttonRefresh").on("click", function(e){
        e.preventDefault();
        that.refreshPatientStatus(true);
    });

    $("#buttonCallEnd").on("click", function(e){
       e.preventDefault();
       console.log("Call end button clicked");
        $("#buttonCallEnd").hide();
        $("#buttonCall").show();
        $("#audioCall").show();
        $(".mute-btns").addClass('hide');
        that.leaveRoomIfJoined();
    });
    $('.fullscreen-btn').on('click', function(){
        $(this).parent().toggleClass('fullscreen');
    });
},
getTwilioTokenFromRestAPI: function(){
    var that = this,
    postRequestActions = {
        "successCallBack": that.onGettingToken,
        "loading": $("#connecting"),
        "ajaxType": "GET"
    };

    that.AJAXING.sendRequest(that.CONFIG.baseUrl+ "/services/v3/twilio/getTwilioToken?patientUuid="+UUID+"&providerUserId="+providerUserId+"&requestedFrom="+"COACH", null, postRequestActions);
},


onGettingToken: function(data){

    var that = window.videoCallObject;
    that.CONFIG.data=data;
    if(data){
          that.CONFIG.TOKEN = data.token;
          $("#connecting").removeClass("hide");
          $("#connecting").show();
          that.sendNotificationForcall(data);
          that.initTwilioCall(data.token,data.room);
    }else{
        that.ALERT_MESSAGES.showAlertMessage($("#terminatedMessage"), "Unable to get token from rest API", that.ALERT_MESSAGES.ERROR);
    }
},
//send Video call Notification to client.
sendNotificationForcall:function (data) {

  var that = this,
    requestActions = {
       "ajaxType": "GET"
    };
  var type = "CREATE_CALL"
  var callType;
  if(that.CONFIG.videoCall)
    callType = "VIDEO_CALL";
  else
    callType = "AUDIO_CALL";
  /*that.AJAXING.sendRequest(that.CONFIG.baseUrl+ "/services/v3/twilio/sendTwilioVideoNotification?patientId="+patId+"&providerUserId="+data.providerUserId+"&roomName="+data.roomName+"&callType="+callType+"&type="+type, null, requestActions);*/

},
 //send Video call Notification to client.
sendNotificationForCallCancel:function (data,type) {

  var that = this,
    requestActions = {
       "ajaxType": "GET"
    };
  var callType;
  if(that.CONFIG.videoCall)
    callType = "VIDEO_CALL";
  else
    callType = "AUDIO_CALL";

  /*that.AJAXING.sendRequest(that.CONFIG.baseUrl+ "/services/v3/twilio/sendTwilioVideoNotification?patientId="+patId+"&providerUserId="+data.providerUserId+"&roomName="+data.roomName+"&callType="+callType+"&type="+type, null, requestActions);*/

},
initTwilioCall: function (token,room) {
  var that = window.videoCallObject;
    that.video.connect(token, {audio: that.CONFIG.audioCall,
          name: room,
          video: that.CONFIG.videoCall
        }).then(function(room) {
         that.onParticipantConnected(room);

          //room.disconnect();
        }, function(error) {
            //console.error('Unable to connect to Room: ' +  error.message);
            that.ALERT_MESSAGES.showAlertMessage($("#terminatedMessage"), "Unable to get token from rest API", error.message);
    });


},
onParticipantConnected: function (room) {
   var that = window.videoCallObject;
    that.CONFIG.activeRoom=room;
    // Attach LocalParticipant's Tracks, if not already attached.
    that.CONFIG.previewContainer = document.getElementById('local-media');
    var previewContainer = that.CONFIG.previewContainer;

    if (!previewContainer.querySelector('video')) {
      document.getElementById('connecting').innerHTML = '<span style="color:Blue;"><img src="/resources/css/images/refresh_gif.gif" />Connecting...</span>';
        //that.attachParticipantTracks(room.localParticipant, previewContainer);

    }
  room.on('participantConnected', function(participant) {

        room.participants.forEach(function(participant) {
            //console.log("Already in Room: '" + participant.identity + "'");
            var previewContainer = document.getElementById('videoContainer');
            that.CONFIG.activeRoom.previewContainer=previewContainer;
            that.attachParticipantTracks(participant, previewContainer);
        });
            //console.log('A remote Participant connected: ', participant);
            $(".fullscreen-btn").removeClass('hide');
            document.getElementById('connecting').innerHTML = '<span style="color:green;">Call active</span>';

    });

    // When a Participant adds a Track, attach it to the DOM.
    room.on('trackAdded', function(track, participant) {
      if(track.kind =='video' && that.CONFIG.videoCall == false){
          that.CONFIG.videoCall = true;
          that.video.createLocalVideoTrack().then(function(localTrack) {

          room.localParticipant.addTrack(localTrack);
            that.attachParticipantTracks(room.localParticipant, that.CONFIG.previewContainer);
          });
        }else{
                room.localParticipant.tracks.forEach(track => {
                if(track.kind == 'video'){
                  track.enable();

                }
            });
            if(track.kind =='video')
                that.attachParticipantTracks(room.localParticipant, that.CONFIG.previewContainer);   

        }
       var previewContainer = document.getElementById('videoContainer');
       that.attachTracks([track], previewContainer);
    });
     // When a Participant removes a Track, detach it from the DOM.
    room.on('trackRemoved', function(track, participant) {
        if(track.kind =='video'){
          that.detachSingleTracks(room.localParticipant);
        }

        that.detachTracks([track]);
     });

    // When a Participant leaves the Room, detach its Tracks.
    room.on('participantDisconnected', function(participant) {
        $("#buttonCall").show();
        $("#audioCall").show();
        $("#buttonCallEnd").hide();
        $(".mute-btns").addClass('hide');
        that.detachParticipantTracks(participant);
         that.detachParticipantTracks(room.localParticipant);
         that.leaveRoomIfJoined();

    });

    // Once the LocalParticipant leaves the room, detach the Tracks
    // of all Participants, including that of the LocalParticipant.
    room.on('disconnected', function() {
        $("#buttonCall").show();
        $("#audioCall").show();
        $("#buttonCallEnd").hide();
        $(".mute-btns").addClass('hide');
        that.detachParticipantTracks(room.localParticipant);

        room.participants.forEach(that.detachParticipantTracks);

    });



},
// Attach the Participant's Tracks to the DOM.
attachParticipantTracks:function (participant, container) {
    var that = window.videoCallObject;
    var tracks = Array.from(participant.tracks.values());
    that.attachTracks(tracks, container);


},
// Attach the Tracks to the DOM.
attachTracks:function(tracks, container) {
  var that = window.videoCallObject;
  tracks.forEach(function(track) {
      if(track.kind == 'audio' && that.CONFIG.audioCallTrackCount == 0){
        container.appendChild(track.attach());
        that.CONFIG.audioCallTrackCount = 1;
      }else if(track.kind == 'video' && that.CONFIG.videoCallTrackCount == 0){
         //console.log("video");
        container.appendChild(track.attach());
        that.CONFIG.videoCallTrackCount = 1;
      }
      else{
        container.appendChild(track.attach());
      }
  });
},
// Detach the Tracks from the DOM.
detachTracks:function(tracks) {
 tracks.forEach(function(track) {

    track.detach().forEach(function(detachedElement) {
      detachedElement.remove();
    });

  });

  $("#connecting").addClass("hide");
  $(".fullscreen-btn").addClass('hide');

},
// Detach the Participant's Tracks from the DOM.
detachParticipantTracks:function(participant) {

    var that = window.videoCallObject;
    var tracks;
    if(participant.tracks !='undefined'){
      tracks = Array.from(participant.tracks.values());
    }
    that.detachTracks(tracks);
},

detachSingleTracks:function(participant) {

    var that = window.videoCallObject;
    var tracks;

    participant.tracks.forEach(track => {

      if(track.kind == 'video'){

        track.detach().forEach(function(detachedElement) {
          detachedElement.remove();
        });
        track.disable();
      }
  });

},


leaveRoomIfJoined:function() {
 var that = window.videoCallObject;
  if (that.CONFIG.activeRoom) {
      that.CONFIG.activeRoom.disconnect();

  that.sendNotificationForCallCancel(that.CONFIG.data,'CANCEL_CALL');
    //that.detachParticipantTracks(that.CONFIG.activeRoom.participant);
  }
}

}

JavaScript beginner here!

I am trying to mute/unmute and pause/unpause audio and video but I have no clue how to do it.

I want the button to mute/unmute the audio when clicked and pause/unpause video from my local when i click another button.This is the full javascript code.

Now please edit this and solve the prolblem.

newBee
  • 33
  • 1
  • 9

4 Answers4

5

Twilio developer evangelist here.

You've not included the bits of your code that actually setup the call, so I can only point you in the right direction.

When you join a room, your local media is accessible from the localParticipant object in the room. A localParticpant is an instance of Participant, so you can call on their audioTracks or videoTracks, which both implement LocalTrack, when you want to.

If you want to mute audio, for example, you can call

room.localParticipant.audioTracks.forEach(function(trackId, track) {
  track.disable();
});

You can do the same for videoTracks. To enable tracks again, you'd do the same but with track.enable().

Let me know if that helps at all.

philnash
  • 70,667
  • 10
  • 60
  • 88
  • Not sure what you've done or what your issue is now. Can you explain? – philnash Aug 11 '17 at 09:46
  • i just want to add the functionality to mute/unmute pause/unpause audio and video into this code. – newBee Aug 11 '17 at 09:49
  • I've told you what you need to do, why not go ahead and try it yourself first and then if you have a problem come back and ask about it. – philnash Aug 11 '17 at 09:50
  • $("#buttonMute").on("click", function(e){ e.preventDefault(); that.CONFIG.activeRoom.localParticipant.audioTracks.forEach(function(trackId, track) { track.detach(); }); });I did this but an error is occuring that track.detach is not a function.I tried with track.disable() also but both not worked. – newBee Aug 11 '17 at 10:33
  • You want to use `disable` not `detach`, so that it's easy to `enable` again. – philnash Aug 11 '17 at 10:34
  • Ok, can you debug it a bit? What do you get passed to the callback for the foreach? Are they track objects at all? – philnash Aug 11 '17 at 11:08
  • $("#buttonMute").on("click", function(e){ e.preventDefault(); var that = window.videoCallObject; var tracks; that.CONFIG.activeRoom.localParticipant.tracks.forEach(track => { if(track.kind == 'audio'){ track.detach().forEach(function(detachedElement) { detachedElement.remove(); }); track.disable(); } }); }); I did this and managed to mute the audio...now what should i do to unmute it again. – newBee Aug 11 '17 at 11:23
  • 1
    Again, I wouldn't `detach`, just `disable`. Then you can `enable` again. – philnash Aug 11 '17 at 11:27
  • Now,i want to get the notification when the user rejects the call – newBee Aug 14 '17 at 13:37
  • How are you calling the user? – philnash Aug 14 '17 at 13:38
  • by generating a room from thier userIds – newBee Aug 14 '17 at 13:41
  • Sure, but that doesn't generate a notification. How are you doing that? – philnash Aug 14 '17 at 13:41
  • by passing room name,userIds and callType.am i clear now? – newBee Aug 14 '17 at 13:48
  • You have a route in your application called `/services/v3/twilio/sendTwilioVideoNotification`. What does it do? – philnash Aug 14 '17 at 13:50
  • and above is the js for it from which i m calling my Api to generate twilio token and send notification. – newBee Aug 14 '17 at 13:50
  • @Secured({ "ROLE_PROVIDER" }) @RequestMapping(value = "/sendTwilioVideoNotification", method = RequestMethod.GET) public @ResponseBody Boolean sendTwilioVideoNotification(@Context HttpServletRequest httpRequest, @RequestParam("patientId") Long patientId, @RequestParam("providerUserId") Long providerUserId, @RequestParam("roomName") String roomName, @RequestParam("callType") String callType, @RequestParam("type") String type) throws Exception{ Map returnMap = new HashMap(); – newBee Aug 14 '17 at 13:54
  • returnMap.put("roomName", roomName); returnMap.put("providerUserId", providerUserId); returnMap.put("callType", callType); String twilioNotificationPayLoad = new GsonBuilder().create().toJson(returnMap); – newBee Aug 14 '17 at 13:54
  • if(type.equalsIgnoreCase(PatientAppUtils.TwillioCallType.CREATE_CALL.parameterName)){ notificationManager.sendPushNotificationToMember(patientId,PatientAppUtils.EventType.VIDEO_CALL.parameterName,PatientAppUtils.EventType.VIDEO_CALL.parameterName,twilioNotificationPayLoad,PatientAppUtils.AlertMessages.VIDEO_CALL.parameterName,null); }else{ notificationManager.sendPushNotificationToMember(patientId,PatientAppUtils.EventType.VIDEO_CALL_CANCEL.parameterName,PatientAppUtils.EventType.VIDEO_CALL_CANCEL.parameterName,twilioNotificationPayLoad,null,null); } return true; – newBee Aug 14 '17 at 13:55
  • this is the API – newBee Aug 14 '17 at 13:55
  • Ok, it might be best for you to start a new question with all of that. It's nothing to do with this question really and it's unreadable in comments like that. Let me know when you've formulated it all as a new question and I'll see how I can help. – philnash Aug 14 '17 at 15:03
3
I implemented in following way..Implementing separate methods for each action.


function muteVideo(){
    var localParticipant = activeRoom.localParticipant;
    localParticipant.videoTracks.forEach(function (videoTracks) {
        videoTracks.track.disable();

    });
}

function unMuteVideo(){
    var localParticipant = activeRoom.localParticipant;
    localParticipant.videoTracks.forEach(function (videoTracks) {
        videoTracks.track.enable();
    });
}

function unMuteAudio(){
    var localParticipant = activeRoom.localParticipant;
    localParticipant.audioTracks.forEach(function (audioTrack) {
        audioTrack.track.enable();
    });
}

function muteAudio(){
    var localParticipant = activeRoom.localParticipant;
    localParticipant.audioTracks.forEach(function (audioTrack) {
        audioTrack.track.disable();
    });
}
0

Probably I'm very late

Quite self-explanatory, but... First you have to assign the localParticipant audio tracks, then check if they are active (unmuted) or disabled (muted). If the track is active, disable it to mute it. If the track is disabled, enable it to unmute it. This code allows you to have a simple "mute" button that was the primary question

function unmute_mute() {
    var localParticipant = room.localParticipant;
    localParticipant.audioTracks.forEach(function (audioTrack) {
    if ( audioTrack.isEnabled == true ) {
            audioTrack.disable();
    } else {
        audioTrack.enable();
    }
    });
}
J Lms
  • 11
  • 1
  • 1
    Nothing wrong with being a [Johnny-come-lately](https://en.wiktionary.org/wiki/Johnny-come-lately), but adding some explanation to your code would definitely help here. – Wai Ha Lee Apr 04 '19 at 15:26
  • Quite self-explanatory, but... First you have to assign the localParticipant audio tracks, then check if they are active (unmuted) or disabled (muted). If the track is active, disable it to mute it. If the track is disabled, enable it to unmute it. This code allows you to have a simple "mute" button that was the primary question – J Lms Apr 05 '19 at 16:19
0

If you are using JavaScript v2 then the following code will work fine.

function muteAudioHandler() {
  event.preventDefault();
  room.localParticipant.audioTracks.forEach(publication => {
    publication.track.disable();
  });
}

function unmuteAudioHandler() {
  event.preventDefault();
  room.localParticipant.audioTracks.forEach(publication => {
    publication.track.enable();
  });
}

function hideVideoHandler() {
  event.preventDefault();
  room.localParticipant.videoTracks.forEach(publication => {
    publication.track.disable();
  });
}

function showVideoHandler() {
  event.preventDefault();
  room.localParticipant.videoTracks.forEach(publication => {
    publication.track.enable();
  });
}
Rajesh Vishnani
  • 55
  • 1
  • 1
  • 12