From 26a7fdf324f093f9eca0f06ebd7daee280739248 Mon Sep 17 00:00:00 2001 From: Jonas Smedegaard Date: Wed, 24 May 2017 13:29:05 +0200 Subject: Minify janus. --- js/lib/janus.min.js | 2 ++ js/lib/janus.nojquery.min.js | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 js/lib/janus.min.js create mode 100644 js/lib/janus.nojquery.min.js (limited to 'js') diff --git a/js/lib/janus.min.js b/js/lib/janus.min.js new file mode 100644 index 0000000..6403526 --- /dev/null +++ b/js/lib/janus.min.js @@ -0,0 +1,2 @@ +Janus.sessions={};Janus.extensionId="hapfgfdkleiggjjpfpenajgdnfckjpaj";Janus.isExtensionEnabled=function(){if(window.navigator.userAgent.match("Chrome")){var chromever=parseInt(window.navigator.userAgent.match(/Chrome\/(.*) /)[1],10);var maxver=33;if(window.navigator.userAgent.match("Linux"))maxver=35;if(chromever>=26&&chromever<=maxver){return true}return $("#janus-extension-installed").length>0}else{return true}};Janus.noop=function(){};Janus.init=function(options){options=options||{};options.callback=typeof options.callback=="function"?options.callback:Janus.noop;if(Janus.initDone===true){options.callback()}else{if(typeof console=="undefined"||typeof console.log=="undefined")console={log:function(){}};Janus.trace=Janus.noop;Janus.debug=Janus.noop;Janus.vdebug=Janus.noop;Janus.log=Janus.noop;Janus.warn=Janus.noop;Janus.error=Janus.noop;if(options.debug===true||options.debug==="all"){Janus.trace=console.trace.bind(console);Janus.debug=console.debug.bind(console);Janus.vdebug=console.debug.bind(console);Janus.log=console.log.bind(console);Janus.warn=console.warn.bind(console);Janus.error=console.error.bind(console)}else if(Array.isArray(options.debug)){for(var i in options.debug){var d=options.debug[i];switch(d){case"trace":Janus.trace=console.trace.bind(console);break;case"debug":Janus.debug=console.debug.bind(console);break;case"vdebug":Janus.vdebug=console.debug.bind(console);break;case"log":Janus.log=console.log.bind(console);break;case"warn":Janus.warn=console.warn.bind(console);break;case"error":Janus.error=console.error.bind(console);break;default:console.error("Unknown debugging option '"+d+"' (supported: 'trace', 'debug', 'vdebug', 'log', warn', 'error')");break}}}Janus.log("Initializing library");Janus.listDevices=function(callback){callback=typeof callback=="function"?callback:Janus.noop;if(navigator.mediaDevices){navigator.mediaDevices.getUserMedia({audio:true,video:true}).then(function(stream){navigator.mediaDevices.enumerateDevices().then(function(devices){Janus.debug(devices);callback(devices);try{stream.stop()}catch(e){}try{var tracks=stream.getTracks();for(var i in tracks){var mst=tracks[i];if(mst!==null&&mst!==undefined)mst.stop()}}catch(e){}})}).catch(function(err){Janus.error(err);callback([])})}else{Janus.warn("navigator.mediaDevices unavailable");callback([])}};Janus.attachMediaStream=function(element,stream){if(adapter.browserDetails.browser==="chrome"){var chromever=adapter.browserDetails.version;if(chromever>=43){element.srcObject=stream}else if(typeof element.src!=="undefined"){element.src=URL.createObjectURL(stream)}else{Janus.error("Error attaching stream to element")}}else if(adapter.browserDetails.browser==="safari"||window.navigator.userAgent.match(/iPad/i)||window.navigator.userAgent.match(/iPhone/i)){element.src=URL.createObjectURL(stream)}else{element.srcObject=stream}};Janus.reattachMediaStream=function(to,from){if(adapter.browserDetails.browser==="chrome"){var chromever=adapter.browserDetails.version;if(chromever>=43){to.srcObject=from.srcObject}else if(typeof to.src!=="undefined"){to.src=from.src}}else if(adapter.browserDetails.browser==="safari"||window.navigator.userAgent.match(/iPad/i)||window.navigator.userAgent.match(/iPhone/i)){to.src=from.src}else{to.srcObject=from.srcObject}};var oldOBF=window.onbeforeunload;window.onbeforeunload=function(){Janus.log("Closing window");for(var s in Janus.sessions){if(Janus.sessions[s]!==null&&Janus.sessions[s]!==undefined&&Janus.sessions[s].destroyOnUnload){Janus.log("Destroying session "+s);Janus.sessions[s].destroy({asyncRequest:false})}}if(oldOBF&&typeof oldOBF=="function")oldOBF()};Janus.initDone=true;options.callback()}};Janus.isWebrtcSupported=function(){return window.RTCPeerConnection!==undefined&&window.RTCPeerConnection!==null&&navigator.getUserMedia!==undefined&&navigator.getUserMedia!==null};Janus.randomString=function(len){var charSet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";var randomString="";for(var i=0;i3){connected=false;gatewayCallbacks.error("Lost connection to the gateway (is it down?)");return}eventHandler()},dataType:"json"})}function handleEvent(json){retries=0;if(!websockets&&sessionId!==undefined&&sessionId!==null)setTimeout(eventHandler,200);if(!websockets&&$.isArray(json)){for(var i=0;i0){var local_audio_track=tracks[0];config.dtmfSender=config.pc.createDTMFSender(local_audio_track);Janus.log("Created DTMF Sender");config.dtmfSender.ontonechange=function(tone){Janus.debug("Sent DTMF tone: "+tone.tone)}}}if(config.dtmfSender===null||config.dtmfSender===undefined){Janus.warn("Invalid DTMF configuration");callbacks.error("Invalid DTMF configuration");return}}var dtmf=callbacks.dtmf;if(dtmf===null||dtmf===undefined){Janus.warn("Invalid DTMF parameters");callbacks.error("Invalid DTMF parameters");return}var tones=dtmf.tones;if(tones===null||tones===undefined){Janus.warn("Invalid DTMF string");callbacks.error("Invalid DTMF string");return}var duration=dtmf.duration;if(duration===null||duration===undefined)duration=500;var gap=dtmf.gap;if(gap===null||gap===undefined)gap=50;Janus.debug("Sending DTMF string "+tones+" (duration "+duration+"ms, gap "+gap+"ms)");config.dtmfSender.insertDTMF(tones,duration,gap)}function destroyHandle(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:jQuery.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:jQuery.noop;Janus.warn(callbacks);var asyncRequest=true;if(callbacks.asyncRequest!==undefined&&callbacks.asyncRequest!==null)asyncRequest=callbacks.asyncRequest===true;Janus.log("Destroying handle "+handleId+" (async="+asyncRequest+")");cleanupWebrtc(handleId);if(pluginHandles[handleId].detached){delete pluginHandles[handleId];callbacks.success();return}if(!connected){Janus.warn("Is the gateway down? (connected=false)");callbacks.error("Is the gateway down? (connected=false)");return}var request={janus:"detach",transaction:Janus.randomString(12)};if(token!==null&&token!==undefined)request["token"]=token;if(apisecret!==null&&apisecret!==undefined)request["apisecret"]=apisecret;if(websockets){request["session_id"]=sessionId;request["handle_id"]=handleId;ws.send(JSON.stringify(request));delete pluginHandles[handleId];callbacks.success();return}$.ajax({type:"POST",url:server+"/"+sessionId+"/"+handleId,async:asyncRequest,xhrFields:{withCredentials:withCredentials},cache:false,contentType:"application/json",data:JSON.stringify(request),success:function(json){Janus.log("Destroyed handle:");Janus.debug(json);if(json["janus"]!=="success"){Janus.error("Ooops: "+json["error"].code+" "+json["error"].reason)}delete pluginHandles[handleId];callbacks.success()},error:function(XMLHttpRequest,textStatus,errorThrown){Janus.error(textStatus+": "+errorThrown);delete pluginHandles[handleId];callbacks.success()},dataType:"json"})}function streamsDone(handleId,jsep,media,callbacks,stream){var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle") +;callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;Janus.debug("streamsDone:",stream);config.myStream=stream;var pc_config={iceServers:iceServers,iceTransportPolicy:iceTransportPolicy};var pc_constraints={optional:[{DtlsSrtpKeyAgreement:true}]};if(ipv6Support===true){pc_constraints.optional.push({googIPv6:true})}if(adapter.browserDetails.browser==="edge"){pc_config.bundlePolicy="max-bundle"}Janus.log("Creating PeerConnection");Janus.debug(pc_constraints);config.pc=new RTCPeerConnection(pc_config,pc_constraints);Janus.debug(config.pc);if(config.pc.getStats){config.volume.value=0;config.bitrate.value="0 kbits/sec"}Janus.log("Preparing local SDP and gathering candidates (trickle="+config.trickle+")");config.pc.oniceconnectionstatechange=function(e){if(config.pc)pluginHandle.iceState(config.pc.iceConnectionState)};config.pc.onicecandidate=function(event){if(event.candidate==null||adapter.browserDetails.browser==="edge"&&event.candidate.candidate.indexOf("endOfCandidates")>0){Janus.log("End of candidates.");config.iceDone=true;if(config.trickle===true){sendTrickleCandidate(handleId,{completed:true})}else{sendSDP(handleId,callbacks)}}else{var candidate={candidate:event.candidate.candidate,sdpMid:event.candidate.sdpMid,sdpMLineIndex:event.candidate.sdpMLineIndex};if(config.trickle===true){sendTrickleCandidate(handleId,candidate)}}};if(stream!==null&&stream!==undefined){Janus.log("Adding local stream");config.pc.addStream(stream);pluginHandle.onlocalstream(stream)}config.pc.ontrack=function(remoteStream){Janus.log("Handling Remote Stream");Janus.debug(remoteStream);config.remoteStream=remoteStream;pluginHandle.onremotestream(remoteStream.streams[0])};if(isDataEnabled(media)){Janus.log("Creating data channel");var onDataChannelMessage=function(event){Janus.log("Received message on data channel: "+event.data);pluginHandle.ondata(event.data)};var onDataChannelStateChange=function(){var dcState=config.dataChannel!==null?config.dataChannel.readyState:"null";Janus.log("State change on data channel: "+dcState);if(dcState==="open"){pluginHandle.ondataopen()}};var onDataChannelError=function(error){Janus.error("Got error on data channel:",error)};config.dataChannel=config.pc.createDataChannel("JanusDataChannel",{ordered:false});config.dataChannel.onmessage=onDataChannelMessage;config.dataChannel.onopen=onDataChannelStateChange;config.dataChannel.onclose=onDataChannelStateChange;config.dataChannel.onerror=onDataChannelError}if(jsep===null||jsep===undefined){createOffer(handleId,media,callbacks)}else{if(adapter.browserDetails.browser==="edge"){jsep.sdp+="a=end-of-candidates\r\n"}config.pc.setRemoteDescription(new RTCSessionDescription(jsep),function(){Janus.log("Remote description accepted!");createAnswer(handleId,media,callbacks)},callbacks.error)}}function prepareWebrtc(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:jQuery.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:webrtcError;var jsep=callbacks.jsep;var media=callbacks.media;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;if(config.pc!==undefined&&config.pc!==null){Janus.log("Updating existing media session");if(jsep===null||jsep===undefined){createOffer(handleId,media,callbacks)}else{if(adapter.browserDetails.browser==="edge"){jsep.sdp+="a=end-of-candidates\r\n"}config.pc.setRemoteDescription(new RTCSessionDescription(jsep),function(){Janus.log("Remote description accepted!");createAnswer(handleId,media,callbacks)},callbacks.error)}return}if(callbacks.stream!==null&&callbacks.stream!==undefined){var stream=callbacks.stream;Janus.log("MediaStream provided by the application");Janus.debug(stream);config.streamExternal=true;streamsDone(handleId,jsep,media,callbacks,stream);return}config.trickle=isTrickleEnabled(callbacks.trickle);if(isAudioSendEnabled(media)||isVideoSendEnabled(media)){var constraints={mandatory:{},optional:[]};pluginHandle.consentDialog(true);var audioSupport=isAudioSendEnabled(media);if(audioSupport===true&&media!=undefined&&media!=null){if(typeof media.audio==="object"){audioSupport=media.audio}}var videoSupport=isVideoSendEnabled(media);if(videoSupport===true&&media!=undefined&&media!=null){if(media.video&&media.video!="screen"&&media.video!="window"){var width=0;var height=0,maxHeight=0;if(media.video==="lowres"){height=240;maxHeight=240;width=320}else if(media.video==="lowres-16:9"){height=180;maxHeight=180;width=320}else if(media.video==="hires"||media.video==="hires-16:9"){height=720;maxHeight=720;width=1280;if(navigator.mozGetUserMedia){var firefoxVer=parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1],10);if(firefoxVer<38){Janus.warn(media.video+" unsupported, falling back to stdres (old Firefox)");height=480;maxHeight=480;width=640}}}else if(media.video==="stdres"){height=480;maxHeight=480;width=640}else if(media.video==="stdres-16:9"){height=360;maxHeight=360;width=640}else{Janus.log("Default video setting ("+media.video+") is stdres 4:3");height=480;maxHeight=480;width=640}Janus.log("Adding media constraint "+media.video);if(navigator.mozGetUserMedia){var firefoxVer=parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1],10);if(firefoxVer<38){videoSupport={require:["height","width"],height:{max:maxHeight,min:height},width:{max:width,min:width}}}else{videoSupport={height:{ideal:height},width:{ideal:width}}}}else{videoSupport={mandatory:{maxHeight:maxHeight,minHeight:height,maxWidth:width,minWidth:width},optional:[]}}if(typeof media.video==="object"){videoSupport=media.video}Janus.debug(videoSupport)}else if(media.video==="screen"||media.video==="window"){if(!media.screenshareFrameRate){media.screenshareFrameRate=3}if(window.location.protocol!=="https:"){Janus.warn("Screen sharing only works on HTTPS, try the https:// version of this page");pluginHandle.consentDialog(false);callbacks.error("Screen sharing only works on HTTPS, try the https:// version of this page");return}var cache={};function callbackUserMedia(error,stream){pluginHandle.consentDialog(false);if(error){callbacks.error({code:error.code,name:error.name,message:error.message})}else{streamsDone(handleId,jsep,media,callbacks,stream)}}function getScreenMedia(constraints,gsmCallback){Janus.log("Adding media constraint (screen capture)");Janus.debug(constraints);navigator.mediaDevices.getUserMedia(constraints).then(function(stream){gsmCallback(null,stream)}).catch(function(error){pluginHandle.consentDialog(false);gsmCallback(error)})}if(adapter.browserDetails.browser==="chrome"){var chromever=adapter.browserDetails.version;var maxver=33;if(window.navigator.userAgent.match("Linux"))maxver=35;if(chromever>=26&&chromever<=maxver){constraints={video:{mandatory:{googLeakyBucket:true,maxWidth:window.screen.width,maxHeight:window.screen.height,minFrameRate:media.screenshareFrameRate,maxFrameRate:media.screenshareFrameRate,chromeMediaSource:"screen"}},audio:isAudioSendEnabled(media)};getScreenMedia(constraints,callbackUserMedia)}else{var pending=window.setTimeout(function(){error=new Error("NavigatorUserMediaError");error.name='The required Chrome extension is not installed: click here to install it. (NOTE: this will need you to refresh the page)';pluginHandle.consentDialog(false);return callbacks.error(error)},1e3);cache[pending]=[callbackUserMedia,null];window.postMessage({type:"janusGetScreen",id:pending},"*")}}else if(window.navigator.userAgent.match("Firefox")){var ffver=parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1],10);if(ffver>=33){constraints={video:{mozMediaSource:media.video,mediaSource:media.video},audio:isAudioSendEnabled(media)};getScreenMedia(constraints,function(err,stream){callbackUserMedia(err,stream);if(!err){var lastTime=stream.currentTime;var polly=window.setInterval(function(){if(!stream)window.clearInterval(polly);if(stream.currentTime==lastTime){window.clearInterval(polly);if(stream.onended){stream.onended()}}lastTime=stream.currentTime},500)}})}else{var error=new Error("NavigatorUserMediaError");error.name="Your version of Firefox does not support screen sharing, please install Firefox 33 (or more recent versions)";pluginHandle.consentDialog(false);callbacks.error(error);return}}window.addEventListener("message",function(event){if(event.origin!=window.location.origin)return;if(event.data.type=="janusGotScreen"&&cache[event.data.id]){var data=cache[event.data.id];var callback=data[0];delete cache[event.data.id];if(event.data.sourceId===""){var error=new Error("NavigatorUserMediaError");error.name="You cancelled the request for permission, giving up...";pluginHandle.consentDialog(false);callbacks.error(error)}else{constraints={audio:isAudioSendEnabled(media),video:{mandatory:{chromeMediaSource:"desktop",maxWidth:window.screen.width,maxHeight:window.screen.height,minFrameRate:media.screenshareFrameRate,maxFrameRate:media.screenshareFrameRate},optional:[{googLeakyBucket:true},{googTemporalLayeredScreencast:true}]}};constraints.video.mandatory.chromeMediaSourceId=event.data.sourceId;getScreenMedia(constraints,callback)}}else if(event.data.type=="janusGetScreenPending"){window.clearTimeout(event.data.id)}});return}}if(media===null||media===undefined||media.video!=="screen"){navigator.mediaDevices.enumerateDevices().then(function(devices){var audioExist=devices.some(function(device){return device.kind==="audioinput"}),videoExist=devices.some(function(device){return device.kind==="videoinput"});var audioSend=isAudioSendEnabled(media);var videoSend=isVideoSendEnabled(media);var needAudioDevice=isAudioSendRequired(media);var needVideoDevice=isVideoSendRequired(media);if(audioSend||videoSend||needAudioDevice||needVideoDevice){var haveAudioDevice=audioSend?audioExist:false;var haveVideoDevice=videoSend?videoExist:false;if(!haveAudioDevice&&!haveVideoDevice){pluginHandle.consentDialog(false);callbacks.error("No capture device found");return false}else if(!haveAudioDevice&&needAudioDevice){pluginHandle.consentDialog(false);callbacks.error("Audio capture is required, but no capture device found");return false}else if(!haveVideoDevice&&needVideoDevice){pluginHandle.consentDialog(false);callbacks.error("Video capture is required, but no capture device found");return false}}navigator.mediaDevices.getUserMedia({audio:audioExist?audioSupport:false,video:videoExist?videoSupport:false}).then(function(stream){pluginHandle.consentDialog(false);streamsDone(handleId,jsep,media,callbacks,stream)}).catch(function(error){pluginHandle.consentDialog(false);callbacks.error({code:error.code,name:error.name,message:error.message})})}).catch(function(error){pluginHandle.consentDialog(false);callbacks.error("enumerateDevices error",error)})}}else{streamsDone(handleId,jsep,media,callbacks)}}function prepareWebrtcPeer(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:jQuery.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:webrtcError;var jsep=callbacks.jsep;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;if(jsep!==undefined&&jsep!==null){if(config.pc===null){Janus.warn("Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep");callbacks.error("No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep");return}if(adapter.browserDetails.browser==="edge"){jsep.sdp+="a=end-of-candidates\r\n"}config.pc.setRemoteDescription(new RTCSessionDescription(jsep),function(){Janus.log("Remote description accepted!");callbacks.success()},callbacks.error)}else{callbacks.error("Invalid JSEP")}}function createOffer(handleId,media,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:jQuery.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:jQuery.noop;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;Janus.log("Creating offer (iceDone="+config.iceDone+")");var mediaConstraints=null;if(adapter.browserDetails.browser=="firefox"||adapter.browserDetails.browser=="edge"){mediaConstraints={offerToReceiveAudio:isAudioRecvEnabled(media),offerToReceiveVideo:isVideoRecvEnabled(media)}}else{mediaConstraints={mandatory:{OfferToReceiveAudio:isAudioRecvEnabled(media),OfferToReceiveVideo:isVideoRecvEnabled(media)}}}Janus.debug(mediaConstraints);config.pc.createOffer(function(offer){Janus.debug(offer);if(config.mySdp===null||config.mySdp===undefined){Janus.log("Setting local description");config.mySdp=offer.sdp;config.pc.setLocalDescription(offer)}if(!config.iceDone&&!config.trickle){Janus.log("Waiting for all candidates...");return}if(config.sdpSent){Janus.log("Offer already sent, not sending it again");return}Janus.log("Offer ready");Janus.debug(callbacks);config.sdpSent=true;var jsep={type:offer.type,sdp:offer.sdp};callbacks.success(jsep)},callbacks.error,mediaConstraints)}function createAnswer(handleId,media,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:jQuery.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:jQuery.noop;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;Janus.log("Creating answer (iceDone="+config.iceDone+")");var mediaConstraints=null;if(adapter.browserDetails.browser=="firefox"||adapter.browserDetails.browser=="edge"){mediaConstraints={offerToReceiveAudio:isAudioRecvEnabled(media),offerToReceiveVideo:isVideoRecvEnabled(media)}}else{mediaConstraints={mandatory:{OfferToReceiveAudio:isAudioRecvEnabled(media),OfferToReceiveVideo:isVideoRecvEnabled(media)}}}Janus.debug(mediaConstraints);config.pc.createAnswer(function(answer){Janus.debug(answer);if(config.mySdp===null||config.mySdp===undefined){Janus.log("Setting local description");config.mySdp=answer.sdp;config.pc.setLocalDescription(answer)}if(!config.iceDone&&!config.trickle){Janus.log("Waiting for all candidates...");return}if(config.sdpSent){Janus.log("Answer already sent, not sending it again");return}config.sdpSent=true;var jsep={type:answer.type,sdp:answer.sdp};callbacks.success(jsep)},callbacks.error,mediaConstraints)}function sendSDP(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:jQuery.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:jQuery.noop;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle, not sending anything");return}var config=pluginHandle.webrtcStuff;Janus.log("Sending offer/answer SDP...");if(config.mySdp===null||config.mySdp===undefined){Janus.warn("Local SDP instance is invalid, not sending anything...");return}config.mySdp={type:config.pc.localDescription.type,sdp:config.pc.localDescription.sdp};if(config.sdpSent){Janus.log("Offer/Answer SDP already sent, not sending it again");return}if(config.trickle===false)config.mySdp["trickle"]=false;Janus.debug(callbacks);config.sdpSent=true;callbacks.success(config.mySdp)}function getVolume(handleId){var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");return 0}var config=pluginHandle.webrtcStuff;if(config.pc.getStats&&adapter.browserDetails.browser=="chrome"){if(config.remoteStream===null||config.remoteStream===undefined){Janus.warn("Remote stream unavailable");return 0}if(config.volume.timer===null||config.volume.timer===undefined){Janus.log("Starting volume monitor");config.volume.timer=setInterval(function(){config.pc.getStats(function(stats){var results=stats.result();for(var i=0;i=26&&chromever<=maxver){return true}return document.getElementById("janus-extension-installed")!==null}else{return true}};Janus.noop=function(){};Janus.init=function(options){options=options||{};options.callback=typeof options.callback=="function"?options.callback:Janus.noop;if(Janus.initDone===true){options.callback()}else{if(typeof console=="undefined"||typeof console.log=="undefined")console={log:function(){}};Janus.trace=Janus.noop;Janus.debug=Janus.noop;Janus.vdebug=Janus.noop;Janus.log=Janus.noop;Janus.warn=Janus.noop;Janus.error=Janus.noop;if(options.debug===true||options.debug==="all"){Janus.trace=console.trace.bind(console);Janus.debug=console.debug.bind(console);Janus.vdebug=console.debug.bind(console);Janus.log=console.log.bind(console);Janus.warn=console.warn.bind(console);Janus.error=console.error.bind(console)}else if(Array.isArray(options.debug)){for(var i in options.debug){var d=options.debug[i];switch(d){case"trace":Janus.trace=console.trace.bind(console);break;case"debug":Janus.debug=console.debug.bind(console);break;case"vdebug":Janus.vdebug=console.debug.bind(console);break;case"log":Janus.log=console.log.bind(console);break;case"warn":Janus.warn=console.warn.bind(console);break;case"error":Janus.error=console.error.bind(console);break;default:console.error("Unknown debugging option '"+d+"' (supported: 'trace', 'debug', 'vdebug', 'log', warn', 'error')");break}}}Janus.log("Initializing library");Janus.listDevices=function(callback){callback=typeof callback=="function"?callback:Janus.noop;if(navigator.mediaDevices){navigator.mediaDevices.getUserMedia({audio:true,video:true}).then(function(stream){navigator.mediaDevices.enumerateDevices().then(function(devices){Janus.debug(devices);callback(devices);try{stream.stop()}catch(e){}try{var tracks=stream.getTracks();for(var i in tracks){var mst=tracks[i];if(mst!==null&&mst!==undefined)mst.stop()}}catch(e){}})}).catch(function(err){Janus.error(err);callback([])})}else{Janus.warn("navigator.mediaDevices unavailable");callback([])}};Janus.attachMediaStream=function(element,stream){if(adapter.browserDetails.browser==="chrome"){var chromever=adapter.browserDetails.version;if(chromever>=43){element.srcObject=stream}else if(typeof element.src!=="undefined"){element.src=URL.createObjectURL(stream)}else{Janus.error("Error attaching stream to element")}}else if(adapter.browserDetails.browser==="safari"||window.navigator.userAgent.match(/iPad/i)||window.navigator.userAgent.match(/iPhone/i)){element.src=URL.createObjectURL(stream)}else{element.srcObject=stream}};Janus.reattachMediaStream=function(to,from){if(adapter.browserDetails.browser==="chrome"){var chromever=adapter.browserDetails.version;if(chromever>=43){to.srcObject=from.srcObject}else if(typeof to.src!=="undefined"){to.src=from.src}}else if(adapter.browserDetails.browser==="safari"||window.navigator.userAgent.match(/iPad/i)||window.navigator.userAgent.match(/iPhone/i)){to.src=from.src}else{to.srcObject=from.srcObject}};Janus.ajax=function(params){if(params===null||params===undefined)return;params.success=typeof params.success=="function"?params.success:Janus.noop;params.error=typeof params.error=="function"?params.error:Janus.noop;if(params.url===null||params.url===undefined){Janus.error("Missing url",params.url);params.error(null,-1,"Missing url");return}params.async=params.async===null||params.async===undefined?true:params.async===true;Janus.log(params);var XHR=new XMLHttpRequest;XHR.open(params.type,params.url,params.async);if(params.contentType!==null&¶ms.contentType!==undefined)XHR.setRequestHeader("Content-type",params.contentType);if(params.withCredentials!==null&¶ms.withCredentials!==undefined)XHR.withCredentials=params.withCredentials;if(params.async){XHR.onreadystatechange=function(){if(XHR.readyState!=4)return;if(XHR.status!==200){params.error(XHR,XHR.status!==0?XHR.status:"error","");return}try{params.success(JSON.parse(XHR.responseText))}catch(e){params.error(XHR,XHR.status,"Could not parse response, error: "+e+", text: "+XHR.responseText)}}}try{XHR.send(params.data);if(!params.async){if(XHR.status!==200){params.error(XHR,XHR.status!==0?XHR.status:"error","");return}try{params.success(JSON.parse(XHR.responseText))}catch(e){params.error(XHR,XHR.status,"Could not parse response, error: "+e+", text: "+XHR.responseText)}}}catch(e){params.error(XHR,"error","")}};var oldOBF=window.onbeforeunload;window.onbeforeunload=function(){Janus.log("Closing window");for(var s in Janus.sessions){if(Janus.sessions[s]!==null&&Janus.sessions[s]!==undefined&&Janus.sessions[s].destroyOnUnload){Janus.log("Destroying session "+s);Janus.sessions[s].destroy({asyncRequest:false})}}if(oldOBF&&typeof oldOBF=="function")oldOBF()};Janus.initDone=true;options.callback()}};Janus.isWebrtcSupported=function(){return window.RTCPeerConnection!==undefined&&window.RTCPeerConnection!==null&&navigator.getUserMedia!==undefined&&navigator.getUserMedia!==null};Janus.randomString=function(len){var charSet="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";var randomString="";for(var i=0;i3){connected=false;gatewayCallbacks.error("Lost connection to the gateway (is it down?)");return}eventHandler()},dataType:"json"})}function handleEvent(json){retries=0;if(!websockets&&sessionId!==undefined&&sessionId!==null)setTimeout(eventHandler,200);if(!websockets&&Array.isArray(json)){for(var i=0;i0){var local_audio_track=tracks[0];config.dtmfSender=config.pc.createDTMFSender(local_audio_track);Janus.log("Created DTMF Sender");config.dtmfSender.ontonechange=function(tone){Janus.debug("Sent DTMF tone: "+tone.tone)}}}if(config.dtmfSender===null||config.dtmfSender===undefined){Janus.warn("Invalid DTMF configuration");callbacks.error("Invalid DTMF configuration");return}}var dtmf=callbacks.dtmf;if(dtmf===null||dtmf===undefined){Janus.warn("Invalid DTMF parameters");callbacks.error("Invalid DTMF parameters");return}var tones=dtmf.tones;if(tones===null||tones===undefined){Janus.warn("Invalid DTMF string");callbacks.error("Invalid DTMF string");return}var duration=dtmf.duration;if(duration===null||duration===undefined)duration=500;var gap=dtmf.gap;if(gap===null||gap===undefined)gap=50;Janus.debug("Sending DTMF string "+tones+" (duration "+duration+"ms, gap "+gap+"ms)");config.dtmfSender.insertDTMF(tones,duration,gap)}function destroyHandle(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:Janus.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:Janus.noop;var asyncRequest=true;if(callbacks.asyncRequest!==undefined&&callbacks.asyncRequest!==null)asyncRequest=callbacks.asyncRequest===true;Janus.log("Destroying handle "+handleId+" (sync="+asyncRequest+")");cleanupWebrtc(handleId);if(pluginHandles[handleId].detached){ +delete pluginHandles[handleId];callbacks.success();return}if(!connected){Janus.warn("Is the gateway down? (connected=false)");callbacks.error("Is the gateway down? (connected=false)");return}var request={janus:"detach",transaction:Janus.randomString(12)};if(token!==null&&token!==undefined)request["token"]=token;if(apisecret!==null&&apisecret!==undefined)request["apisecret"]=apisecret;if(websockets){request["session_id"]=sessionId;request["handle_id"]=handleId;ws.send(JSON.stringify(request));delete pluginHandles[handleId];callbacks.success();return}Janus.ajax({type:"POST",url:server+"/"+sessionId+"/"+handleId,async:asyncRequest,withCredentials:withCredentials,cache:false,contentType:"application/json",data:JSON.stringify(request),success:function(json){Janus.log("Destroyed handle:");Janus.debug(json);if(json["janus"]!=="success"){Janus.error("Ooops: "+json["error"].code+" "+json["error"].reason)}delete pluginHandles[handleId];callbacks.success()},error:function(XMLHttpRequest,textStatus,errorThrown){Janus.error(textStatus+": "+errorThrown);delete pluginHandles[handleId];callbacks.success()},dataType:"json"})}function streamsDone(handleId,jsep,media,callbacks,stream){var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;Janus.debug("streamsDone:",stream);config.myStream=stream;var pc_config={iceServers:iceServers,iceTransportPolicy:iceTransportPolicy};var pc_constraints={optional:[{DtlsSrtpKeyAgreement:true}]};if(ipv6Support===true){pc_constraints.optional.push({googIPv6:true})}if(adapter.browserDetails.browser==="edge"){pc_config.bundlePolicy="max-bundle"}Janus.log("Creating PeerConnection");Janus.debug(pc_constraints);config.pc=new RTCPeerConnection(pc_config,pc_constraints);Janus.debug(config.pc);if(config.pc.getStats){config.volume.value=0;config.bitrate.value="0 kbits/sec"}Janus.log("Preparing local SDP and gathering candidates (trickle="+config.trickle+")");config.pc.oniceconnectionstatechange=function(e){if(config.pc)pluginHandle.iceState(config.pc.iceConnectionState)};config.pc.onicecandidate=function(event){if(event.candidate==null||adapter.browserDetails.browser==="edge"&&event.candidate.candidate.indexOf("endOfCandidates")>0){Janus.log("End of candidates.");config.iceDone=true;if(config.trickle===true){sendTrickleCandidate(handleId,{completed:true})}else{sendSDP(handleId,callbacks)}}else{var candidate={candidate:event.candidate.candidate,sdpMid:event.candidate.sdpMid,sdpMLineIndex:event.candidate.sdpMLineIndex};if(config.trickle===true){sendTrickleCandidate(handleId,candidate)}}};if(stream!==null&&stream!==undefined){Janus.log("Adding local stream");config.pc.addStream(stream);pluginHandle.onlocalstream(stream)}config.pc.ontrack=function(remoteStream){Janus.log("Handling Remote Stream");Janus.debug(remoteStream);config.remoteStream=remoteStream;pluginHandle.onremotestream(remoteStream.streams[0])};if(isDataEnabled(media)){Janus.log("Creating data channel");var onDataChannelMessage=function(event){Janus.log("Received message on data channel: "+event.data);pluginHandle.ondata(event.data)};var onDataChannelStateChange=function(){var dcState=config.dataChannel!==null?config.dataChannel.readyState:"null";Janus.log("State change on data channel: "+dcState);if(dcState==="open"){pluginHandle.ondataopen()}};var onDataChannelError=function(error){Janus.error("Got error on data channel:",error)};config.dataChannel=config.pc.createDataChannel("JanusDataChannel",{ordered:false});config.dataChannel.onmessage=onDataChannelMessage;config.dataChannel.onopen=onDataChannelStateChange;config.dataChannel.onclose=onDataChannelStateChange;config.dataChannel.onerror=onDataChannelError}if(jsep===null||jsep===undefined){createOffer(handleId,media,callbacks)}else{if(adapter.browserDetails.browser==="edge"){jsep.sdp+="a=end-of-candidates\r\n"}config.pc.setRemoteDescription(new RTCSessionDescription(jsep),function(){Janus.log("Remote description accepted!");createAnswer(handleId,media,callbacks)},callbacks.error)}}function prepareWebrtc(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:Janus.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:webrtcError;var jsep=callbacks.jsep;var media=callbacks.media;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;if(config.pc!==undefined&&config.pc!==null){Janus.log("Updating existing media session");if(jsep===null||jsep===undefined){createOffer(handleId,media,callbacks)}else{if(adapter.browserDetails.browser==="edge"){jsep.sdp+="a=end-of-candidates\r\n"}config.pc.setRemoteDescription(new RTCSessionDescription(jsep),function(){Janus.log("Remote description accepted!");createAnswer(handleId,media,callbacks)},callbacks.error)}return}if(callbacks.stream!==null&&callbacks.stream!==undefined){var stream=callbacks.stream;Janus.log("MediaStream provided by the application");Janus.debug(stream);config.streamExternal=true;streamsDone(handleId,jsep,media,callbacks,stream);return}config.trickle=isTrickleEnabled(callbacks.trickle);if(isAudioSendEnabled(media)||isVideoSendEnabled(media)){var constraints={mandatory:{},optional:[]};pluginHandle.consentDialog(true);var audioSupport=isAudioSendEnabled(media);if(audioSupport===true&&media!=undefined&&media!=null){if(typeof media.audio==="object"){audioSupport=media.audio}}var videoSupport=isVideoSendEnabled(media);if(videoSupport===true&&media!=undefined&&media!=null){if(media.video&&media.video!="screen"&&media.video!="window"){var width=0;var height=0,maxHeight=0;if(media.video==="lowres"){height=240;maxHeight=240;width=320}else if(media.video==="lowres-16:9"){height=180;maxHeight=180;width=320}else if(media.video==="hires"||media.video==="hires-16:9"){height=720;maxHeight=720;width=1280;if(navigator.mozGetUserMedia){var firefoxVer=parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1],10);if(firefoxVer<38){Janus.warn(media.video+" unsupported, falling back to stdres (old Firefox)");height=480;maxHeight=480;width=640}}}else if(media.video==="stdres"){height=480;maxHeight=480;width=640}else if(media.video==="stdres-16:9"){height=360;maxHeight=360;width=640}else{Janus.log("Default video setting ("+media.video+") is stdres 4:3");height=480;maxHeight=480;width=640}Janus.log("Adding media constraint "+media.video);if(navigator.mozGetUserMedia){var firefoxVer=parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1],10);if(firefoxVer<38){videoSupport={require:["height","width"],height:{max:maxHeight,min:height},width:{max:width,min:width}}}else{videoSupport={height:{ideal:height},width:{ideal:width}}}}else{videoSupport={mandatory:{maxHeight:maxHeight,minHeight:height,maxWidth:width,minWidth:width},optional:[]}}if(typeof media.video==="object"){videoSupport=media.video}Janus.debug(videoSupport)}else if(media.video==="screen"||media.video==="window"){if(!media.screenshareFrameRate){media.screenshareFrameRate=3}if(window.location.protocol!=="https:"){Janus.warn("Screen sharing only works on HTTPS, try the https:// version of this page");pluginHandle.consentDialog(false);callbacks.error("Screen sharing only works on HTTPS, try the https:// version of this page");return}var cache={};function callbackUserMedia(error,stream){pluginHandle.consentDialog(false);if(error){callbacks.error({code:error.code,name:error.name,message:error.message})}else{streamsDone(handleId,jsep,media,callbacks,stream)}}function getScreenMedia(constraints,gsmCallback){Janus.log("Adding media constraint (screen capture)");Janus.debug(constraints);navigator.mediaDevices.getUserMedia(constraints).then(function(stream){gsmCallback(null,stream)}).catch(function(error){pluginHandle.consentDialog(false);gsmCallback(error)})}if(adapter.browserDetails.browser==="chrome"){var chromever=adapter.browserDetails.version;var maxver=33;if(window.navigator.userAgent.match("Linux"))maxver=35;if(chromever>=26&&chromever<=maxver){constraints={video:{mandatory:{googLeakyBucket:true,maxWidth:window.screen.width,maxHeight:window.screen.height,minFrameRate:media.screenshareFrameRate,maxFrameRate:media.screenshareFrameRate,chromeMediaSource:"screen"}},audio:isAudioSendEnabled(media)};getScreenMedia(constraints,callbackUserMedia)}else{var pending=window.setTimeout(function(){error=new Error("NavigatorUserMediaError");error.name='The required Chrome extension is not installed: click here to install it. (NOTE: this will need you to refresh the page)';pluginHandle.consentDialog(false);return callbacks.error(error)},1e3);cache[pending]=[callbackUserMedia,null];window.postMessage({type:"janusGetScreen",id:pending},"*")}}else if(window.navigator.userAgent.match("Firefox")){var ffver=parseInt(window.navigator.userAgent.match(/Firefox\/(.*)/)[1],10);if(ffver>=33){constraints={video:{mozMediaSource:media.video,mediaSource:media.video},audio:isAudioSendEnabled(media)};getScreenMedia(constraints,function(err,stream){callbackUserMedia(err,stream);if(!err){var lastTime=stream.currentTime;var polly=window.setInterval(function(){if(!stream)window.clearInterval(polly);if(stream.currentTime==lastTime){window.clearInterval(polly);if(stream.onended){stream.onended()}}lastTime=stream.currentTime},500)}})}else{var error=new Error("NavigatorUserMediaError");error.name="Your version of Firefox does not support screen sharing, please install Firefox 33 (or more recent versions)";pluginHandle.consentDialog(false);callbacks.error(error);return}}window.addEventListener("message",function(event){if(event.origin!=window.location.origin)return;if(event.data.type=="janusGotScreen"&&cache[event.data.id]){var data=cache[event.data.id];var callback=data[0];delete cache[event.data.id];if(event.data.sourceId===""){var error=new Error("NavigatorUserMediaError");error.name="You cancelled the request for permission, giving up...";pluginHandle.consentDialog(false);callbacks.error(error)}else{constraints={audio:isAudioSendEnabled(media),video:{mandatory:{chromeMediaSource:"desktop",maxWidth:window.screen.width,maxHeight:window.screen.height,minFrameRate:media.screenshareFrameRate,maxFrameRate:media.screenshareFrameRate},optional:[{googLeakyBucket:true},{googTemporalLayeredScreencast:true}]}};constraints.video.mandatory.chromeMediaSourceId=event.data.sourceId;getScreenMedia(constraints,callback)}}else if(event.data.type=="janusGetScreenPending"){window.clearTimeout(event.data.id)}});return}}if(media===null||media===undefined||media.video!=="screen"){navigator.mediaDevices.enumerateDevices().then(function(devices){var audioExist=devices.some(function(device){return device.kind==="audioinput"}),videoExist=devices.some(function(device){return device.kind==="videoinput"});var audioSend=isAudioSendEnabled(media);var videoSend=isVideoSendEnabled(media);var needAudioDevice=isAudioSendRequired(media);var needVideoDevice=isVideoSendRequired(media);if(audioSend||videoSend||needAudioDevice||needVideoDevice){var haveAudioDevice=audioSend?audioExist:false;var haveVideoDevice=videoSend?videoExist:false;if(!haveAudioDevice&&!haveVideoDevice){pluginHandle.consentDialog(false);callbacks.error("No capture device found");return false}else if(!haveAudioDevice&&needAudioDevice){pluginHandle.consentDialog(false);callbacks.error("Audio capture is required, but no capture device found");return false}else if(!haveVideoDevice&&needVideoDevice){pluginHandle.consentDialog(false);callbacks.error("Video capture is required, but no capture device found");return false}}navigator.mediaDevices.getUserMedia({audio:audioExist?audioSupport:false,video:videoExist?videoSupport:false}).then(function(stream){pluginHandle.consentDialog(false);streamsDone(handleId,jsep,media,callbacks,stream)}).catch(function(error){pluginHandle.consentDialog(false);callbacks.error({code:error.code,name:error.name,message:error.message})})}).catch(function(error){pluginHandle.consentDialog(false);callbacks.error("enumerateDevices error",error)})}}else{streamsDone(handleId,jsep,media,callbacks)}}function prepareWebrtcPeer(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:Janus.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:webrtcError;var jsep=callbacks.jsep;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;if(jsep!==undefined&&jsep!==null){if(config.pc===null){Janus.warn("Wait, no PeerConnection?? if this is an answer, use createAnswer and not handleRemoteJsep");callbacks.error("No PeerConnection: if this is an answer, use createAnswer and not handleRemoteJsep");return}if(adapter.browserDetails.browser==="edge"){jsep.sdp+="a=end-of-candidates\r\n"}config.pc.setRemoteDescription(new RTCSessionDescription(jsep),function(){Janus.log("Remote description accepted!");callbacks.success()},callbacks.error)}else{callbacks.error("Invalid JSEP")}}function createOffer(handleId,media,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:Janus.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:Janus.noop;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;Janus.log("Creating offer (iceDone="+config.iceDone+")");var mediaConstraints=null;if(adapter.browserDetails.browser=="firefox"||adapter.browserDetails.browser=="edge"){mediaConstraints={offerToReceiveAudio:isAudioRecvEnabled(media),offerToReceiveVideo:isVideoRecvEnabled(media)}}else{mediaConstraints={mandatory:{OfferToReceiveAudio:isAudioRecvEnabled(media),OfferToReceiveVideo:isVideoRecvEnabled(media)}}}Janus.debug(mediaConstraints);config.pc.createOffer(function(offer){Janus.debug(offer);if(config.mySdp===null||config.mySdp===undefined){Janus.log("Setting local description");config.mySdp=offer.sdp;config.pc.setLocalDescription(offer)}if(!config.iceDone&&!config.trickle){Janus.log("Waiting for all candidates...");return}if(config.sdpSent){Janus.log("Offer already sent, not sending it again");return}Janus.log("Offer ready");Janus.debug(callbacks);config.sdpSent=true;var jsep={type:offer.type,sdp:offer.sdp};callbacks.success(jsep)},callbacks.error,mediaConstraints)}function createAnswer(handleId,media,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:Janus.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:Janus.noop;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");callbacks.error("Invalid handle");return}var config=pluginHandle.webrtcStuff;Janus.log("Creating answer (iceDone="+config.iceDone+")");var mediaConstraints=null;if(adapter.browserDetails.browser=="firefox"||adapter.browserDetails.browser=="edge"){mediaConstraints={offerToReceiveAudio:isAudioRecvEnabled(media),offerToReceiveVideo:isVideoRecvEnabled(media)}}else{mediaConstraints={mandatory:{OfferToReceiveAudio:isAudioRecvEnabled(media),OfferToReceiveVideo:isVideoRecvEnabled(media)}}}Janus.debug(mediaConstraints);config.pc.createAnswer(function(answer){Janus.debug(answer);if(config.mySdp===null||config.mySdp===undefined){Janus.log("Setting local description");config.mySdp=answer.sdp;config.pc.setLocalDescription(answer)}if(!config.iceDone&&!config.trickle){Janus.log("Waiting for all candidates...");return}if(config.sdpSent){Janus.log("Answer already sent, not sending it again");return}config.sdpSent=true;var jsep={type:answer.type,sdp:answer.sdp};callbacks.success(jsep)},callbacks.error,mediaConstraints)}function sendSDP(handleId,callbacks){callbacks=callbacks||{};callbacks.success=typeof callbacks.success=="function"?callbacks.success:Janus.noop;callbacks.error=typeof callbacks.error=="function"?callbacks.error:Janus.noop;var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle, not sending anything");return}var config=pluginHandle.webrtcStuff;Janus.log("Sending offer/answer SDP...");if(config.mySdp===null||config.mySdp===undefined){Janus.warn("Local SDP instance is invalid, not sending anything...");return}config.mySdp={type:config.pc.localDescription.type,sdp:config.pc.localDescription.sdp};if(config.sdpSent){Janus.log("Offer/Answer SDP already sent, not sending it again");return}if(config.trickle===false)config.mySdp["trickle"]=false;Janus.debug(callbacks);config.sdpSent=true;callbacks.success(config.mySdp)}function getVolume(handleId){var pluginHandle=pluginHandles[handleId];if(pluginHandle===null||pluginHandle===undefined||pluginHandle.webrtcStuff===null||pluginHandle.webrtcStuff===undefined){Janus.warn("Invalid handle");return 0}var config=pluginHandle.webrtcStuff;if(config.pc.getStats&&adapter.browserDetails.browser=="chrome"){if(config.remoteStream===null||config.remoteStream===undefined){Janus.warn("Remote stream unavailable");return 0}if(config.volume.timer===null||config.volume.timer===undefined){Janus.log("Starting volume monitor");config.volume.timer=setInterval(function(){config.pc.getStats(function(stats){var results=stats.result();for(var i=0;i