]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8543 #resolve [Improve mute handling on conference and WebRTC]
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 16 Nov 2015 17:31:27 +0000 (11:31 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 16 Nov 2015 17:31:34 +0000 (11:31 -0600)
html5/verto/js/src/jquery.FSRTC.js
html5/verto/js/src/jquery.verto.js
html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js
html5/verto/video_demo/index.html
html5/verto/video_demo/js/verto-min.js
html5/verto/video_demo/verto.js
src/mod/applications/mod_conference/conference_video.c
src/switch_core_media.c

index d0bf7bf24c370f661ae4e8673de1a9cf4b29ec4f..7d3e0ad2ec3f8a4dbbed69bf545be11cadfac39f 100644 (file)
@@ -90,7 +90,8 @@
             },
         }, options);
 
-       this.enabled = true;
+       this.audioEnabled = true;
+       this.videoEnabled = true;
 
 
         this.mediaData = {
 
     $.FSRTC.prototype.getMute = function() {
        var self = this;
-       return self.enabled;
+       return self.audioEnabled;
     }
 
     $.FSRTC.prototype.setMute = function(what) {
                break;
            }
 
-           self.enabled = audioTracks[i].enabled;
+           self.audioEnabled = audioTracks[i].enabled;
        }
 
-       return !self.enabled;
+       return !self.audioEnabled;
+    }
+
+    $.FSRTC.prototype.getVideoMute = function() {
+       var self = this;
+       return self.videoEnabled;
+    }
+
+    $.FSRTC.prototype.setVideoMute = function(what) {
+       var self = this;
+       var videoTracks = self.localStream.getVideoTracks();    
+
+       for (var i = 0, len = videoTracks.length; i < len; i++ ) {
+           switch(what) {
+           case "on":
+               videoTracks[i].enabled = true;
+               break;
+           case "off":
+               videoTracks[i].enabled = false;
+               break;
+           case "toggle":
+               videoTracks[i].enabled = !videoTracks[i].enabled;
+           default:
+               break;
+           }
+
+           self.videoEnabled = videoTracks[i].enabled;
+       }
+
+       return !self.videoEnabled;
     }
 
     $.FSRTC.prototype.createAnswer = function(params) {
index 779ba791250f1814ec31dfc4f7a6c2231ac9879c..b7912c2a72fc53b8b7a97d7079293524cb06f0d8 100644 (file)
        return dialog.rtc.getMute();
     };
 
+    $.verto.dialog.prototype.setVideoMute = function(what) {
+       var dialog = this;
+       return dialog.rtc.setVideoMute(what);
+    };
+
+    $.verto.dialog.prototype.getVideoMute = function() {
+       var dialog = this; 
+       return dialog.rtc.getVideoMute();
+    };
+
     $.verto.dialog.prototype.useStereo = function(on) {
         var dialog = this;
 
index 256d1bb3e5b14cb14466bfd3e4eca7ff3f97fa4c..3129db87c7d216f05832b1ec648e176bd5fb2c73 100644 (file)
             if (parseInt(member.id) == parseInt(verto.data.conferenceMemberID)) {
               verto.data.mutedMic = member.status.audio.muted;
               verto.data.mutedVideo = member.status.video.muted;
+                         verto.data.call.setMute(member.status.audio.muted ? "off" : "on");
+                         verto.data.call.setVideoMute(member.status.video.muted ? "off" : "on");
             }
             angular.extend($scope.members[memberIdx], member);
           });
index 276b75b36beba2898d5f3c34621eba0e7bf930a4..74992e5807def15dfb6a458acd541ef999afa8c9 100644 (file)
@@ -147,6 +147,7 @@ div#preload { display: none; }
       <button data-inline="true" id="hupbtn">End Call</button>
       <button data-inline="true" id="mutebtn">Toggle Audio Mute</button>
       <button data-inline="true" id="localmutebtn">Toggle Local Audio Mute</button>
+      <button data-inline="true" id="localvidmutebtn">Toggle Local Video Mute</button>
 <!--      <button data-inline="true" class="startxferbtn">Transfer</button>-->
       <span class="sharediv">
          <button data-inline="true" id="sharebtn">Share</button>
index fd9430ce4e96fec0a8cbee7ce6f6469ff1937df3..71e5e27b088dc486afc5d46d0a239c076444e085 100644 (file)
@@ -6,7 +6,7 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\
 function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i<elements.length;i++){if(index===3){newLine[index++]=payload;}
 if(elements[i]!==payload)newLine[index++]=elements[i];}
 return newLine.join(' ');}
