2014-12-01 21:39:18 +00:00
2015-09-17 16:12:34 +00:00
( function ( $ ) { function findLine ( sdpLines , prefix , substr ) { return findLineInRange ( sdpLines , 0 , - 1 , prefix , substr ) ; }
2014-12-06 17:40:44 +00:00
function findLineInRange ( sdpLines , startLine , endLine , prefix , substr ) { var realEndLine = ( endLine != - 1 ) ? endLine : sdpLines . length ; for ( var i = startLine ; i < realEndLine ; ++ i ) { if ( sdpLines [ i ] . indexOf ( prefix ) === 0 ) { if ( ! substr || sdpLines [ i ] . toLowerCase ( ) . indexOf ( substr . toLowerCase ( ) ) !== - 1 ) { return i ; } } }
return null ; }
function getCodecPayloadType ( sdpLine ) { var pattern = new RegExp ( 'a=rtpmap:(\\d+) \\w+\\/\\d+' ) ; var result = sdpLine . match ( pattern ) ; return ( result && result . length == 2 ) ? result [ 1 ] : null ; }
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 ( ' ' ) ; }
2015-09-17 18:29:47 +00:00
$ . 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 , } } ; }
2015-02-20 23:19:09 +00:00
if ( self . options . useVideo ) { self . options . useVideo . style . display = 'none' ; }
2015-09-17 18:29:47 +00:00
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 ; } }
2015-02-20 23:19:09 +00:00
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 ; }
2015-09-22 20:10:29 +00:00
var sdpLines = sdp . split ( '\r\n' ) ; var opusIndex = findLine ( sdpLines , 'a=rtpmap' , 'opus/48000' ) , opusPayload ; if ( ! opusIndex ) { return sdp ; } else { opusPayload = getCodecPayloadType ( sdpLines [ opusIndex ] ) ; }
2015-09-22 20:31:09 +00:00
var fmtpLineIndex = findLine ( sdpLines , 'a=fmtp:' + opusPayload . toString ( ) ) ; if ( fmtpLineIndex === null ) { sdpLines [ opusIndex ] = sdpLines [ opusIndex ] + '\r\na=fmtp:' + opusPayload . toString ( ) + " stereo=1; sprop-stereo=1" } else { sdpLines [ fmtpLineIndex ] = sdpLines [ fmtpLineIndex ] . concat ( '; stereo=1; sprop-stereo=1' ) ; }
2015-09-22 20:10:29 +00:00
sdp = sdpLines . join ( '\r\n' ) ; return sdp ; } ; function setCompat ( ) { $ . FSRTC . moz = ! ! navigator . mozGetUserMedia ; if ( ! navigator . getUserMedia ) { navigator . getUserMedia = navigator . mozGetUserMedia || navigator . webkitGetUserMedia || navigator . msGetUserMedia ; } }
2014-12-06 17:40:44 +00:00
function checkCompat ( ) { if ( ! navigator . getUserMedia ) { alert ( 'This application cannot function in this browser.' ) ; return false ; }
return true ; }
2015-03-24 17:49:06 +00:00
function onStreamError ( self , e ) { console . log ( 'There has been a problem retrieving the streams - did you allow access? Check Device Resolution' , e ) ; doCallback ( self , "onError" , e ) ; }
2015-01-24 09:13:44 +00:00
function onStreamSuccess ( self , stream ) { console . log ( "Stream Success" ) ; doCallback ( self , "onStream" , stream ) ; }
2014-12-06 17:40:44 +00:00
function onICE ( self , candidate ) { self . mediaData . candidate = candidate ; self . mediaData . candidateList . push ( self . mediaData . candidate ) ; doCallback ( self , "onICE" ) ; }
function doCallback ( self , func , arg ) { if ( func in self . options . callbacks ) { self . options . callbacks [ func ] ( self , arg ) ; } }
function onICEComplete ( self , candidate ) { console . log ( "ICE Complete" ) ; doCallback ( self , "onICEComplete" ) ; }
function onChannelError ( self , e ) { console . error ( "Channel Error" , e ) ; doCallback ( self , "onError" , e ) ; }
function onICESDP ( self , sdp ) { self . mediaData . SDP = self . stereoHack ( sdp . sdp ) ; console . log ( "ICE SDP" ) ; doCallback ( self , "onICESDP" ) ; }
function onAnswerSDP ( self , sdp ) { self . answer . SDP = self . stereoHack ( sdp . sdp ) ; console . log ( "ICE ANSWER SDP" ) ; doCallback ( self , "onAnswerSDP" , self . answer . SDP ) ; }
function onMessage ( self , msg ) { console . log ( "Message" ) ; doCallback ( self , "onICESDP" , msg ) ; }
2015-02-20 23:19:09 +00:00
function onRemoteStream ( self , stream ) { if ( self . options . useVideo ) { self . options . useVideo . style . display = 'block' ; }
var element = self . options . useAudio ; console . log ( "REMOTE STREAM" , stream , element ) ; if ( typeof element . srcObject !== 'undefined' ) { element . srcObject = stream ; } else if ( typeof element . mozSrcObject !== 'undefined' ) { element . mozSrcObject = stream ; } else if ( typeof element . src !== 'undefined' ) { element . src = URL . createObjectURL ( stream ) ; } else { console . error ( 'Error attaching stream to element.' ) ; }
2014-12-06 17:40:44 +00:00
self . options . useAudio . play ( ) ; self . remoteStream = stream ; }
function onOfferSDP ( self , sdp ) { self . mediaData . SDP = self . stereoHack ( sdp . sdp ) ; console . log ( "Offer SDP" ) ; doCallback ( self , "onOfferSDP" ) ; }
2015-09-22 16:21:15 +00:00
$ . FSRTC . prototype . answer = function ( sdp , onSuccess , onError ) { this . peer . addAnswerSDP ( { type : "answer" , sdp : sdp } , onSuccess , onError ) ; } ; $ . FSRTC . prototype . stopPeer = function ( ) { if ( self . peer ) { console . log ( "stopping peer" ) ; self . peer . stop ( ) ; } }
$ . FSRTC . prototype . stop = function ( ) { var self = this ; if ( self . options . useVideo ) { self . options . useVideo . style . display = 'none' ; if ( moz ) { self . options . useVideo [ 'mozSrcObject' ] = null ; } else { self . options . useVideo [ 'src' ] = '' ; } }
2014-12-06 17:40:44 +00:00
if ( self . localStream ) { self . localStream . stop ( ) ; self . localStream = null ; }
2015-08-28 19:11:03 +00:00
if ( self . options . localVideo ) { self . options . localVideo . style . display = 'none' ; if ( moz ) { self . options . localVideo [ 'mozSrcObject' ] = null ; } else { self . options . localVideo [ 'src' ] = '' ; } }
2015-01-24 09:13:44 +00:00
if ( self . options . localVideoStream ) { self . options . localVideoStream . stop ( ) ; }
2015-03-24 18:39:51 +00:00
if ( self . peer ) { console . log ( "stopping peer" ) ; self . peer . stop ( ) ; } } ; $ . FSRTC . prototype . getMute = function ( ) { var self = this ; return self . enabled ; }
$ . 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 ; }
2015-08-28 14:42:37 +00:00
$ . 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 ) ; }
2014-12-06 17:40:44 +00:00
function onError ( e ) { onStreamError ( self , e ) ; }
2015-09-17 18:29:47 +00:00
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!" ) ; } } ) ; }
2015-03-04 21:13:35 +00:00
getUserMedia ( { constraints : { audio : mediaParams . audio , video : mediaParams . video } , video : mediaParams . useVideo , onsuccess : onSuccess , onerror : onError } ) ; } ; function getMediaParams ( obj ) { var audio ; if ( obj . options . videoParams && obj . options . screenShare ) { console . error ( "SCREEN SHARE" ) ; audio = false ; } else { audio = { mandatory : obj . options . audioParams , optional : [ ] } ; if ( obj . options . useMic !== "any" ) { audio . optional = [ { sourceId : obj . options . useMic } ] } }
2015-02-19 23:08:36 +00:00
if ( obj . options . useVideo && obj . options . localVideo ) { getUserMedia ( { constraints : { audio : false , video : { mandatory : obj . options . videoParams , optional : [ ] } , } , localVideo : obj . options . localVideo , onsuccess : function ( e ) { self . options . localVideoStream = e ; console . log ( "local video ready" ) ; } , onerror : function ( e ) { console . error ( "local video error!" ) ; } } ) ; }
2015-06-30 19:46:57 +00:00
var video = { } ; var bestFrameRate = obj . options . videoParams . vertoBestFrameRate ; delete obj . options . videoParams . vertoBestFrameRate ; if ( window . moz ) { video = obj . options . videoParams ; if ( ! video . width ) video . width = video . minWidth ; if ( ! video . height ) video . height = video . minHeight ; if ( ! video . frameRate ) video . frameRate = video . minFrameRate ; } else { video = { mandatory : obj . options . videoParams , optional : [ ] } }
2015-07-21 15:59:17 +00:00
var useVideo = obj . options . useVideo ; if ( useVideo && obj . options . useCamera && obj . options . useCamera !== "none" ) { if ( ! video . optional ) { video . optional = [ ] ; }
if ( obj . options . useCamera !== "any" ) { video . optional . push ( { sourceId : obj . options . useCamera } ) ; }
2015-09-17 18:29:47 +00:00
if ( bestFrameRate && ! window . moz ) { video . optional . push ( { minFrameRate : bestFrameRate } ) ; } } else { video = false ; useVideo = false ; }
2015-02-19 23:08:36 +00:00
return { audio : audio , video : video , useVideo : useVideo } ; }
2015-03-04 21:13:35 +00:00
$ . FSRTC . prototype . call = function ( profile ) { checkCompat ( ) ; var self = this ; var screen = false ; self . type = "offer" ; if ( self . options . videoParams && self . options . screenShare ) { screen = true ; }
2015-09-17 18:29:47 +00:00
function onSuccess ( stream ) { self . localStream = stream ; if ( screen ) { if ( moz ) { self . constraints . OfferToReceiveVideo = false ; } else { self . constraints . mandatory . OfferToReceiveVideo = false ; } }
2015-08-27 21:14:45 +00:00
self . peer = RTCPeerConnection ( { type : self . type , attachStream : self . localStream , onICE : function ( candidate ) { return onICE ( self , candidate ) ; } , onICEComplete : function ( ) { return onICEComplete ( self ) ; } , onRemoteStream : screen ? function ( stream ) { } : function ( stream ) { return onRemoteStream ( self , stream ) ; } , onOfferSDP : function ( sdp ) { return onOfferSDP ( self , sdp ) ; } , onICESDP : function ( sdp ) { return onICESDP ( self , sdp ) ; } , onChannelError : function ( e ) { return onChannelError ( self , e ) ; } , constraints : self . constraints , iceServers : self . options . iceServers , } ) ; onStreamSuccess ( self , stream ) ; }
2014-12-06 17:40:44 +00:00
function onError ( e ) { onStreamError ( self , e ) ; }
2015-09-17 18:29:47 +00:00
var mediaParams = getMediaParams ( self ) ; console . log ( "Audio constraints" , mediaParams . audio ) ; console . log ( "Video constraints" , mediaParams . video ) ; getUserMedia ( { constraints : { audio : mediaParams . audio , video : mediaParams . video } , video : mediaParams . useVideo , onsuccess : onSuccess , onerror : onError } ) ; } ; window . moz = ! ! navigator . mozGetUserMedia ; function RTCPeerConnection ( options ) { var gathering = false , done = false ; var w = window , PeerConnection = w . mozRTCPeerConnection || w . webkitRTCPeerConnection , SessionDescription = w . mozRTCSessionDescription || w . RTCSessionDescription , IceCandidate = w . mozRTCIceCandidate || w . RTCIceCandidate ; var STUN = { url : ! moz ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121' } ; var iceServers = null ; if ( options . iceServers ) { var tmp = options . iceServers ; if ( typeof ( tmp ) === "boolean" ) { tmp = null ; }
2015-01-07 07:43:49 +00:00
if ( tmp && ! ( typeof ( tmp ) == "object" && tmp . constructor === Array ) ) { console . warn ( "iceServers must be an array, reverting to default ice servers" ) ; tmp = null ; }
2015-06-15 20:48:58 +00:00
iceServers = { iceServers : tmp || [ STUN ] } ; if ( ! moz && ! tmp ) { iceServers . iceServers = [ STUN ] ; } }
2014-12-06 17:40:44 +00:00
var optional = { optional : [ ] } ; if ( ! moz ) { optional . optional = [ { DtlsSrtpKeyAgreement : true } , { RtpDataChannels : options . onChannelMessage ? true : false } ] ; }
2015-09-17 16:12:34 +00:00
var peer = new PeerConnection ( iceServers , optional ) ; openOffererChannel ( ) ; var x = 0 ; function ice _handler ( ) { done = true ; gathering = null ; if ( options . onICEComplete ) { options . onICEComplete ( ) ; }
if ( options . type == "offer" ) { if ( ( ! moz || ( ! options . sentICESDP && peer . localDescription . sdp . match ( /a=candidate/ ) ) && ! x && options . onICESDP ) ) { options . onICESDP ( peer . localDescription ) ; } } else { if ( ! x && options . onICESDP ) { options . onICESDP ( peer . localDescription ) ; } } }
peer . onicecandidate = function ( event ) { if ( done ) { return ; }
if ( ! gathering ) { gathering = setTimeout ( ice _handler , 1000 ) ; }
if ( event ) { if ( event . candidate ) { options . onICE ( event . candidate ) ; } } else { done = true ; if ( gathering ) { clearTimeout ( gathering ) ; gathering = null ; }
ice _handler ( ) ; } } ; if ( options . attachStream ) peer . addStream ( options . attachStream ) ; if ( options . attachStreams && options . attachStream . length ) { var streams = options . attachStreams ; for ( var i = 0 ; i < streams . length ; i ++ ) { peer . addStream ( streams [ i ] ) ; } }
2014-12-06 17:40:44 +00:00
peer . onaddstream = function ( event ) { var remoteMediaStream = event . stream ; remoteMediaStream . onended = function ( ) { if ( options . onRemoteStreamEnded ) options . onRemoteStreamEnded ( remoteMediaStream ) ; } ; if ( options . onRemoteStream ) options . onRemoteStream ( remoteMediaStream ) ; } ; var constraints = options . constraints || { offerToReceiveAudio : true , offerToReceiveVideo : true } ; function createOffer ( ) { if ( ! options . onOfferSDP ) return ; peer . createOffer ( function ( sessionDescription ) { sessionDescription . sdp = serializeSdp ( sessionDescription . sdp ) ; peer . setLocalDescription ( sessionDescription ) ; options . onOfferSDP ( sessionDescription ) ; if ( moz && options . onICESDP && sessionDescription . sdp . match ( /a=candidate/ ) ) { options . onICESDP ( sessionDescription ) ; options . sentICESDP = 1 ; } } , onSdpError , constraints ) ; }
function createAnswer ( ) { if ( options . type != "answer" ) return ; peer . setRemoteDescription ( new SessionDescription ( options . offerSDP ) , onSdpSuccess , onSdpError ) ; peer . createAnswer ( function ( sessionDescription ) { sessionDescription . sdp = serializeSdp ( sessionDescription . sdp ) ; peer . setLocalDescription ( sessionDescription ) ; if ( options . onAnswerSDP ) { options . onAnswerSDP ( sessionDescription ) ; } } , onSdpError , constraints ) ; }
if ( ( options . onChannelMessage && ! moz ) || ! options . onChannelMessage ) { createOffer ( ) ; createAnswer ( ) ; }
function setBandwidth ( sdp ) { sdp = sdp . replace ( /b=AS([^\r\n]+\r\n)/g , '' ) ; sdp = sdp . replace ( /a=mid:data\r\n/g , 'a=mid:data\r\nb=AS:1638400\r\n' ) ; return sdp ; }
function getInteropSDP ( sdp ) { var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . split ( '' ) , extractedChars = '' ; function getChars ( ) { extractedChars += chars [ parseInt ( Math . random ( ) * 40 ) ] || '' ; if ( extractedChars . length < 40 ) getChars ( ) ; return extractedChars ; }
if ( options . onAnswerSDP ) sdp = sdp . replace ( /(a=crypto:0 AES_CM_128_HMAC_SHA1_32)(.*?)(\r\n)/g , '' ) ; var inline = getChars ( ) + '\r\n' + ( extractedChars = '' ) ; sdp = sdp . indexOf ( 'a=crypto' ) == - 1 ? sdp . replace ( /c=IN/g , 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:' + inline + 'c=IN' ) : sdp ; return sdp ; }
function serializeSdp ( sdp ) { return sdp ; }
var channel ; function openOffererChannel ( ) { if ( ! options . onChannelMessage || ( moz && ! options . onOfferSDP ) ) return ; _openOffererChannel ( ) ; if ( ! moz ) return ; navigator . mozGetUserMedia ( { audio : true , fake : true } , function ( stream ) { peer . addStream ( stream ) ; createOffer ( ) ; } , useless ) ; }
function _openOffererChannel ( ) { channel = peer . createDataChannel ( options . channel || 'RTCDataChannel' , moz ? { } : { reliable : false } ) ; if ( moz ) channel . binaryType = 'blob' ; setChannelEvents ( ) ; }
function setChannelEvents ( ) { channel . onmessage = function ( event ) { if ( options . onChannelMessage ) options . onChannelMessage ( event ) ; } ; channel . onopen = function ( ) { if ( options . onChannelOpened ) options . onChannelOpened ( channel ) ; } ; channel . onclose = function ( event ) { if ( options . onChannelClosed ) options . onChannelClosed ( event ) ; console . warn ( 'WebRTC DataChannel closed' , event ) ; } ; channel . onerror = function ( event ) { if ( options . onChannelError ) options . onChannelError ( event ) ; console . error ( 'WebRTC DataChannel error' , event ) ; } ; }
if ( options . onAnswerSDP && moz && options . onChannelMessage ) openAnswererChannel ( ) ; function openAnswererChannel ( ) { peer . ondatachannel = function ( event ) { channel = event . channel ; channel . binaryType = 'blob' ; setChannelEvents ( ) ; } ; if ( ! moz ) return ; navigator . mozGetUserMedia ( { audio : true , fake : true } , function ( stream ) { peer . addStream ( stream ) ; createAnswer ( ) ; } , useless ) ; }
function useless ( ) { log ( 'Error in fake:true' ) ; }
function onSdpSuccess ( ) { }
function onSdpError ( e ) { if ( options . onChannelError ) { options . onChannelError ( e ) ; }
console . error ( 'sdp error:' , e ) ; }
return { addAnswerSDP : function ( sdp , cbSuccess , cbError ) { peer . setRemoteDescription ( new SessionDescription ( sdp ) , cbSuccess ? cbSuccess : onSdpSuccess , cbError ? cbError : onSdpError ) ; } , addICE : function ( candidate ) { peer . addIceCandidate ( new IceCandidate ( { sdpMLineIndex : candidate . sdpMLineIndex , candidate : candidate . candidate } ) ) ; } , peer : peer , channel : channel , sendData : function ( message ) { if ( channel ) { channel . send ( message ) ; } } , stop : function ( ) { peer . close ( ) ; if ( options . attachStream ) { options . attachStream . stop ( ) ; } } } ; }
2015-02-20 23:19:09 +00:00
var video _constraints = { mandatory : { } , optional : [ ] } ; function getUserMedia ( options ) { var n = navigator , media ; n . getMedia = n . webkitGetUserMedia || n . mozGetUserMedia ; n . getMedia ( options . constraints || { audio : true , video : video _constraints } , streaming , options . onerror || function ( e ) { console . error ( e ) ; } ) ; function streaming ( stream ) { if ( options . localVideo ) { options . localVideo [ moz ? 'mozSrcObject' : 'src' ] = moz ? stream : window . webkitURL . createObjectURL ( stream ) ; options . localVideo . style . display = 'block' ; }
2014-12-06 17:40:44 +00:00
if ( options . onsuccess ) { options . onsuccess ( stream ) ; }
media = stream ; }
2015-04-28 20:56:25 +00:00
return media ; }
2015-08-28 19:20:18 +00:00
$ . FSRTC . resSupported = function ( w , h ) { for ( var i in $ . FSRTC . validRes ) { if ( $ . FSRTC . validRes [ i ] [ 0 ] == w && $ . FSRTC . validRes [ i ] [ 1 ] == h ) { return true ; } }
2015-04-28 20:56:25 +00:00
return false ; }
$ . FSRTC . bestResSupported = function ( ) { var w = 0 , h = 0 ; for ( var i in $ . FSRTC . validRes ) { if ( $ . FSRTC . validRes [ i ] [ 0 ] > w && $ . FSRTC . validRes [ i ] [ 1 ] > h ) { w = $ . FSRTC . validRes [ i ] [ 0 ] ; h = $ . FSRTC . validRes [ i ] [ 1 ] ; } }
return [ w , h ] ; }
2015-08-28 14:42:37 +00:00
var resList = [ [ 320 , 180 ] , [ 320 , 240 ] , [ 640 , 360 ] , [ 640 , 480 ] , [ 1280 , 720 ] , [ 1920 , 1080 ] ] ; var resI = 0 ; var ttl = 0 ; var checkRes = function ( cam , func ) { if ( resI >= resList . length ) { var res = { 'validRes' : $ . FSRTC . validRes , 'bestResSupported' : $ . FSRTC . bestResSupported ( ) } ; localStorage . setItem ( "res_" + cam , $ . toJSON ( res ) ) ; if ( func ) return func ( res ) ; return ; }
2015-04-30 18:40:39 +00:00
var video = { mandatory : { } , optional : [ ] }
2015-05-01 03:27:05 +00:00
if ( cam ) { video . optional = [ { sourceId : cam } ] ; }
2015-06-18 17:47:04 +00:00
w = resList [ resI ] [ 0 ] ; h = resList [ resI ] [ 1 ] ; resI ++ ; video . mandatory = { "minWidth" : w , "minHeight" : h , "maxWidth" : w , "maxHeight" : h } ; if ( window . moz ) { video = video . mandatory ; if ( ! video . width ) video . width = video . minWidth ; if ( ! video . height ) video . height = video . minHeight ; if ( ! video . frameRate ) video . frameRate = video . minFrameRate ; }
2015-06-18 18:00:42 +00:00
getUserMedia ( { constraints : { audio : ttl ++ == 0 , video : video } , onsuccess : function ( e ) { e . stop ( ) ; console . info ( w + "x" + h + " supported." ) ; $ . FSRTC . validRes . push ( [ w , h ] ) ; checkRes ( cam , func ) ; } , onerror : function ( e ) { console . error ( w + "x" + h + " not supported." ) ; checkRes ( cam , func ) ; } } ) ; }
2015-08-28 19:32:48 +00:00
$ . FSRTC . getValidRes = function ( cam , func ) { var used = [ ] ; var cached = localStorage . getItem ( "res_" + cam ) ; if ( cached ) { var cache = $ . parseJSON ( cached ) ; if ( cache ) { $ . FSRTC . validRes = cache . validRes ; console . log ( "CACHED RES FOR CAM " + cam , cache ) ; } else { console . error ( "INVALID CACHE" ) ; }
return func ? func ( cache ) : null ; }
2015-08-28 14:42:37 +00:00
$ . FSRTC . validRes = [ ] ; resI = 0 ; checkRes ( cam , func ) ; }
2015-09-17 20:09:19 +00:00
$ . FSRTC . checkPerms = function ( runtime , check _audio , check _video ) { getUserMedia ( { constraints : { audio : check _audio , video : check _video , } , onsuccess : function ( e ) { e . 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 . call = function ( method , params , success _cb , error _cb ) { if ( ! params ) { params = { } ; }
2014-12-06 17:40:44 +00:00
if ( this . options . sessid ) { params . sessid = this . options . sessid ; }
var request = { jsonrpc : '2.0' , method : method , params : params , id : this . _current _id ++ } ; if ( ! success _cb ) { success _cb = function ( e ) { console . log ( "Success: " , e ) ; } ; }
if ( ! error _cb ) { error _cb = function ( e ) { console . log ( "Error: " , e ) ; } ; }
var socket = this . options . getSocket ( this . wsOnMessage ) ; if ( socket !== null ) { this . _wsCall ( socket , request , success _cb , error _cb ) ; return ; }
if ( this . options . ajaxUrl === null ) { throw "$.JsonRpcClient.call used with no websocket and no http endpoint." ; }
$ . ajax ( { type : 'POST' , url : this . options . ajaxUrl , data : $ . toJSON ( request ) , dataType : 'json' , cache : false , success : function ( data ) { if ( 'error' in data ) error _cb ( data . error , this ) ; success _cb ( data . result , this ) ; } , error : function ( jqXHR , textStatus , errorThrown ) { try { var response = $ . parseJSON ( jqXHR . responseText ) ; if ( 'console' in window ) console . log ( response ) ; error _cb ( response . error , this ) ; } catch ( err ) { error _cb ( { error : jqXHR . responseText } , this ) ; } } } ) ; } ; $ . JsonRpcClient . prototype . notify = function ( method , params ) { if ( this . options . sessid ) { params . sessid = this . options . sessid ; }
var request = { jsonrpc : '2.0' , method : method , params : params } ; var socket = this . options . getSocket ( this . wsOnMessage ) ; if ( socket !== null ) { this . _wsCall ( socket , request ) ; return ; }
if ( this . options . ajaxUrl === null ) { throw "$.JsonRpcClient.notify used with no websocket and no http endpoint." ; }
$ . ajax ( { type : 'POST' , url : this . options . ajaxUrl , data : $ . toJSON ( request ) , dataType : 'json' , cache : false } ) ; } ; $ . JsonRpcClient . prototype . batch = function ( callback , all _done _cb , error _cb ) { var batch = new $ . JsonRpcClient . _batchObject ( this , all _done _cb , error _cb ) ; callback ( batch ) ; batch . _execute ( ) ; } ; $ . JsonRpcClient . prototype . socketReady = function ( ) { if ( this . _ws _socket === null || this . _ws _socket . readyState > 1 ) { return false ; }
2015-04-28 20:56:25 +00:00
return true ; } ; $ . JsonRpcClient . prototype . closeSocket = function ( ) { var self = this ; if ( self . socketReady ( ) ) { self . _ws _socket . onclose = function ( w ) { console . log ( "Closing Socket" ) ; } ; self . _ws _socket . close ( ) ; } } ; $ . JsonRpcClient . prototype . loginData = function ( params ) { var self = this ; self . options . login = params . login ; self . options . passwd = params . passwd ; self . options . loginParams = params . loginParams ; self . options . userVariables = params . userVariables ; } ; $ . JsonRpcClient . prototype . connectSocket = function ( onmessage _cb ) { var self = this ; if ( self . to ) { clearTimeout ( self . to ) ; }
2014-12-06 17:40:44 +00:00
if ( ! self . socketReady ( ) ) { self . authing = false ; if ( self . _ws _socket ) { delete self . _ws _socket ; }
self . _ws _socket = new WebSocket ( self . options . socketUrl ) ; if ( self . _ws _socket ) { self . _ws _socket . onmessage = onmessage _cb ; self . _ws _socket . onclose = function ( w ) { if ( ! self . ws _sleep ) { self . ws _sleep = 1000 ; }
if ( self . options . onWSClose ) { self . options . onWSClose ( self ) ; }
2015-01-07 07:43:49 +00:00
console . error ( "Websocket Lost " + self . ws _cnt + " sleep: " + self . ws _sleep + "msec" ) ; self . to = setTimeout ( function ( ) { console . log ( "Attempting Reconnection...." ) ; self . connectSocket ( onmessage _cb ) ; } , self . ws _sleep ) ; self . ws _cnt ++ ; if ( self . ws _sleep < 3000 && ( self . ws _cnt % 10 ) === 0 ) { self . ws _sleep += 1000 ; } } ; self . _ws _socket . onopen = function ( ) { if ( self . to ) { clearTimeout ( self . to ) ; }
2014-12-06 17:40:44 +00:00
self . ws _sleep = 1000 ; self . ws _cnt = 0 ; if ( self . options . onWSConnect ) { self . options . onWSConnect ( self ) ; }
2015-01-07 07:43:49 +00:00
var req ; while ( ( req = $ . JsonRpcClient . q . pop ( ) ) ) { self . _ws _socket . send ( req ) ; } } ; } }
return self . _ws _socket ? true : false ; } ; $ . JsonRpcClient . prototype . _getSocket = function ( onmessage _cb ) { if ( this . options . socketUrl === null || ! ( "WebSocket" in window ) ) return null ; this . connectSocket ( onmessage _cb ) ; return this . _ws _socket ; } ; $ . JsonRpcClient . q = [ ] ; $ . JsonRpcClient . prototype . _wsCall = function ( socket , request , success _cb , error _cb ) { var request _json = $ . toJSON ( request ) ; if ( socket . readyState < 1 ) { self = this ; $ . JsonRpcClient . q . push ( request _json ) ; } else { socket . send ( request _json ) ; }
2015-04-28 20:56:25 +00:00
if ( 'id' in request && typeof success _cb !== 'undefined' ) { this . _ws _callbacks [ request . id ] = { request : request _json , request _obj : request , success _cb : success _cb , error _cb : error _cb } ; } } ; $ . JsonRpcClient . prototype . _wsOnMessage = function ( event ) { var response ; try { response = $ . parseJSON ( event . data ) ; if ( typeof response === 'object' && 'jsonrpc' in response && response . jsonrpc === '2.0' ) { if ( 'result' in response && this . _ws _callbacks [ response . id ] ) { var success _cb = this . _ws _callbacks [ response . id ] . success _cb ; delete this . _ws _callbacks [ response . id ] ; success _cb ( response . result , this ) ; return ; } else if ( 'error' in response && this . _ws _callbacks [ response . id ] ) { var error _cb = this . _ws _callbacks [ response . id ] . error _cb ; var orig _req = this . _ws _callbacks [ response . id ] . request ; if ( ! self . authing && response . error . code == - 32000 && self . options . login && self . options . passwd ) { self . authing = true ; this . call ( "login" , { login : self . options . login , passwd : self . options . passwd , loginParams : self . options . loginParams , userVariables : self . options . userVariables } , this . _ws _callbacks [ response . id ] . request _obj . method == "login" ? function ( e ) { self . authing = false ; console . log ( "logged in" ) ; delete self . _ws _callbacks [ response . id ] ; if ( self . options . onWSLogin ) { self . options . onWSLogin ( true , self ) ; } } : function ( e ) { self . authing = false ; console . log ( "logged in, resending request id: " + response . id ) ; var socket = self . options . getSocket ( self . wsOnMessage ) ; if ( socket !== null ) { socket . send ( orig _req ) ; }
2014-12-06 17:40:44 +00:00
if ( self . options . onWSLogin ) { self . options . onWSLogin ( true , self ) ; } } , function ( e ) { console . log ( "error logging in, request id:" , response . id ) ; delete self . _ws _callbacks [ response . id ] ; error _cb ( response . error , this ) ; if ( self . options . onWSLogin ) { self . options . onWSLogin ( false , self ) ; } } ) ; return ; }
delete this . _ws _callbacks [ response . id ] ; error _cb ( response . error , this ) ; return ; } } } catch ( err ) { console . log ( "ERROR: " + err ) ; return ; }
if ( typeof this . options . onmessage === 'function' ) { event . eventData = response ; if ( ! event . eventData ) { event . eventData = { } ; }
var reply = this . options . onmessage ( event ) ; if ( reply && typeof reply === "object" && event . eventData . id ) { var msg = { jsonrpc : "2.0" , id : event . eventData . id , result : reply } ; var socket = self . options . getSocket ( self . wsOnMessage ) ; if ( socket !== null ) { socket . send ( $ . toJSON ( msg ) ) ; } } } } ; $ . JsonRpcClient . _batchObject = function ( jsonrpcclient , all _done _cb , error _cb ) { this . _requests = [ ] ; this . jsonrpcclient = jsonrpcclient ; this . all _done _cb = all _done _cb ; this . error _cb = typeof error _cb === 'function' ? error _cb : function ( ) { } ; } ; $ . JsonRpcClient . _batchObject . prototype . call = function ( method , params , success _cb , error _cb ) { if ( ! params ) { params = { } ; }
if ( this . options . sessid ) { params . sessid = this . options . sessid ; }
if ( ! success _cb ) { success _cb = function ( e ) { console . log ( "Success: " , e ) ; } ; }
if ( ! error _cb ) { error _cb = function ( e ) { console . log ( "Error: " , e ) ; } ; }
this . _requests . push ( { request : { jsonrpc : '2.0' , method : method , params : params , id : this . jsonrpcclient . _current _id ++ } , success _cb : success _cb , error _cb : error _cb } ) ; } ; $ . JsonRpcClient . _batchObject . prototype . notify = function ( method , params ) { if ( this . options . sessid ) { params . sessid = this . options . sessid ; }
2015-01-07 07:43:49 +00:00
this . _requests . push ( { request : { jsonrpc : '2.0' , method : method , params : params } } ) ; } ; $ . JsonRpcClient . _batchObject . prototype . _execute = function ( ) { var self = this ; if ( this . _requests . length === 0 ) return ; var batch _request = [ ] ; var handlers = { } ; var i = 0 ; var call ; var success _cb ; var error _cb ; var socket = self . jsonrpcclient . options . getSocket ( self . jsonrpcclient . wsOnMessage ) ; if ( socket !== null ) { for ( i = 0 ; i < this . _requests . length ; i ++ ) { call = this . _requests [ i ] ; success _cb = ( 'success_cb' in call ) ? call . success _cb : undefined ; error _cb = ( 'error_cb' in call ) ? call . error _cb : undefined ; self . jsonrpcclient . _wsCall ( socket , call . request , success _cb , error _cb ) ; }
2014-12-06 17:40:44 +00:00
if ( typeof all _done _cb === 'function' ) all _done _cb ( result ) ; return ; }
2015-01-07 07:43:49 +00:00
for ( i = 0 ; i < this . _requests . length ; i ++ ) { call = this . _requests [ i ] ; batch _request . push ( call . request ) ; if ( 'id' in call . request ) { handlers [ call . request . id ] = { success _cb : call . success _cb , error _cb : call . error _cb } ; } }
success _cb = function ( data ) { self . _batchCb ( data , handlers , self . all _done _cb ) ; } ; if ( self . jsonrpcclient . options . ajaxUrl === null ) { throw "$.JsonRpcClient.batch used with no websocket and no http endpoint." ; }
2014-12-06 17:40:44 +00:00
$ . ajax ( { url : self . jsonrpcclient . options . ajaxUrl , data : $ . toJSON ( batch _request ) , dataType : 'json' , cache : false , type : 'POST' , error : function ( jqXHR , textStatus , errorThrown ) { self . error _cb ( jqXHR , textStatus , errorThrown ) ; } , success : success _cb } ) ; } ; $ . JsonRpcClient . _batchObject . prototype . _batchCb = function ( result , handlers , all _done _cb ) { for ( var i = 0 ; i < result . length ; i ++ ) { var response = result [ i ] ; if ( 'error' in response ) { if ( response . id === null || ! ( response . id in handlers ) ) { if ( 'console' in window ) console . log ( response ) ; } else { handlers [ response . id ] . error _cb ( response . error , this ) ; } } else { if ( ! ( response . id in handlers ) && 'console' in window ) { console . log ( response ) ; } else { handlers [ response . id ] . success _cb ( response . result , this ) ; } } }
2015-02-19 23:08:36 +00:00
if ( typeof all _done _cb === 'function' ) all _done _cb ( result ) ; } ; } ) ( jQuery ) ; ( function ( $ ) { var sources = [ ] ; var generateGUID = ( typeof ( window . crypto ) !== 'undefined' && typeof ( window . crypto . getRandomValues ) !== 'undefined' ) ? function ( ) { var buf = new Uint16Array ( 8 ) ; window . crypto . getRandomValues ( buf ) ; var S4 = function ( num ) { var ret = num . toString ( 16 ) ; while ( ret . length < 4 ) { ret = "0" + ret ; }
2015-08-28 16:40:52 +00:00
return ret ; } ; return ( S4 ( buf [ 0 ] ) + S4 ( buf [ 1 ] ) + "-" + S4 ( buf [ 2 ] ) + "-" + S4 ( buf [ 3 ] ) + "-" + S4 ( buf [ 4 ] ) + "-" + S4 ( buf [ 5 ] ) + S4 ( buf [ 6 ] ) + S4 ( buf [ 7 ] ) ) ; } : function ( ) { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( /[xy]/g , function ( c ) { var r = Math . random ( ) * 16 | 0 , v = c == 'x' ? r : ( r & 0x3 | 0x8 ) ; return v . toString ( 16 ) ; } ) ; } ; $ . verto = function ( options , callbacks ) { var verto = this ; $ . verto . saved . push ( verto ) ; verto . options = $ . extend ( { login : null , passwd : null , socketUrl : null , tag : null , localTag : null , videoParams : { } , audioParams : { } , loginParams : { } , deviceParams : { onResCheck : null } , userVariables : { } , iceServers : false , ringSleep : 6000 , sessid : null } , options ) ; if ( verto . options . deviceParams . useCamera ) { $ . FSRTC . getValidRes ( verto . options . deviceParams . useCamera , verto . options . deviceParams . onResCheck ) ; } else { verto . options . deviceParams . useCamera = "any" ; $ . FSRTC . getValidRes ( undefined , undefined ) ; }
2015-08-25 21:04:34 +00:00
if ( ! verto . options . deviceParams . useMic ) { verto . options . deviceParams . useMic = "any" ; }
if ( ! verto . options . deviceParams . useSpeak ) { verto . options . deviceParams . useSpeak = "any" ; }
2015-08-28 14:42:37 +00:00
if ( verto . options . sessid ) { verto . sessid = verto . options . sessid ; } else { verto . sessid = localStorage . getItem ( "verto_session_uuid" ) || generateGUID ( ) ; localStorage . setItem ( "verto_session_uuid" , verto . sessid ) ; }
2015-07-02 22:55:04 +00:00
verto . dialogs = { } ; verto . callbacks = callbacks || { } ; verto . eventSUBS = { } ; verto . rpcClient = new $ . JsonRpcClient ( { login : verto . options . login , passwd : verto . options . passwd , socketUrl : verto . options . socketUrl , loginParams : verto . options . loginParams , userVariables : verto . options . userVariables , sessid : verto . sessid , onmessage : function ( e ) { return verto . handleMessage ( e . eventData ) ; } , onWSConnect : function ( o ) { o . call ( 'login' , { } ) ; } , onWSLogin : function ( success ) { if ( verto . callbacks . onWSLogin ) { verto . callbacks . onWSLogin ( verto , success ) ; } } , onWSClose : function ( success ) { if ( verto . callbacks . onWSClose ) { verto . callbacks . onWSClose ( verto , success ) ; }
2014-12-06 17:40:44 +00:00
verto . purge ( ) ; } } ) ; if ( verto . options . ringFile && verto . options . tag ) { verto . ringer = $ ( "#" + verto . options . tag ) ; }
2015-08-28 14:45:52 +00:00
verto . rpcClient . call ( 'login' , { } ) ; } ; $ . verto . prototype . deviceParams = function ( obj ) { var verto = this ; for ( var i in obj ) { verto . options . deviceParams [ i ] = obj [ i ] ; }
2015-08-28 19:34:31 +00:00
if ( obj . useCamera ) { $ . FSRTC . getValidRes ( verto . options . deviceParams . useCamera , obj ? obj . onResCheck : undefined ) ; } } ; $ . verto . prototype . videoParams = function ( obj ) { var verto = this ; for ( var i in obj ) { verto . options . videoParams [ i ] = obj [ i ] ; } } ; $ . verto . prototype . iceServers = function ( obj ) { var verto = this ; verto . options . iceServers = obj ; } ; $ . verto . prototype . loginData = function ( params ) { var verto = this ; verto . options . login = params . login ; verto . options . passwd = params . passwd ; verto . rpcClient . loginData ( params ) ; } ; $ . verto . prototype . logout = function ( msg ) { var verto = this ; verto . rpcClient . closeSocket ( ) ; if ( verto . callbacks . onWSClose ) { verto . callbacks . onWSClose ( verto , false ) ; }
2015-01-06 03:20:31 +00:00
verto . purge ( ) ; } ; $ . verto . prototype . login = function ( msg ) { var verto = this ; verto . logout ( ) ; verto . rpcClient . call ( 'login' , { } ) ; } ; $ . verto . prototype . message = function ( msg ) { var verto = this ; var err = 0 ; if ( ! msg . to ) { console . error ( "Missing To" ) ; err ++ ; }
2014-12-06 17:40:44 +00:00
if ( ! msg . body ) { console . error ( "Missing Body" ) ; err ++ ; }
if ( err ) { return false ; }
verto . sendMethod ( "verto.info" , { msg : msg } ) ; return true ; } ; $ . verto . prototype . processReply = function ( method , success , e ) { var verto = this ; var i ; switch ( method ) { case "verto.subscribe" : for ( i in e . unauthorizedChannels ) { drop _bad ( verto , e . unauthorizedChannels [ i ] ) ; }
for ( i in e . subscribedChannels ) { mark _ready ( verto , e . subscribedChannels [ i ] ) ; }
break ; case "verto.unsubscribe" : break ; } } ; $ . verto . prototype . sendMethod = function ( method , params ) { var verto = this ; verto . rpcClient . call ( method , params , function ( e ) { verto . processReply ( method , true , e ) ; } , function ( e ) { verto . processReply ( method , false , e ) ; } ) ; } ; function do _sub ( verto , channel , obj ) { }
function drop _bad ( verto , channel ) { console . error ( "drop unauthorized channel: " + channel ) ; delete verto . eventSUBS [ channel ] ; }
function mark _ready ( verto , channel ) { for ( var j in verto . eventSUBS [ channel ] ) { verto . eventSUBS [ channel ] [ j ] . ready = true ; console . log ( "subscribed to channel: " + channel ) ; if ( verto . eventSUBS [ channel ] [ j ] . readyHandler ) { verto . eventSUBS [ channel ] [ j ] . readyHandler ( verto , channel ) ; } } }
var SERNO = 1 ; function do _subscribe ( verto , channel , subChannels , sparams ) { var params = sparams || { } ; var local = params . local ; var obj = { eventChannel : channel , userData : params . userData , handler : params . handler , ready : false , readyHandler : params . readyHandler , serno : SERNO ++ } ; var isnew = false ; if ( ! verto . eventSUBS [ channel ] ) { verto . eventSUBS [ channel ] = [ ] ; subChannels . push ( channel ) ; isnew = true ; }
verto . eventSUBS [ channel ] . push ( obj ) ; if ( local ) { obj . ready = true ; obj . local = true ; }
if ( ! isnew && verto . eventSUBS [ channel ] [ 0 ] . ready ) { obj . ready = true ; if ( obj . readyHandler ) { obj . readyHandler ( verto , channel ) ; } }
return { serno : obj . serno , eventChannel : channel } ; }
$ . verto . prototype . subscribe = function ( channel , sparams ) { var verto = this ; var r = [ ] ; var subChannels = [ ] ; var params = sparams || { } ; if ( typeof ( channel ) === "string" ) { r . push ( do _subscribe ( verto , channel , subChannels , params ) ) ; } else { for ( var i in channel ) { r . push ( do _subscribe ( verto , channel , subChannels , params ) ) ; } }
if ( subChannels . length ) { verto . sendMethod ( "verto.subscribe" , { eventChannel : subChannels . length == 1 ? subChannels [ 0 ] : subChannels , subParams : params . subParams } ) ; }
return r ; } ; $ . verto . prototype . unsubscribe = function ( handle ) { var verto = this ; var i ; if ( ! handle ) { for ( i in verto . eventSUBS ) { if ( verto . eventSUBS [ i ] ) { verto . unsubscribe ( verto . eventSUBS [ i ] ) ; } } } else { var unsubChannels = { } ; var sendChannels = [ ] ; var channel ; if ( typeof ( handle ) == "string" ) { delete verto . eventSUBS [ handle ] ; unsubChannels [ handle ] ++ ; } else { for ( i in handle ) { if ( typeof ( handle [ i ] ) == "string" ) { channel = handle [ i ] ; delete verto . eventSUBS [ channel ] ; unsubChannels [ channel ] ++ ; } else { var repl = [ ] ; channel = handle [ i ] . eventChannel ; for ( var j in verto . eventSUBS [ channel ] ) { if ( verto . eventSUBS [ channel ] [ j ] . serno == handle [ i ] . serno ) { } else { repl . push ( verto . eventSUBS [ channel ] [ j ] ) ; } }
verto . eventSUBS [ channel ] = repl ; if ( verto . eventSUBS [ channel ] . length === 0 ) { delete verto . eventSUBS [ channel ] ; unsubChannels [ channel ] ++ ; } } } }
for ( var u in unsubChannels ) { console . log ( "Sending Unsubscribe for: " , u ) ; sendChannels . push ( u ) ; }
if ( sendChannels . length ) { verto . sendMethod ( "verto.unsubscribe" , { eventChannel : sendChannels . length == 1 ? sendChannels [ 0 ] : sendChannels } ) ; } } } ; $ . verto . prototype . broadcast = function ( channel , params ) { var verto = this ; var msg = { eventChannel : channel , data : { } } ; for ( var i in params ) { msg . data [ i ] = params [ i ] ; }
verto . sendMethod ( "verto.broadcast" , msg ) ; } ; $ . verto . prototype . purge = function ( callID ) { var verto = this ; var x = 0 ; var i ; for ( i in verto . dialogs ) { if ( ! x ) { console . log ( "purging dialogs" ) ; }
x ++ ; verto . dialogs [ i ] . setState ( $ . verto . enum . state . purge ) ; }
for ( i in verto . eventSUBS ) { if ( verto . eventSUBS [ i ] ) { console . log ( "purging subscription: " + i ) ; delete verto . eventSUBS [ i ] ; } } } ; $ . verto . prototype . hangup = function ( callID ) { var verto = this ; if ( callID ) { var dialog = verto . dialogs [ callID ] ; if ( dialog ) { dialog . hangup ( ) ; } } else { for ( var i in verto . dialogs ) { verto . dialogs [ i ] . hangup ( ) ; } } } ; $ . verto . prototype . newCall = function ( args , callbacks ) { var verto = this ; if ( ! verto . rpcClient . socketReady ( ) ) { console . error ( "Not Connected..." ) ; return ; }
var dialog = new $ . verto . dialog ( $ . verto . enum . direction . outbound , this , args ) ; dialog . invite ( ) ; if ( callbacks ) { dialog . callbacks = callbacks ; }
return dialog ; } ; $ . verto . prototype . handleMessage = function ( data ) { var verto = this ; if ( ! ( data && data . method ) ) { console . error ( "Invalid Data" , data ) ; return ; }
2015-03-24 00:56:19 +00:00
if ( data . params . callID ) { var dialog = verto . dialogs [ data . params . callID ] ; if ( data . method === "verto.attach" && dialog ) { delete dialog . verto . dialogs [ dialog . callID ] ; dialog . rtc . stop ( ) ; dialog = null ; }
if ( dialog ) { switch ( data . method ) { case 'verto.bye' : dialog . hangup ( data . params ) ; break ; case 'verto.answer' : dialog . handleAnswer ( data . params ) ; break ; case 'verto.media' : dialog . handleMedia ( data . params ) ; break ; case 'verto.display' : dialog . handleDisplay ( data . params ) ; break ; case 'verto.info' : dialog . handleInfo ( data . params ) ; break ; default : console . debug ( "INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED" , dialog , data . method ) ; break ; } } else { switch ( data . method ) { case 'verto.attach' : data . params . attach = true ; if ( data . params . sdp && data . params . sdp . indexOf ( "m=video" ) > 0 ) { data . params . useVideo = true ; }
2014-12-06 17:40:44 +00:00
if ( data . params . sdp && data . params . sdp . indexOf ( "stereo=1" ) > 0 ) { data . params . useStereo = true ; }
dialog = new $ . verto . dialog ( $ . verto . enum . direction . inbound , verto , data . params ) ; dialog . setState ( $ . verto . enum . state . recovering ) ; break ; case 'verto.invite' : if ( data . params . sdp && data . params . sdp . indexOf ( "m=video" ) > 0 ) { data . params . wantVideo = true ; }
if ( data . params . sdp && data . params . sdp . indexOf ( "stereo=1" ) > 0 ) { data . params . useStereo = true ; }
dialog = new $ . verto . dialog ( $ . verto . enum . direction . inbound , verto , data . params ) ; break ; default : console . debug ( "INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED" ) ; break ; } }
2015-01-06 03:20:31 +00:00
return { method : data . method } ; } else { switch ( data . method ) { case 'verto.punt' : verto . purge ( ) ; verto . logout ( ) ; break ; case 'verto.event' : var list = null ; var key = null ; if ( data . params ) { key = data . params . eventChannel ; }
2014-12-06 17:40:44 +00:00
if ( key ) { list = verto . eventSUBS [ key ] ; if ( ! list ) { list = verto . eventSUBS [ key . split ( "." ) [ 0 ] ] ; } }
if ( ! list && key && key === verto . sessid ) { if ( verto . callbacks . onMessage ) { verto . callbacks . onMessage ( verto , null , $ . verto . enum . message . pvtEvent , data . params ) ; } } else if ( ! list && key && verto . dialogs [ key ] ) { verto . dialogs [ key ] . sendMessage ( $ . verto . enum . message . pvtEvent , data . params ) ; } else if ( ! list ) { if ( ! key ) { key = "UNDEFINED" ; }
console . error ( "UNSUBBED or invalid EVENT " + key + " IGNORED" ) ; } else { for ( var i in list ) { var sub = list [ i ] ; if ( ! sub || ! sub . ready ) { console . error ( "invalid EVENT for " + key + " IGNORED" ) ; } else if ( sub . handler ) { sub . handler ( verto , data . params , sub . userData ) ; } else if ( verto . callbacks . onEvent ) { verto . callbacks . onEvent ( verto , data . params , sub . userData ) ; } else { console . log ( "EVENT:" , data . params ) ; } } }
break ; case "verto.info" : if ( verto . callbacks . onMessage ) { verto . callbacks . onMessage ( verto , null , $ . verto . enum . message . info , data . params . msg ) ; }
console . debug ( "MESSAGE from: " + data . params . msg . from , data . params . msg . body ) ; break ; default : console . error ( "INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED" , data . method ) ; break ; } } } ; var del _array = function ( array , name ) { var r = [ ] ; var len = array . length ; for ( var i = 0 ; i < len ; i ++ ) { if ( array [ i ] != name ) { r . push ( array [ i ] ) ; } }
return r ; } ; var hashArray = function ( ) { var vha = this ; var hash = { } ; var array = [ ] ; vha . reorder = function ( a ) { array = a ; var h = hash ; hash = { } ; var len = array . length ; for ( var i = 0 ; i < len ; i ++ ) { var key = array [ i ] ; if ( h [ key ] ) { hash [ key ] = h [ key ] ; delete h [ key ] ; } }
h = undefined ; } ; vha . clear = function ( ) { hash = undefined ; array = undefined ; hash = { } ; array = [ ] ; } ; vha . add = function ( name , val , insertAt ) { var redraw = false ; if ( ! hash [ name ] ) { if ( insertAt === undefined || insertAt < 0 || insertAt >= array . length ) { array . push ( name ) ; } else { var x = 0 ; var n = [ ] ; var len = array . length ; for ( var i = 0 ; i < len ; i ++ ) { if ( x ++ == insertAt ) { n . push ( name ) ; }
n . push ( array [ i ] ) ; }
array = undefined ; array = n ; n = undefined ; redraw = true ; } }
hash [ name ] = val ; return redraw ; } ; vha . del = function ( name ) { var r = false ; if ( hash [ name ] ) { array = del _array ( array , name ) ; delete hash [ name ] ; r = true ; } else { console . error ( "can't del nonexistant key " + name ) ; }
return r ; } ; vha . get = function ( name ) { return hash [ name ] ; } ; vha . order = function ( ) { return array ; } ; vha . hash = function ( ) { return hash ; } ; vha . indexOf = function ( name ) { var len = array . length ; for ( var i = 0 ; i < len ; i ++ ) { if ( array [ i ] == name ) { return i ; } } } ; vha . arrayLen = function ( ) { return array . length ; } ; vha . asArray = function ( ) { var r = [ ] ; var len = array . length ; for ( var i = 0 ; i < len ; i ++ ) { var key = array [ i ] ; r . push ( hash [ key ] ) ; }
return r ; } ; vha . each = function ( cb ) { var len = array . length ; for ( var i = 0 ; i < len ; i ++ ) { cb ( array [ i ] , hash [ array [ i ] ] ) ; } } ; vha . dump = function ( html ) { var str = "" ; vha . each ( function ( name , val ) { str += "name: " + name + " val: " + JSON . stringify ( val ) + ( html ? "<br>" : "\n" ) ; } ) ; return str ; } ; } ; $ . verto . liveArray = function ( verto , context , name , config ) { var la = this ; var lastSerno = 0 ; var binding = null ; var user _obj = config . userObj ; var local = false ; hashArray . call ( la ) ; la . _add = la . add ; la . _del = la . del ; la . _reorder = la . reorder ; la . _clear = la . clear ; la . context = context ; la . name = name ; la . user _obj = user _obj ; la . verto = verto ; la . broadcast = function ( channel , obj ) { verto . broadcast ( channel , obj ) ; } ; la . errs = 0 ; la . clear = function ( ) { la . _clear ( ) ; lastSerno = 0 ; if ( la . onChange ) { la . onChange ( la , { action : "clear" } ) ; } } ; la . checkSerno = function ( serno ) { if ( serno < 0 ) { return true ; }
if ( lastSerno > 0 && serno != ( lastSerno + 1 ) ) { if ( la . onErr ) { la . onErr ( la , { lastSerno : lastSerno , serno : serno } ) ; }
la . errs ++ ; console . debug ( la . errs ) ; if ( la . errs < 3 ) { la . bootstrap ( la . user _obj ) ; }
return false ; } else { lastSerno = serno ; return true ; } } ; la . reorder = function ( serno , a ) { if ( la . checkSerno ( serno ) ) { la . _reorder ( a ) ; if ( la . onChange ) { la . onChange ( la , { serno : serno , action : "reorder" } ) ; } } } ; la . init = function ( serno , val , key , index ) { if ( key === null || key === undefined ) { key = serno ; }
if ( la . checkSerno ( serno ) ) { if ( la . onChange ) { la . onChange ( la , { serno : serno , action : "init" , index : index , key : key , data : val } ) ; } } } ; la . bootObj = function ( serno , val ) { if ( la . checkSerno ( serno ) ) { for ( var i in val ) { la . _add ( val [ i ] [ 0 ] , val [ i ] [ 1 ] ) ; }
if ( la . onChange ) { la . onChange ( la , { serno : serno , action : "bootObj" , data : val , redraw : true } ) ; } } } ; la . add = function ( serno , val , key , index ) { if ( key === null || key === undefined ) { key = serno ; }
if ( la . checkSerno ( serno ) ) { var redraw = la . _add ( key , val , index ) ; if ( la . onChange ) { la . onChange ( la , { serno : serno , action : "add" , index : index , key : key , data : val , redraw : redraw } ) ; } } } ; la . modify = function ( serno , val , key , index ) { if ( key === null || key === undefined ) { key = serno ; }
if ( la . checkSerno ( serno ) ) { la . _add ( key , val , index ) ; if ( la . onChange ) { la . onChange ( la , { serno : serno , action : "modify" , key : key , data : val , index : index } ) ; } } } ; la . del = function ( serno , key , index ) { if ( key === null || key === undefined ) { key = serno ; }
if ( la . checkSerno ( serno ) ) { if ( index === null || index < 0 || index === undefined ) { index = la . indexOf ( key ) ; }
var ok = la . _del ( key ) ; if ( ok && la . onChange ) { la . onChange ( la , { serno : serno , action : "del" , key : key , index : index } ) ; } } } ; var eventHandler = function ( v , e , la ) { var packet = e . data ; if ( packet . name != la . name ) { return ; }
switch ( packet . action ) { case "init" : la . init ( packet . wireSerno , packet . data , packet . hashKey , packet . arrIndex ) ; break ; case "bootObj" : la . bootObj ( packet . wireSerno , packet . data ) ; break ; case "add" : la . add ( packet . wireSerno , packet . data , packet . hashKey , packet . arrIndex ) ; break ; case "modify" : if ( ! ( packet . arrIndex || packet . hashKey ) ) { console . error ( "Invalid Packet" , packet ) ; } else { la . modify ( packet . wireSerno , packet . data , packet . hashKey , packet . arrIndex ) ; }
break ; case "del" : if ( ! ( packet . arrIndex || packet . hashKey ) ) { console . error ( "Invalid Packet" , packet ) ; } else { la . del ( packet . wireSerno , packet . hashKey , packet . arrIndex ) ; }
break ; case "clear" : la . clear ( ) ; break ; case "reorder" : la . reorder ( packet . wireSerno , packet . order ) ; break ; default : if ( la . checkSerno ( packet . wireSerno ) ) { if ( la . onChange ) { la . onChange ( la , { serno : packet . wireSerno , action : packet . action , data : packet . data } ) ; } }
break ; } } ; if ( la . context ) { binding = la . verto . subscribe ( la . context , { handler : eventHandler , userData : la , subParams : config . subParams } ) ; }
la . destroy = function ( ) { la . _clear ( ) ; la . verto . unsubscribe ( binding ) ; } ; la . sendCommand = function ( cmd , obj ) { var self = la ; self . broadcast ( self . context , { liveArray : { command : cmd , context : self . context , name : self . name , obj : obj } } ) ; } ; la . bootstrap = function ( obj ) { var self = la ; la . sendCommand ( "bootstrap" , obj ) ; } ; la . changepage = function ( obj ) { var self = la ; self . clear ( ) ; self . broadcast ( self . context , { liveArray : { command : "changepage" , context : la . context , name : la . name , obj : obj } } ) ; } ; la . heartbeat = function ( obj ) { var self = la ; var callback = function ( ) { self . heartbeat . call ( self , obj ) ; } ; self . broadcast ( self . context , { liveArray : { command : "heartbeat" , context : self . context , name : self . name , obj : obj } } ) ; self . hb _pid = setTimeout ( callback , 30000 ) ; } ; la . bootstrap ( la . user _obj ) ; } ; $ . verto . liveTable = function ( verto , context , name , jq , config ) { var dt ; var la = new $ . verto . liveArray ( verto , context , name , { subParams : config . subParams } ) ; var lt = this ; lt . liveArray = la ; lt . dataTable = dt ; lt . verto = verto ; lt . destroy = function ( ) { if ( dt ) { dt . fnDestroy ( ) ; }
if ( la ) { la . destroy ( ) ; }
dt = null ; la = null ; } ; la . onErr = function ( obj , args ) { console . error ( "Error: " , obj , args ) ; } ; la . onChange = function ( obj , args ) { var index = 0 ; var iserr = 0 ; if ( ! dt ) { if ( ! config . aoColumns ) { if ( args . action != "init" ) { return ; }
config . aoColumns = [ ] ; for ( var i in args . data ) { config . aoColumns . push ( { "sTitle" : args . data [ i ] } ) ; } }
dt = jq . dataTable ( config ) ; }
if ( dt && ( args . action == "del" || args . action == "modify" ) ) { index = args . index ; if ( index === undefined && args . key ) { index = la . indexOf ( args . key ) ; }
if ( index === undefined ) { console . error ( "INVALID PACKET Missing INDEX\n" , args ) ; return ; } }
if ( config . onChange ) { config . onChange ( obj , args ) ; }
try { switch ( args . action ) { case "bootObj" : if ( ! args . data ) { console . error ( "missing data" ) ; return ; }
dt . fnClearTable ( ) ; dt . fnAddData ( obj . asArray ( ) ) ; dt . fnAdjustColumnSizing ( ) ; break ; case "add" : if ( ! args . data ) { console . error ( "missing data" ) ; return ; }
if ( args . redraw > - 1 ) { dt . fnClearTable ( ) ; dt . fnAddData ( obj . asArray ( ) ) ; } else { dt . fnAddData ( args . data ) ; }
dt . fnAdjustColumnSizing ( ) ; break ; case "modify" : if ( ! args . data ) { return ; }
dt . fnUpdate ( args . data , index ) ; dt . fnAdjustColumnSizing ( ) ; break ; case "del" : dt . fnDeleteRow ( index ) ; dt . fnAdjustColumnSizing ( ) ; break ; case "clear" : dt . fnClearTable ( ) ; break ; case "reorder" : dt . fnClearTable ( ) ; dt . fnAddData ( obj . asArray ( ) ) ; break ; case "hide" : jq . hide ( ) ; break ; case "show" : jq . show ( ) ; break ; } } catch ( err ) { console . error ( "ERROR: " + err ) ; iserr ++ ; }
2015-08-28 22:47:05 +00:00
if ( iserr ) { obj . errs ++ ; if ( obj . errs < 3 ) { obj . bootstrap ( obj . user _obj ) ; } } else { obj . errs = 0 ; } } ; la . onChange ( la , { action : "init" } ) ; } ; var CONFMAN _SERNO = 1 ; $ . verto . conf = function ( verto , params ) { var conf = this ; conf . params = $ . extend ( { dialog : null , hasVid : false , laData : null , onBroadcast : null , onLaChange : null , onLaRow : null } , params ) ; conf . verto = verto ; conf . serno = CONFMAN _SERNO ++ ; createMainModeratorMethods ( ) ; verto . subscribe ( conf . params . laData . modChannel , { handler : function ( v , e ) { if ( conf . params . onBroadcast ) { conf . params . onBroadcast ( verto , conf , e . data ) ; } } } ) ; verto . subscribe ( conf . params . laData . chatChannel , { handler : function ( v , e ) { if ( typeof ( conf . params . chatCallback ) === "function" ) { conf . params . chatCallback ( v , e ) ; } } } ) ; } ; $ . verto . conf . prototype . modCommand = function ( cmd , id , value ) { var conf = this ; conf . verto . rpcClient . call ( "verto.broadcast" , { "eventChannel" : conf . params . laData . modChannel , "data" : { "application" : "conf-control" , "command" : cmd , "id" : id , "value" : value } } ) ; } ; $ . verto . conf . prototype . destroy = function ( ) { var conf = this ; conf . destroyed = true ; conf . params . onBroadcast ( conf . verto , conf , 'destroy' ) ; if ( conf . params . laData . modChannel ) { conf . verto . unsubscribe ( conf . params . laData . modChannel ) ; }
2015-08-26 17:04:07 +00:00
if ( conf . params . laData . chatChannel ) { conf . verto . unsubscribe ( conf . params . laData . chatChannel ) ; } } ; function createMainModeratorMethods ( ) { $ . verto . conf . prototype . listVideoLayouts = function ( ) { this . modCommand ( "list-videoLayouts" , null , null ) ; } ; $ . verto . conf . prototype . play = function ( file ) { this . modCommand ( "play" , null , file ) ; } ; $ . verto . conf . prototype . stop = function ( ) { this . modCommand ( "stop" , null , "all" ) ; } ; $ . verto . conf . prototype . record = function ( file ) { this . modCommand ( "recording" , null , [ "start" , file ] ) ; } ; $ . verto . conf . prototype . stopRecord = function ( ) { this . modCommand ( "recording" , null , [ "stop" , "all" ] ) ; } ; $ . verto . conf . prototype . snapshot = function ( file ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
2015-08-20 22:14:03 +00:00
this . modCommand ( "vid-write-png" , null , file ) ; } ; $ . verto . conf . prototype . setVideoLayout = function ( layout ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "vid-layout" , null , layout ) ; } ; $ . verto . conf . prototype . kick = function ( memberID ) { this . modCommand ( "kick" , parseInt ( memberID ) ) ; } ; $ . verto . conf . prototype . muteMic = function ( memberID ) { this . modCommand ( "tmute" , parseInt ( memberID ) ) ; } ; $ . verto . conf . prototype . muteVideo = function ( memberID ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "tvmute" , parseInt ( memberID ) ) ; } ; $ . verto . conf . prototype . presenter = function ( memberID ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "vid-res-id" , parseInt ( memberID ) , "presenter" ) ; } ; $ . verto . conf . prototype . videoFloor = function ( memberID ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "vid-floor" , parseInt ( memberID ) , "force" ) ; } ; $ . verto . conf . prototype . banner = function ( memberID , text ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "vid-banner" , parseInt ( memberID ) , escape ( text ) ) ; } ; $ . verto . conf . prototype . volumeDown = function ( memberID ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "volume_in" , parseInt ( memberID ) , "down" ) ; } ; $ . verto . conf . prototype . volumeUp = function ( memberID ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
this . modCommand ( "volume_in" , parseInt ( memberID ) , "up" ) ; } ; $ . verto . conf . prototype . transfer = function ( memberID , exten ) { if ( ! this . params . hasVid ) { throw 'Conference has no video' ; }
2015-08-28 14:42:37 +00:00
this . modCommand ( "transfer" , parseInt ( memberID ) , exten ) ; } ; $ . verto . conf . prototype . sendChat = function ( message , type ) { var conf = this ; conf . verto . rpcClient . call ( "verto.broadcast" , { "eventChannel" : conf . params . laData . chatChannel , "data" : { "action" : "send" , "message" : message , "type" : type } } ) ; } ; }
2015-08-20 22:14:03 +00:00
$ . verto . modfuncs = { } ; $ . verto . confMan = function ( verto , params ) { var confMan = this ; confMan . params = $ . extend ( { tableID : null , statusID : null , mainModID : null , dialog : null , hasVid : false , laData : null , onBroadcast : null , onLaChange : null , onLaRow : null } , params ) ; confMan . verto = verto ; confMan . serno = CONFMAN _SERNO ++ ; confMan . canvasCount = confMan . params . laData . canvasCount ; function genMainMod ( jq ) { var play _id = "play_" + confMan . serno ; var stop _id = "stop_" + confMan . serno ; var recording _id = "recording_" + confMan . serno ; var snapshot _id = "snapshot_" + confMan . serno ; var rec _stop _id = "recording_stop" + confMan . serno ; var div _id = "confman_" + confMan . serno ; var html = "<div id='" + div _id + "'><br>" + "<button class='ctlbtn' id='" + play _id + "'>Play</button>" + "<button class='ctlbtn' id='" + stop _id + "'>Stop</button>" + "<button class='ctlbtn' id='" + recording _id + "'>Record</button>" + "<button class='ctlbtn' id='" + rec _stop _id + "'>Record Stop</button>" +
2015-07-02 22:55:04 +00:00
( confMan . params . hasVid ? "<button class='ctlbtn' id='" + snapshot _id + "'>PNG Snapshot</button>" : "" ) + "<br><br></div>" ; jq . html ( html ) ; $ . verto . modfuncs . change _video _layout = function ( id , canvas _id ) { var val = $ ( "#" + id + " option:selected" ) . text ( ) ; if ( val !== "none" ) { confMan . modCommand ( "vid-layout" , null , [ val , canvas _id ] ) ; } } ; if ( confMan . params . hasVid ) { for ( var j = 0 ; j < confMan . canvasCount ; j ++ ) { var vlayout _id = "confman_vid_layout_" + j + "_" + confMan . serno ; var vlselect _id = "confman_vl_select_" + j + "_" + confMan . serno ; var vlhtml = "<div id='" + vlayout _id + "'><br>" + "<b>Video Layout Canvas " + ( j + 1 ) + "</b> <select onChange='$.verto.modfuncs.change_video_layout(\"" + vlayout _id + "\", \"" + j + "\")' id='" + vlselect _id + "'></select> " + "<br><br></div>" ; jq . append ( vlhtml ) ; }
$ ( "#" + snapshot _id ) . click ( function ( ) { var file = prompt ( "Please enter file name" , "" ) ; if ( file ) { confMan . modCommand ( "vid-write-png" , null , file ) ; } } ) ; }
2015-02-21 00:04:00 +00:00
$ ( "#" + play _id ) . click ( function ( ) { var file = prompt ( "Please enter file name" , "" ) ; if ( file ) { confMan . modCommand ( "play" , null , file ) ; } } ) ; $ ( "#" + stop _id ) . click ( function ( ) { confMan . modCommand ( "stop" , null , "all" ) ; } ) ; $ ( "#" + recording _id ) . click ( function ( ) { var file = prompt ( "Please enter file name" , "" ) ; if ( file ) { confMan . modCommand ( "recording" , null , [ "start" , file ] ) ; } } ) ; $ ( "#" + rec _stop _id ) . click ( function ( ) { confMan . modCommand ( "recording" , null , [ "stop" , "all" ] ) ; } ) ; }
2015-07-02 22:55:04 +00:00
function genControls ( jq , rowid ) { var x = parseInt ( rowid ) ; var kick _id = "kick_" + x ; var canvas _in _next _id = "canvas_in_next_" + x ; var canvas _in _prev _id = "canvas_in_prev_" + x ; var canvas _out _next _id = "canvas_out_next_" + x ; var canvas _out _prev _id = "canvas_out_prev_" + x ; var canvas _in _set _id = "canvas_in_set_" + x ; var canvas _out _set _id = "canvas_out_set_" + x ; var layer _set _id = "layer_set_" + x ; var layer _next _id = "layer_next_" + x ; var layer _prev _id = "layer_prev_" + x ; var tmute _id = "tmute_" + x ; var tvmute _id = "tvmute_" + x ; var vbanner _id = "vbanner_" + x ; var tvpresenter _id = "tvpresenter_" + x ; var tvfloor _id = "tvfloor_" + x ; var box _id = "box_" + x ; var volup _id = "volume_in_up" + x ; var voldn _id = "volume_in_dn" + x ; var transfer _id = "transfer" + x ; var html = "<div id='" + box _id + "'>" ; html += "<b>General Controls</b><hr noshade>" ; html += "<button class='ctlbtn' id='" + kick _id + "'>Kick</button>" + "<button class='ctlbtn' id='" + tmute _id + "'>Mute</button>" + "<button class='ctlbtn' id='" + voldn _id + "'>Vol -</button>" + "<button class='ctlbtn' id='" + volup _id + "'>Vol +</button>" + "<button class='ctlbtn' id='" + transfer _id + "'>Transfer</button>" ; if ( confMan . params . hasVid ) { html += "<br><br><b>Video Controls</b><hr noshade>" ; html += "<button class='ctlbtn' id='" + tvmute _id + "'>VMute</button>" + "<button class='ctlbtn' id='" + tvpresenter _id + "'>Presenter</button>" + "<button class='ctlbtn' id='" + tvfloor _id + "'>Vid Floor</button>" + "<button class='ctlbtn' id='" + vbanner _id + "'>Banner</button>" ; if ( confMan . canvasCount > 1 ) { html += "<br><br><b>Canvas Controls</b><hr noshade>" + "<button class='ctlbtn' id='" + canvas _in _set _id + "'>Set Input Canvas</button>" + "<button class='ctlbtn' id='" + canvas _in _prev _id + "'>Prev Input Canvas</button>" + "<button class='ctlbtn' id='" + canvas _in _next _id + "'>Next Input Canvas</button>" + "<br>" + "<button class='ctlbtn' id='" + canvas _out _set _id + "'>Set Watching Canvas</button>" + "<button class='ctlbtn' id='" + canvas _out _prev _id + "'>Prev Watching Canvas</button>" + "<button class='ctlbtn' id='" + canvas _out _next _id + "'>Next Watching Canvas</button>" ; }
html += "<br>" + "<button class='ctlbtn' id='" + layer _set _id + "'>Set Layer</button>" + "<button class='ctlbtn' id='" + layer _prev _id + "'>Prev Layer</button>" + "<button class='ctlbtn' id='" + layer _next _id + "'>Next Layer</button>" + "</div>" ; }
jq . html ( html ) ; if ( ! jq . data ( "mouse" ) ) { $ ( "#" + box _id ) . hide ( ) ; }
jq . mouseover ( function ( e ) { jq . data ( { "mouse" : true } ) ; $ ( "#" + box _id ) . show ( ) ; } ) ; jq . mouseout ( function ( e ) { jq . data ( { "mouse" : false } ) ; $ ( "#" + box _id ) . hide ( ) ; } ) ; $ ( "#" + transfer _id ) . click ( function ( ) { var xten = prompt ( "Enter Extension" ) ; if ( xten ) { confMan . modCommand ( "transfer" , x , xten ) ; } } ) ; $ ( "#" + kick _id ) . click ( function ( ) { confMan . modCommand ( "kick" , x ) ; } ) ; $ ( "#" + layer _set _id ) . click ( function ( ) { var cid = prompt ( "Please enter layer ID" , "" ) ; if ( cid ) { confMan . modCommand ( "vid-layer" , x , cid ) ; } } ) ; $ ( "#" + layer _next _id ) . click ( function ( ) { confMan . modCommand ( "vid-layer" , x , "next" ) ; } ) ; $ ( "#" + layer _prev _id ) . click ( function ( ) { confMan . modCommand ( "vid-layer" , x , "prev" ) ; } ) ; $ ( "#" + canvas _in _set _id ) . click ( function ( ) { var cid = prompt ( "Please enter canvas ID" , "" ) ; if ( cid ) { confMan . modCommand ( "vid-canvas" , x , cid ) ; } } ) ; $ ( "#" + canvas _out _set _id ) . click ( function ( ) { var cid = prompt ( "Please enter canvas ID" , "" ) ; if ( cid ) { confMan . modCommand ( "vid-watching-canvas" , x , cid ) ; } } ) ; $ ( "#" + canvas _in _next _id ) . click ( function ( ) { confMan . modCommand ( "vid-canvas" , x , "next" ) ; } ) ; $ ( "#" + canvas _in _prev _id ) . click ( function ( ) { confMan . modCommand ( "vid-canvas" , x , "prev" ) ; } ) ; $ ( "#" + canvas _out _next _id ) . click ( function ( ) { confMan . modCommand ( "vid-watching-canvas" , x , "next" ) ; } ) ; $ ( "#" + canvas _out _prev _id ) . click ( function ( ) { confMan . modCommand ( "vid-watching-canvas" , x , "prev" ) ; } ) ; $ ( "#" + tmute _id ) . click ( function ( ) { confMan . modCommand ( "tmute" , x ) ; } ) ; if ( confMan . params . hasVid ) { $ ( "#" + tvmute _id ) . click ( function ( ) { confMan . modCommand ( "tvmute" , x ) ; } ) ; $ ( "#" + tvpresenter _id ) . click ( function ( ) { confMan . modCommand ( "vid-res-id" , x , "presenter" ) ; } ) ; $ ( "#" + tvfloor _id ) . click ( function ( ) { confMan . modCommand ( "vid-floor" , x , "force" ) ; } ) ; $ ( "#" + vbanner _id ) . click ( function ( ) { var text = prompt ( "Please enter text" , "" ) ; if ( text ) { confMan . modCommand ( "vid-banner" , x , escape ( text ) ) ; } } ) ; }
2015-02-20 23:19:09 +00:00
$ ( "#" + volup _id ) . click ( function ( ) { confMan . modCommand ( "volume_in" , x , "up" ) ; } ) ; $ ( "#" + voldn _id ) . click ( function ( ) { confMan . modCommand ( "volume_in" , x , "down" ) ; } ) ; return html ; }
2015-07-24 00:09:24 +00:00
var atitle = "" ; var awidth = 0 ; verto . subscribe ( confMan . params . laData . chatChannel , { handler : function ( v , e ) { if ( typeof ( confMan . params . chatCallback ) === "function" ) { confMan . params . chatCallback ( v , e ) ; } } } ) ; if ( confMan . params . laData . role === "moderator" ) { atitle = "Action" ; awidth = 600 ; if ( confMan . params . mainModID ) { genMainMod ( $ ( confMan . params . mainModID ) ) ; $ ( confMan . params . displayID ) . html ( "Moderator Controls Ready<br><br>" ) ; } else { $ ( confMan . params . mainModID ) . html ( "" ) ; }
2015-04-09 19:29:23 +00:00
verto . subscribe ( confMan . params . laData . modChannel , { handler : function ( v , e ) { if ( confMan . params . onBroadcast ) { confMan . params . onBroadcast ( verto , confMan , e . data ) ; }
2015-07-02 22:55:04 +00:00
if ( e . data [ "conf-command" ] === "list-videoLayouts" ) { for ( var j = 0 ; j < confMan . canvasCount ; j ++ ) { var vlselect _id = "#confman_vl_select_" + j + "_" + confMan . serno ; var vlayout _id = "#confman_vid_layout_" + j + "_" + confMan . serno ; var x = 0 ; var options ; $ ( vlselect _id ) . selectmenu ( { } ) ; $ ( vlselect _id ) . selectmenu ( "enable" ) ; $ ( vlselect _id ) . empty ( ) ; $ ( vlselect _id ) . append ( new Option ( "Choose a Layout" , "none" ) ) ; if ( e . data . responseData ) { options = e . data . responseData . sort ( ) ; for ( var i in options ) { $ ( vlselect _id ) . append ( new Option ( options [ i ] , options [ i ] ) ) ; x ++ ; } }
if ( x ) { $ ( vlselect _id ) . selectmenu ( 'refresh' , true ) ; } else { $ ( vlayout _id ) . hide ( ) ; } } } else { if ( ! confMan . destroyed && confMan . params . displayID ) { $ ( confMan . params . displayID ) . html ( e . data . response + "<br><br>" ) ; if ( confMan . lastTimeout ) { clearTimeout ( confMan . lastTimeout ) ; confMan . lastTimeout = 0 ; }
2015-02-20 23:19:09 +00:00
confMan . lastTimeout = setTimeout ( function ( ) { $ ( confMan . params . displayID ) . html ( confMan . destroyed ? "" : "Moderator Controls Ready<br><br>" ) ; } , 4000 ) ; } } } } ) ; if ( confMan . params . hasVid ) { confMan . modCommand ( "list-videoLayouts" , null , null ) ; } }
2014-12-06 17:40:44 +00:00
var row _callback = null ; if ( confMan . params . laData . role === "moderator" ) { row _callback = function ( nRow , aData , iDisplayIndex , iDisplayIndexFull ) { if ( ! aData [ 5 ] ) { var $row = $ ( 'td:eq(5)' , nRow ) ; genControls ( $row , aData ) ; if ( confMan . params . onLaRow ) { confMan . params . onLaRow ( verto , confMan , $row , aData ) ; } } } ; }
2015-07-24 00:09:24 +00:00
confMan . lt = new $ . verto . liveTable ( verto , confMan . params . laData . laChannel , confMan . params . laData . laName , $ ( confMan . params . tableID ) , { subParams : { callID : confMan . params . dialog ? confMan . params . dialog . callID : null } , "onChange" : function ( obj , args ) { $ ( confMan . params . statusID ) . text ( "Conference Members: " + " (" + obj . arrayLen ( ) + " Total)" ) ; if ( confMan . params . onLaChange ) { confMan . params . onLaChange ( verto , confMan , $ . verto . enum . confEvent . laChange , obj , args ) ; } } , "aaData" : [ ] , "aoColumns" : [ { "sTitle" : "ID" , "sWidth" : "50" } , { "sTitle" : "Number" , "sWidth" : "250" } , { "sTitle" : "Name" , "sWidth" : "250" } , { "sTitle" : "Codec" , "sWidth" : "100" } , { "sTitle" : "Status" , "sWidth" : confMan . params . hasVid ? "200px" : "150px" } , { "sTitle" : atitle , "sWidth" : awidth , } ] , "bAutoWidth" : true , "bDestroy" : true , "bSort" : false , "bInfo" : false , "bFilter" : false , "bLengthChange" : false , "bPaginate" : false , "iDisplayLength" : 1400 , "oLanguage" : { "sEmptyTable" : "The Conference is Empty....." } , "fnRowCallback" : row _callback } ) ; } ; $ . verto . confMan . prototype . modCommand = function ( cmd , id , value ) { var confMan = this ; confMan . verto . rpcClient . call ( "verto.broadcast" , { "eventChannel" : confMan . params . laData . modChannel , "data" : { "application" : "conf-control" , "command" : cmd , "id" : id , "value" : value } } ) ; } ; $ . verto . confMan . prototype . sendChat = function ( message , type ) { var confMan = this ; confMan . verto . rpcClient . call ( "verto.broadcast" , { "eventChannel" : confMan . params . laData . chatChannel , "data" : { "action" : "send" , "message" : message , "type" : type } } ) ; } ; $ . verto . confMan . prototype . destroy = function ( ) { var confMan = this ; confMan . destroyed = true ; if ( confMan . lt ) { confMan . lt . destroy ( ) ; }
if ( confMan . params . laData . chatChannel ) { confMan . verto . unsubscribe ( confMan . params . laData . chatChannel ) ; }
2014-12-06 17:40:44 +00:00
if ( confMan . params . laData . modChannel ) { confMan . verto . unsubscribe ( confMan . params . laData . modChannel ) ; }
2015-08-28 14:42:37 +00:00
if ( confMan . params . mainModID ) { $ ( confMan . params . mainModID ) . html ( "" ) ; } } ; $ . verto . dialog = function ( direction , verto , params ) { var dialog = this ; dialog . params = $ . extend ( { useVideo : verto . options . useVideo , useStereo : verto . options . useStereo , screenShare : false , useCamera : verto . options . deviceParams . useCamera , useMic : verto . options . deviceParams . useMic , useSpeak : verto . options . deviceParams . useSpeak , tag : verto . options . tag , localTag : verto . options . localTag , login : verto . options . login , videoParams : verto . options . videoParams } , params ) ; dialog . verto = verto ; dialog . direction = direction ; dialog . lastState = null ; dialog . state = dialog . lastState = $ . verto . enum . state . new ; dialog . callbacks = verto . callbacks ; dialog . answered = false ; dialog . attach = params . attach || false ; dialog . screenShare = params . screenShare || false ; dialog . useCamera = dialog . params . useCamera ; dialog . useMic = dialog . params . useMic ; dialog . useSpeak = dialog . params . useSpeak ; if ( dialog . params . callID ) { dialog . callID = dialog . params . callID ; } else { dialog . callID = dialog . params . callID = generateGUID ( ) ; }
2014-12-06 17:40:44 +00:00
if ( dialog . params . tag ) { dialog . audioStream = document . getElementById ( dialog . params . tag ) ; if ( dialog . params . useVideo ) { dialog . videoStream = dialog . audioStream ; } }
2015-01-24 09:13:44 +00:00
if ( dialog . params . localTag ) { dialog . localVideo = document . getElementById ( dialog . params . localTag ) ; }
2014-12-06 17:40:44 +00:00
dialog . verto . dialogs [ dialog . callID ] = dialog ; var RTCcallbacks = { } ; if ( dialog . direction == $ . verto . enum . direction . inbound ) { if ( dialog . params . display _direction === "outbound" ) { dialog . params . remote _caller _id _name = dialog . params . caller _id _name ; dialog . params . remote _caller _id _number = dialog . params . caller _id _number ; } else { dialog . params . remote _caller _id _name = dialog . params . callee _id _name ; dialog . params . remote _caller _id _number = dialog . params . callee _id _number ; }
if ( ! dialog . params . remote _caller _id _name ) { dialog . params . remote _caller _id _name = "Nobody" ; }
if ( ! dialog . params . remote _caller _id _number ) { dialog . params . remote _caller _id _number = "UNKNOWN" ; }
RTCcallbacks . onMessage = function ( rtc , msg ) { console . debug ( msg ) ; } ; RTCcallbacks . onAnswerSDP = function ( rtc , sdp ) { console . error ( "answer sdp" , sdp ) ; } ; } else { dialog . params . remote _caller _id _name = "Outbound Call" ; dialog . params . remote _caller _id _number = dialog . params . destination _number ; }
2015-08-28 14:42:37 +00:00
RTCcallbacks . onICESDP = function ( rtc ) { console . log ( "RECV " + rtc . type + " SDP" , rtc . mediaData . SDP ) ; if ( dialog . state == $ . verto . enum . state . requesting || dialog . state == $ . verto . enum . state . answering || dialog . state == $ . verto . enum . state . active ) { location . reload ( ) ; return ; }
2015-09-22 16:21:15 +00:00
if ( rtc . type == "offer" ) { if ( dialog . state == $ . verto . enum . state . active ) { dialog . setState ( $ . verto . enum . state . requesting ) ; dialog . sendMethod ( "verto.attach" , { sdp : rtc . mediaData . SDP } ) ; } else { dialog . setState ( $ . verto . enum . state . requesting ) ; dialog . sendMethod ( "verto.invite" , { sdp : rtc . mediaData . SDP } ) ; } } else { dialog . setState ( $ . verto . enum . state . answering ) ; dialog . sendMethod ( dialog . attach ? "verto.attach" : "verto.answer" , { sdp : dialog . rtc . mediaData . SDP } ) ; } } ; RTCcallbacks . onICE = function ( rtc ) { if ( rtc . type == "offer" ) { console . log ( "offer" , rtc . mediaData . candidate ) ; return ; } } ; RTCcallbacks . onStream = function ( rtc , stream ) { console . log ( "stream started" ) ; } ; RTCcallbacks . onError = function ( e ) { console . error ( "ERROR:" , e ) ; dialog . hangup ( { cause : "Device or Permission Error" } ) ; } ; dialog . rtc = new $ . FSRTC ( { callbacks : RTCcallbacks , localVideo : dialog . screenShare ? null : dialog . localVideo , useVideo : dialog . params . useVideo ? dialog . videoStream : null , useAudio : dialog . audioStream , useStereo : dialog . params . useStereo , videoParams : dialog . params . videoParams , audioParams : verto . options . audioParams , iceServers : verto . options . iceServers , screenShare : dialog . screenShare , useCamera : dialog . useCamera , useMic : dialog . useMic , useSpeak : dialog . useSpeak } ) ; dialog . rtc . verto = dialog . verto ; if ( dialog . direction == $ . verto . enum . direction . inbound ) { if ( dialog . attach ) { dialog . answer ( ) ; } else { dialog . ring ( ) ; } } } ; $ . verto . dialog . prototype . invite = function ( ) { var dialog = this ; dialog . rtc . call ( ) ; } ; $ . verto . dialog . prototype . sendMethod = function ( method , obj ) { var dialog = this ; obj . dialogParams = { } ; for ( var i in dialog . params ) { if ( i == "sdp" && method != "verto.invite" && method != "verto.attach" ) { continue ; }
2014-12-06 17:40:44 +00:00
obj . dialogParams [ i ] = dialog . params [ i ] ; }
dialog . verto . rpcClient . call ( method , obj , function ( e ) { dialog . processReply ( method , true , e ) ; } , function ( e ) { dialog . processReply ( method , false , e ) ; } ) ; } ; function checkStateChange ( oldS , newS ) { if ( newS == $ . verto . enum . state . purge || $ . verto . enum . states [ oldS . name ] [ newS . name ] ) { return true ; }
return false ; }
$ . verto . dialog . prototype . setState = function ( state ) { var dialog = this ; if ( dialog . state == $ . verto . enum . state . ringing ) { dialog . stopRinging ( ) ; }
if ( dialog . state == state || ! checkStateChange ( dialog . state , state ) ) { console . error ( "Dialog " + dialog . callID + ": INVALID state change from " + dialog . state . name + " to " + state . name ) ; dialog . hangup ( ) ; return false ; }
2015-08-28 22:12:06 +00:00
console . log ( "Dialog " + dialog . callID + ": state change from " + dialog . state . name + " to " + state . name ) ; dialog . lastState = dialog . state ; dialog . state = state ; if ( ! dialog . causeCode ) { dialog . causeCode = 16 ; }
2014-12-06 17:40:44 +00:00
if ( ! dialog . cause ) { dialog . cause = "NORMAL CLEARING" ; }
if ( dialog . callbacks . onDialogState ) { dialog . callbacks . onDialogState ( this ) ; }
2015-07-21 15:59:17 +00:00
switch ( dialog . state ) { case $ . verto . enum . state . early : case $ . verto . enum . state . active : var speaker = dialog . useSpeak ; console . info ( "Using Speaker: " , speaker ) ; if ( speaker && speaker !== "any" ) { var videoElement = dialog . audioStream ; setTimeout ( function ( ) { console . info ( "Setting speaker:" , videoElement , speaker ) ; attachSinkId ( videoElement , speaker ) ; } , 500 ) ; }
break ; case $ . verto . enum . state . trying : setTimeout ( function ( ) { if ( dialog . state == $ . verto . enum . state . trying ) { dialog . setState ( $ . verto . enum . state . hangup ) ; } } , 30000 ) ; break ; case $ . verto . enum . state . purge : dialog . setState ( $ . verto . enum . state . destroy ) ; break ; case $ . verto . enum . state . hangup : if ( dialog . lastState . val > $ . verto . enum . state . requesting . val && dialog . lastState . val < $ . verto . enum . state . hangup . val ) { dialog . sendMethod ( "verto.bye" , { } ) ; }
2015-09-22 16:21:15 +00:00
dialog . setState ( $ . verto . enum . state . destroy ) ; break ; case $ . verto . enum . state . destroy : delete dialog . verto . dialogs [ dialog . callID ] ; if ( dialog . params . screenShare ) { dialog . rtc . stopPeer ( ) ; } else { dialog . rtc . stop ( ) ; }
2015-02-17 03:21:10 +00:00
break ; }
2014-12-06 17:40:44 +00:00
return true ; } ; $ . verto . dialog . prototype . processReply = function ( method , success , e ) { var dialog = this ; switch ( method ) { case "verto.answer" : case "verto.attach" : if ( success ) { dialog . setState ( $ . verto . enum . state . active ) ; } else { dialog . hangup ( ) ; }
break ; case "verto.invite" : if ( success ) { dialog . setState ( $ . verto . enum . state . trying ) ; } else { dialog . setState ( $ . verto . enum . state . destroy ) ; }
break ; case "verto.bye" : dialog . hangup ( ) ; break ; case "verto.modify" : if ( e . holdState ) { if ( e . holdState == "held" ) { if ( dialog . state != $ . verto . enum . state . held ) { dialog . setState ( $ . verto . enum . state . held ) ; } } else if ( e . holdState == "active" ) { if ( dialog . state != $ . verto . enum . state . active ) { dialog . setState ( $ . verto . enum . state . active ) ; } } }
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 ; } }
2015-03-24 17:49:06 +00:00
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 ; }
2015-08-20 22:14:03 +00:00
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 ++ ; }
2014-12-06 17:40:44 +00:00
if ( ! msg . body ) { console . error ( "Missing Body" ) ; err ++ ; }
if ( err ) { return false ; }
2015-02-19 23:08:36 +00:00
dialog . sendMethod ( "verto.info" , { msg : msg } ) ; return true ; } ; $ . verto . dialog . prototype . answer = function ( params ) { var dialog = this ; if ( ! dialog . answered ) { if ( ! params ) { params = { } ; }
2015-08-25 21:04:34 +00:00
params . sdp = dialog . params . sdp ; if ( params ) { if ( params . useVideo ) { dialog . useVideo ( true ) ; }
2015-08-28 14:42:37 +00:00
dialog . params . callee _id _name = params . callee _id _name ; dialog . params . callee _id _number = params . callee _id _number ; if ( params . useCamera ) { dialog . useCamera = params . useCamera ; }
if ( params . useMic ) { dialog . useMic = params . useMic ; }
if ( params . useSpeak ) { dialog . useSpeak = params . useSpeak ; } }
2015-02-19 23:08:36 +00:00
dialog . rtc . createAnswer ( params ) ; dialog . answered = true ; } } ; $ . verto . dialog . prototype . handleAnswer = function ( params ) { var dialog = this ; dialog . gotAnswer = true ; if ( dialog . state . val >= $ . verto . enum . state . active . val ) { return ; }
2014-12-06 17:40:44 +00:00
if ( dialog . state . val >= $ . verto . enum . state . early . val ) { dialog . setState ( $ . verto . enum . state . active ) ; } else { if ( dialog . gotEarly ) { console . log ( "Dialog " + dialog . callID + " Got answer while still establishing early media, delaying..." ) ; } else { console . log ( "Dialog " + dialog . callID + " Answering Channel" ) ; dialog . rtc . answer ( params . sdp , function ( ) { dialog . setState ( $ . verto . enum . state . active ) ; } , function ( e ) { console . error ( e ) ; dialog . hangup ( ) ; } ) ; console . log ( "Dialog " + dialog . callID + "ANSWER SDP" , params . sdp ) ; } } } ; $ . verto . dialog . prototype . cidString = function ( enc ) { var dialog = this ; var party = dialog . params . remote _caller _id _name + ( enc ? " <" : " <" ) + dialog . params . remote _caller _id _number + ( enc ? ">" : ">" ) ; return party ; } ; $ . verto . dialog . prototype . sendMessage = function ( msg , params ) { var dialog = this ; if ( dialog . callbacks . onMessage ) { dialog . callbacks . onMessage ( dialog . verto , dialog , msg , params ) ; } } ; $ . verto . dialog . prototype . handleInfo = function ( params ) { var dialog = this ; dialog . sendMessage ( $ . verto . enum . message . info , params . msg ) ; } ; $ . verto . dialog . prototype . handleDisplay = function ( params ) { var dialog = this ; if ( params . display _name ) { dialog . params . remote _caller _id _name = params . display _name ; }
if ( params . display _number ) { dialog . params . remote _caller _id _number = params . display _number ; }
dialog . sendMessage ( $ . verto . enum . message . display , { } ) ; } ; $ . verto . dialog . prototype . handleMedia = function ( params ) { var dialog = this ; if ( dialog . state . val >= $ . verto . enum . state . early . val ) { return ; }
2015-08-28 14:42:37 +00:00
dialog . gotEarly = true ; dialog . rtc . answer ( params . sdp , function ( ) { console . log ( "Dialog " + dialog . callID + "Establishing early media" ) ; dialog . setState ( $ . verto . enum . state . early ) ; if ( dialog . gotAnswer ) { console . log ( "Dialog " + dialog . callID + "Answering Channel" ) ; dialog . setState ( $ . verto . enum . state . active ) ; } } , function ( e ) { console . error ( e ) ; dialog . hangup ( ) ; } ) ; console . log ( "Dialog " + dialog . callID + "EARLY SDP" , params . sdp ) ; } ; $ . verto . ENUM = function ( s ) { var i = 0 , o = { } ; s . split ( " " ) . map ( function ( x ) { o [ x ] = { name : x , val : i ++ } ; } ) ; return Object . freeze ( o ) ; } ; $ . verto . enum = { } ; $ . verto . enum . states = Object . freeze ( { new : { requesting : 1 , recovering : 1 , ringing : 1 , destroy : 1 , answering : 1 , hangup : 1 } , requesting : { trying : 1 , hangup : 1 , active : 1 } , recovering : { answering : 1 , hangup : 1 } , trying : { active : 1 , early : 1 , hangup : 1 } , ringing : { answering : 1 , hangup : 1 } , answering : { active : 1 , hangup : 1 } , active : { answering : 1 , requesting : 1 , hangup : 1 , held : 1 } , held : { hangup : 1 , active : 1 } , early : { hangup : 1 , active : 1 } , hangup : { destroy : 1 } , destroy : { } , purge : { destroy : 1 } } ) ; $ . verto . enum . state = $ . verto . ENUM ( "new requesting trying recovering ringing answering early active held hangup destroy purge" ) ; $ . verto . enum . direction = $ . verto . ENUM ( "inbound outbound" ) ; $ . verto . enum . message = $ . verto . ENUM ( "display info pvtEvent" ) ; $ . verto . enum = Object . freeze ( $ . verto . enum ) ; $ . verto . saved = [ ] ; $ . verto . unloadJobs = [ ] ; $ ( window ) . bind ( 'beforeunload' , function ( ) { for ( var f in $ . verto . unloadJobs ) { $ . verto . unloadJobs [ f ] ( ) ; }
2015-07-02 22:55:04 +00:00
for ( var i in $ . verto . saved ) { var verto = $ . verto . saved [ i ] ; if ( verto ) { verto . purge ( ) ; verto . logout ( ) ; } }
2015-07-21 15:59:17 +00:00
return $ . verto . warnOnUnload ; } ) ; $ . verto . videoDevices = [ ] ; $ . verto . audioInDevices = [ ] ; $ . verto . audioOutDevices = [ ] ; var checkDevices = function ( runtime ) { console . info ( "enumerating devices" ) ; var aud _in = [ ] , aud _out = [ ] , vid = [ ] ; if ( ( ! navigator . mediaDevices || ! navigator . mediaDevices . enumerateDevices ) && MediaStreamTrack . getSources ) { MediaStreamTrack . getSources ( function ( media _sources ) { for ( var i = 0 ; i < media _sources . length ; i ++ ) { if ( media _sources [ i ] . kind == 'video' ) { vid . push ( media _sources [ i ] ) ; } else { aud _in . push ( media _sources [ i ] ) ; } }
$ . verto . videoDevices = vid ; $ . verto . audioInDevices = aud _in ; console . info ( "Audio Devices" , $ . verto . audioInDevices ) ; console . info ( "Video Devices" , $ . verto . videoDevices ) ; runtime ( ) ; } ) ; } else { if ( ! navigator . mediaDevices || ! navigator . mediaDevices . enumerateDevices ) { console . log ( "enumerateDevices() not supported." ) ; return ; }
2015-09-19 01:54:24 +00:00
navigator . mediaDevices . enumerateDevices ( ) . then ( function ( devices ) { devices . forEach ( function ( device ) { console . log ( device ) ; console . log ( device . kind + ": " + device . label + " id = " + device . deviceId ) ; if ( device . kind === "videoinput" ) { vid . push ( { id : device . deviceId , kind : "video" , label : device . label } ) ; } else if ( device . kind === "audioinput" ) { aud _in . push ( { id : device . deviceId , kind : "audio_in" , label : device . label } ) ; } else if ( device . kind === "audiooutput" ) { aud _out . push ( { id : device . deviceId , kind : "audio_out" , label : device . label } ) ; } } ) ; $ . verto . videoDevices = vid ; $ . verto . audioInDevices = aud _in ; $ . verto . audioOutDevices = aud _out ; console . info ( "Audio IN Devices" , $ . verto . audioInDevices ) ; console . info ( "Audio Out Devices" , $ . verto . audioOutDevices ) ; console . info ( "Video Devices" , $ . verto . videoDevices ) ; runtime ( ) ; } ) . catch ( function ( err ) { console . log ( " Device Enumeration ERROR: " + err . name + ": " + err . message ) ; runtime ( ) ; } ) ; } } ; $ . verto . refreshDevices = function ( runtime ) { checkDevices ( runtime ) ; }
2015-09-17 20:09:19 +00:00
$ . verto . init = function ( obj , runtime ) { $ . FSRTC . checkPerms ( function ( ) { checkDevices ( runtime ) ; } , true , true ) ; }
2015-07-02 22:55:04 +00:00
$ . verto . genUUID = function ( ) { return generateGUID ( ) ; } } ) ( jQuery ) ;