-$.FSRTC=function(options){this.options=$.extend({useVideo:null,useStereo:false,userData:null,localVideo:null,screenShare:false,useCamera:"any",iceServers:false,videoParams:{},audioParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}},},options);this.enabled=true;this.mediaData={SDP:null,profile:{},candidateList:[]};if(moz){this.constraints={offerToReceiveAudio:true,offerToReceiveVideo:this.options.useVideo?true:false,};}else{this.constraints={optional:[{'DtlsSrtpKeyAgreement':'true'}],mandatory:{OfferToReceiveAudio:true,OfferToReceiveVideo:this.options.useVideo?true:false,}};}
+$.FSRTC=function(options){this.options=$.extend({useVideo:null,useStereo:false,userData:null,localVideo:null,screenShare:false,useCamera:"any",iceServers:false,videoParams:{},audioParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}},},options);this.audioEnabled=true;this.videoEnabled=true;this.mediaData={SDP:null,profile:{},candidateList:[]};if(moz){this.constraints={offerToReceiveAudio:true,offerToReceiveVideo:this.options.useVideo?true:false,};}else{this.constraints={optional:[{'DtlsSrtpKeyAgreement':'true'}],mandatory:{OfferToReceiveAudio:true,OfferToReceiveVideo:this.options.useVideo?true:false,}};}
 if(self.options.useVideo){self.options.useVideo.style.display='none';}
 setCompat();checkCompat();};$.FSRTC.validRes=[];$.FSRTC.prototype.useVideo=function(obj,local){var self=this;if(obj){self.options.useVideo=obj;self.options.localVideo=local;if(moz){self.constraints.offerToReceiveVideo=true;}else{self.constraints.mandatory.OfferToReceiveVideo=true;}}else{self.options.useVideo=null;self.options.localVideo=null;if(moz){self.constraints.offerToReceiveVideo=false;}else{self.constraints.mandatory.OfferToReceiveVideo=false;}}
 if(self.options.useVideo){self.options.useVideo.style.display='none';}};$.FSRTC.prototype.useStereo=function(on){var self=this;self.options.useStereo=on;};$.FSRTC.prototype.stereoHack=function(sdp){var self=this;if(!self.options.useStereo){return sdp;}
@@ -34,10 +34,14 @@ if(self.localStream){if(typeof self.localStream.stop=='function'){self.localStre
 self.localStream=null;}
 if(self.options.localVideo){self.options.localVideo.style.display='none';if(moz){self.options.localVideo['mozSrcObject']=null;}else{self.options.localVideo['src']='';}}
 if(self.options.localVideoStream){if(typeof self.options.localVideoStream.stop=='function'){self.options.localVideoStream.stop();}else{if(self.localVideoStream.active){var tracks=self.localVideoStream.getTracks();console.error(tracks);tracks.forEach(function(track,index){console.log(track);track.stop();})}}}
-if(self.peer){console.log("stopping peer");self.peer.stop();}};$.FSRTC.prototype.getMute=function(){var self=this;return self.enabled;}
+if(self.peer){console.log("stopping peer");self.peer.stop();}};$.FSRTC.prototype.getMute=function(){var self=this;return self.audioEnabled;}
 $.FSRTC.prototype.setMute=function(what){var self=this;var audioTracks=self.localStream.getAudioTracks();for(var i=0,len=audioTracks.length;i<len;i++){switch(what){case"on":audioTracks[i].enabled=true;break;case"off":audioTracks[i].enabled=false;break;case"toggle":audioTracks[i].enabled=!audioTracks[i].enabled;default:break;}
-self.enabled=audioTracks[i].enabled;}
-return!self.enabled;}
+self.audioEnabled=audioTracks[i].enabled;}
+return!self.audioEnabled;}
+$.FSRTC.prototype.getVideoMute=function(){var self=this;return self.videoEnabled;}
+$.FSRTC.prototype.setVideoMute=function(what){var self=this;var videoTracks=self.localStream.getVideoTracks();for(var i=0,len=videoTracks.length;i<len;i++){switch(what){case"on":videoTracks[i].enabled=true;break;case"off":videoTracks[i].enabled=false;break;case"toggle":videoTracks[i].enabled=!videoTracks[i].enabled;default:break;}
+self.videoEnabled=videoTracks[i].enabled;}
+return!self.videoEnabled;}
 $.FSRTC.prototype.createAnswer=function(params){var self=this;self.type="answer";self.remoteSDP=params.sdp;console.debug("inbound sdp: ",params.sdp);function onSuccess(stream){self.localStream=stream;self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:function(stream){return onRemoteStream(self,stream);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,offerSDP:{type:"offer",sdp:self.remoteSDP}});onStreamSuccess(self);}
 function onError(e){onStreamError(self,e);}
 var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(self.options.useVideo&&self.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:self.options.videoParams,optional:[]},},localVideo:self.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
@@ -95,7 +99,7 @@ $.FSRTC.getValidRes=function(cam,func){var used=[];var cached=localStorage.getIt
 return func?func(cache):null;}
 $.FSRTC.validRes=[];resI=0;checkRes(cam,func);}
 $.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true);}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);}
-console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.speedTest=function(bytes,cb){var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this.speedCB=cb;this.speedBytes=bytes;socket.send("#SPU "+bytes);var loops=bytes/512;var rem=bytes%512;var i;var data=new Array(512).join(".");for(i=0;i<loops;i++){socket.send("#SPB "+data);}
+console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.speedTest=function(bytes,cb){var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this.speedCB=cb;this.speedBytes=bytes;socket.send("#SPU "+bytes);var loops=bytes/1024;var rem=bytes%1024;var i;var data=new Array(1024).join(".");for(i=0;i<loops;i++){socket.send("#SPB "+data);}
 if(rem){socket.send("#SPB "+data);}
 socket.send("#SPE");}};$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
 if(this.options.sessid){params.sessid=this.options.sessid;}
@@ -265,7 +269,7 @@ if(success){}
 break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;}
 if(params.cause){dialog.cause=params.cause;}}
 if(dialog.state.val>=$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;}
-dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
+dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
 if(!msg.body){console.error("Missing Body");err++;}
 if(err){return false;}
 dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(!params){params={};}
index 32caac3041201cff897423a763409c812d0ed80b..31bb147da3dca66cb97ff432c63250816fbaeadc 100644 (file)
@@ -716,6 +716,17 @@ $("#localmutebtn").click(function() {
 
 });
 
+$("#localvidmutebtn").click(function() {
+    var muted = cur_call.setVideoMute("toggle");
+
+    if (muted) {
+       display("Talking to: " + cur_call.cidString() + " [VIDEO LOCALLY MUTED]");
+    } else {
+       display("Talking to: " + cur_call.cidString());
+    }
+
+});
+
 $("#vmutebtn").click(function() {
     cur_call.dtmf("*0");
 });
index 1dabed8888e4387083304201785fce99578ed06c..62120322e8779ef71b20e627fa7130e1db9794b2 100644 (file)
@@ -1845,7 +1845,7 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
 void conference_video_set_incoming_bitrate(conference_member_t *member, int kps)
 {
        switch_core_session_message_t msg = { 0 };
-       
+
        msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
        msg.numeric_arg = kps * 1024;
        msg.from = __FILE__;
@@ -1902,7 +1902,7 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_
        if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) {
                member->managed_kps = 0;
        } else if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps) {
-               int kps;
+               int kps = 256;
                int w = 320;
                int h = 240;
 
@@ -1922,11 +1922,7 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_
                } else {
                        int max = 0;
 
-                       if (!layer || !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) || member->avatar_png_img) {
-                               kps = 256;
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
-                                                                 switch_channel_get_name(member->channel), kps);
-                       } else {
+                       if (layer) {
                                kps = switch_calc_bitrate(w, h, 1, (int)(member->conference->video_fps.fps));
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n",
                                                                  switch_channel_get_name(member->channel), kps, layer->screen_w, layer->screen_h);
@@ -1944,7 +1940,6 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_
                                                                  switch_channel_get_name(member->channel), kps);
                        }
                }
-
                conference_video_set_incoming_bitrate(member, kps);
        }
 }
index 904da2e9e9bbda5125d018078da78024a8136392..dbec5b0d9551116daac52a9a0725c5cb0f74d3ac 100644 (file)
@@ -10894,12 +10894,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
                return SWITCH_STATUS_FALSE;
        }
 
-       if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE_READ)) {
-               *frame = &runtime.dummy_cng_frame;
-               switch_yield(20000);
-               return SWITCH_STATUS_SUCCESS;
-       }
-
        if (session->endpoint_interface->io_routines->read_video_frame) {
                if ((status = session->endpoint_interface->io_routines->read_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) {
                        for (ptr = session->event_hooks.video_read_frame; ptr; ptr = ptr->next) {
@@ -10910,6 +10904,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
                }
        }
 
+       if (switch_channel_test_flag(session->channel, CF_VIDEO_PAUSE_READ)) {
+               *frame = &runtime.dummy_cng_frame;
+               switch_cond_next();
+               return SWITCH_STATUS_SUCCESS;
+       }
+
        if (status == SWITCH_STATUS_INUSE) {
                *frame = &runtime.dummy_cng_frame;
                switch_cond_next();