2014-08-16 22:38:13 -07:00
( function ( window , chrome , console ) {
// Based on https://github.com/googlecast/CastVideos-chrome/blob/master/CastVideos.js
/ * *
* Constants of states for Chromecast device
* * /
2014-07-07 19:27:17 -07:00
var DEVICE _STATE = {
2014-08-16 22:38:13 -07:00
'IDLE' : 0 ,
'ACTIVE' : 1 ,
'WARNING' : 2 ,
2014-07-07 19:27:17 -07:00
'ERROR' : 3 ,
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Constants of states for CastPlayer
* * /
2014-07-07 19:27:17 -07:00
var PLAYER _STATE = {
2014-08-16 22:38:13 -07:00
'IDLE' : 'IDLE' ,
'LOADING' : 'LOADING' ,
'LOADED' : 'LOADED' ,
'PLAYING' : 'PLAYING' ,
'PAUSED' : 'PAUSED' ,
'STOPPED' : 'STOPPED' ,
'SEEKING' : 'SEEKING' ,
2014-07-07 19:27:17 -07:00
'ERROR' : 'ERROR'
2014-08-16 22:38:13 -07:00
} ;
var PlayerName = 'Chromecast' ;
2014-08-17 11:24:48 -07:00
var messageNamespace = 'urn:x-cast:com.google.cast.mediabrowser.v3' ;
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
var cPlayer = {
deviceState : DEVICE _STATE . IDLE
2014-08-16 22:38:13 -07:00
} ;
var CastPlayer = function ( ) {
/* device variables */
// @type {DEVICE_STATE} A state for device
this . deviceState = DEVICE _STATE . IDLE ;
/* Cast player variables */
// @type {Object} a chrome.cast.media.Media object
this . currentMediaSession = null ;
// @type {string} a chrome.cast.Session object
this . session = null ;
// @type {PLAYER_STATE} A state for Cast media player
this . castPlayerState = PLAYER _STATE . IDLE ;
this . hasReceivers = false ;
// bind once - commit 2ebffc2271da0bc5e8b13821586aee2a2e3c7753
this . errorHandler = this . onError . bind ( this ) ;
this . mediaStatusUpdateHandler = this . onMediaStatusUpdate . bind ( this ) ;
2014-07-07 19:27:17 -07:00
this . initializeCastPlayer ( ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Initialize Cast media player
* Initializes the API . Note that either successCallback and errorCallback will be
* invoked once the API has finished initialization . The sessionListener and
* receiverListener may be invoked at any time afterwards , and possibly more than once .
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . initializeCastPlayer = function ( ) {
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( ! chrome ) {
return ;
2014-08-16 22:38:13 -07:00
}
2014-07-07 19:27:17 -07:00
if ( ! chrome . cast || ! chrome . cast . isAvailable ) {
2014-08-16 22:38:13 -07:00
setTimeout ( this . initializeCastPlayer . bind ( this ) , 1000 ) ;
2014-07-07 19:27:17 -07:00
return ;
2014-08-16 22:38:13 -07:00
}
// v1 Id AE4DA10A
// v2 Id 472F0435
2014-08-17 11:12:17 -07:00
// v3 Id 69C59853
2014-09-17 21:50:21 -07:00
// v4 Id F4EB2E8E
2014-08-16 22:38:13 -07:00
// default receiver chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
2015-04-05 20:47:01 -07:00
var applicationID = "69C59853" ;
2014-08-16 22:38:13 -07:00
// request session
var sessionRequest = new chrome . cast . SessionRequest ( applicationID ) ;
var apiConfig = new chrome . cast . ApiConfig ( sessionRequest ,
this . sessionListener . bind ( this ) ,
this . receiverListener . bind ( this ) ) ;
console . log ( 'chromecast.initialize' ) ;
2014-07-07 19:27:17 -07:00
chrome . cast . initialize ( apiConfig , this . onInitSuccess . bind ( this ) , this . errorHandler ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Callback function for init success
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onInitSuccess = function ( ) {
2014-08-16 22:38:13 -07:00
this . isInitialized = true ;
2014-07-07 19:27:17 -07:00
console . log ( "chromecast init success" ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Generic error callback function
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onError = function ( ) {
console . log ( "chromecast error" ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* @ param { ! Object } e A new session
* This handles auto - join when a page is reloaded
* When active session is detected , playback will automatically
* join existing session and occur in Cast mode and media
* status gets synced up with current media of the session
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . sessionListener = function ( e ) {
2014-08-16 22:38:13 -07:00
this . session = e ;
2014-07-07 19:27:17 -07:00
if ( this . session ) {
2014-08-16 22:38:13 -07:00
2014-08-18 18:42:53 -07:00
console . log ( 'sessionListener ' + JSON . stringify ( e ) ) ;
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( this . session . media [ 0 ] ) {
this . onMediaDiscovered ( 'activeSession' , this . session . media [ 0 ] ) ;
2014-08-16 22:38:13 -07:00
}
2014-08-18 07:20:02 -07:00
this . onSessionConnected ( e ) ;
2014-07-07 19:27:17 -07:00
}
2014-08-16 22:38:13 -07:00
} ;
CastPlayer . prototype . messageListener = function ( namespace , message ) {
2014-08-17 20:00:37 -07:00
message = JSON . parse ( message ) ;
if ( message . type && message . type . indexOf ( 'playback' ) == 0 ) {
$ ( this ) . trigger ( message . type , [ message . data ] ) ;
}
2014-08-16 22:38:13 -07:00
} ;
/ * *
* @ param { string } e Receiver availability
* This indicates availability of receivers but
* does not provide a list of device IDs
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . receiverListener = function ( e ) {
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( e === 'available' ) {
2014-08-16 22:38:13 -07:00
console . log ( "chromecast receiver found" ) ;
2014-07-07 19:27:17 -07:00
this . hasReceivers = true ;
2014-08-16 22:38:13 -07:00
}
2014-07-07 19:27:17 -07:00
else {
2014-08-16 22:38:13 -07:00
console . log ( "chromecast receiver list empty" ) ;
2014-07-07 19:27:17 -07:00
this . hasReceivers = false ;
}
2014-08-16 22:38:13 -07:00
} ;
/ * *
* session update listener
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . sessionUpdateListener = function ( isAlive ) {
2014-08-16 22:38:13 -07:00
console . log ( 'sessionUpdateListener alive: ' + isAlive ) ;
if ( isAlive ) {
}
else {
this . session = null ;
this . deviceState = DEVICE _STATE . IDLE ;
this . castPlayerState = PLAYER _STATE . IDLE ;
this . currentMediaSession = null ;
2014-07-07 19:27:17 -07:00
MediaController . removeActivePlayer ( PlayerName ) ;
}
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Requests that a receiver application session be created or joined . By default , the SessionRequest
* passed to the API at initialization time is used ; this may be overridden by passing a different
* session request in opt _sessionRequest .
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . launchApp = function ( ) {
2014-08-16 22:38:13 -07:00
console . log ( "chromecast launching app..." ) ;
chrome . cast . requestSession ( this . onRequestSessionSuccess . bind ( this ) , this . onLaunchError . bind ( this ) ) ;
} ;
/ * *
* Callback function for request session success
* @ param { Object } e A chrome . cast . Session object
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onRequestSessionSuccess = function ( e ) {
2014-08-18 07:20:02 -07:00
2014-08-16 22:38:13 -07:00
console . log ( "chromecast session success: " + e . sessionId ) ;
2014-08-18 07:20:02 -07:00
this . onSessionConnected ( e ) ;
} ;
CastPlayer . prototype . onSessionConnected = function ( session ) {
this . session = session ;
2014-08-16 22:38:13 -07:00
this . deviceState = DEVICE _STATE . ACTIVE ;
2014-08-18 07:20:02 -07:00
this . session . addMessageListener ( messageNamespace , this . messageListener . bind ( this ) ) ;
2014-08-18 19:49:16 -07:00
this . session . addMediaListener ( this . sessionMediaListener . bind ( this ) ) ;
2014-07-07 19:27:17 -07:00
this . session . addUpdateListener ( this . sessionUpdateListener . bind ( this ) ) ;
2014-08-18 07:20:02 -07:00
$ ( this ) . trigger ( 'connect' ) ;
MediaController . setActivePlayer ( PlayerName ) ;
2014-08-19 15:28:35 -07:00
this . sendMessage ( {
options : { } ,
command : 'Identify'
} ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-08-18 19:49:16 -07:00
/ * *
* session update listener
* /
CastPlayer . prototype . sessionMediaListener = function ( e ) {
console . log ( 'sessionMediaListener' ) ;
this . currentMediaSession = e ;
this . currentMediaSession . addUpdateListener ( this . mediaStatusUpdateHandler ) ;
} ;
2014-08-16 22:38:13 -07:00
/ * *
* Callback function for launch error
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onLaunchError = function ( ) {
2014-08-16 22:38:13 -07:00
console . log ( "chromecast launch error" ) ;
this . deviceState = DEVICE _STATE . ERROR ;
2014-08-17 20:00:37 -07:00
//Dashboard.alert({
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
// title: Globalize.translate("Error"),
// message: Globalize.translate("ErrorLaunchingChromecast")
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
//});
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
MediaController . removeActivePlayer ( PlayerName ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Stops the running receiver application associated with the session .
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . stopApp = function ( ) {
2014-08-16 22:38:13 -07:00
this . session . stop ( this . onStopAppSuccess . bind ( this , 'Session stopped' ) ,
2014-07-07 19:27:17 -07:00
this . errorHandler ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Callback function for stop app success
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onStopAppSuccess = function ( message ) {
2014-08-16 22:38:13 -07:00
console . log ( message ) ;
this . deviceState = DEVICE _STATE . IDLE ;
this . castPlayerState = PLAYER _STATE . IDLE ;
this . currentMediaSession = null ;
} ;
/ * *
* Loads media into a running receiver application
* @ param { Number } mediaIndex An index number to indicate current media content
* /
CastPlayer . prototype . loadMedia = function ( options , command ) {
2014-07-07 19:27:17 -07:00
if ( ! this . session ) {
2014-08-16 22:38:13 -07:00
console . log ( "no session" ) ;
2014-07-07 19:27:17 -07:00
return ;
2014-08-09 22:29:45 -07:00
}
2014-08-18 20:25:56 -07:00
// Convert the items to smaller stubs to send the minimal amount of information
options . items = options . items . map ( function ( i ) {
return {
Id : i . Id ,
Name : i . Name ,
Type : i . Type ,
MediaType : i . MediaType ,
IsFolder : i . IsFolder
} ;
} ) ;
2014-08-18 19:49:16 -07:00
this . sendMessage ( {
2014-08-16 22:38:13 -07:00
options : options ,
2014-08-18 19:49:16 -07:00
command : command
} ) ;
} ;
2014-08-19 15:28:35 -07:00
var endpointInfo ;
function getEndpointInfo ( ) {
if ( endpointInfo ) {
var deferred = $ . Deferred ( ) ;
deferred . resolveWith ( null , [ endpointInfo ] ) ;
return deferred . promise ( ) ;
}
return ApiClient . getJSON ( ApiClient . getUrl ( 'System/Endpoint' ) ) . done ( function ( info ) {
endpointInfo = info ;
} ) ;
}
2014-08-18 19:49:16 -07:00
CastPlayer . prototype . sendMessage = function ( message ) {
2014-08-16 22:38:13 -07:00
2014-08-18 19:49:16 -07:00
var player = this ;
2014-09-16 18:38:50 -07:00
var bitrateSetting = AppSettings . maxStreamingBitrate ( ) ;
2014-08-21 19:24:38 -07:00
bitrateSetting = Math . min ( bitrateSetting , 10000000 ) ;
2014-08-25 19:30:52 -07:00
var receiverName = null ;
if ( castPlayer . session && castPlayer . session . receiver && castPlayer . session . receiver . friendlyName ) {
receiverName = castPlayer . session . receiver . friendlyName ;
}
2014-08-18 19:49:16 -07:00
message = $ . extend ( message , {
2014-08-16 22:38:13 -07:00
userId : Dashboard . getCurrentUserId ( ) ,
deviceId : ApiClient . deviceId ( ) ,
accessToken : ApiClient . accessToken ( ) ,
2014-08-21 19:24:38 -07:00
serverAddress : ApiClient . serverAddress ( ) ,
2014-08-25 19:30:52 -07:00
maxBitrate : bitrateSetting ,
receiverName : receiverName
2014-08-18 19:49:16 -07:00
} ) ;
2014-08-16 22:38:13 -07:00
2014-08-19 15:28:35 -07:00
getEndpointInfo ( ) . done ( function ( endpoint ) {
2014-08-18 09:25:59 -07:00
2014-08-19 15:28:35 -07:00
if ( endpoint . IsLocal || endpoint . IsInNetwork ) {
ApiClient . getSystemInfo ( ) . done ( function ( info ) {
2014-08-18 09:25:59 -07:00
2014-08-19 15:28:35 -07:00
message . serverAddress = info . LocalAddress ;
player . sendMessageInternal ( message ) ;
} ) ;
} else {
2014-08-18 19:49:16 -07:00
player . sendMessageInternal ( message ) ;
2014-08-19 15:28:35 -07:00
}
} ) ;
2014-08-18 09:25:59 -07:00
} ;
2014-08-18 19:49:16 -07:00
CastPlayer . prototype . sendMessageInternal = function ( message ) {
2014-08-16 22:38:13 -07:00
message = JSON . stringify ( message ) ;
//console.log(message);
this . session . sendMessage ( messageNamespace , message , this . onPlayCommandSuccess . bind ( this ) , this . errorHandler ) ;
2014-08-18 19:49:16 -07:00
} ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
CastPlayer . prototype . onPlayCommandSuccess = function ( ) {
2014-08-18 09:25:59 -07:00
console . log ( 'Message was sent to receiver ok.' ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Callback function for loadMedia success
* @ param { Object } mediaSession A new media object .
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onMediaDiscovered = function ( how , mediaSession ) {
2014-08-16 22:38:13 -07:00
console . log ( "chromecast new media session ID:" + mediaSession . mediaSessionId + ' (' + how + ')' ) ;
this . currentMediaSession = mediaSession ;
2014-07-07 19:27:17 -07:00
if ( how == 'loadMedia' ) {
2014-08-16 22:38:13 -07:00
this . castPlayerState = PLAYER _STATE . PLAYING ;
}
2014-07-07 19:27:17 -07:00
if ( how == 'activeSession' ) {
this . castPlayerState = mediaSession . playerState ;
2014-08-16 22:38:13 -07:00
}
this . currentMediaSession . addUpdateListener ( this . mediaStatusUpdateHandler ) ;
} ;
/ * *
* Callback function when media load returns error
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onLoadMediaError = function ( e ) {
2014-08-16 22:38:13 -07:00
console . log ( "chromecast media error" ) ;
2014-07-07 19:27:17 -07:00
this . castPlayerState = PLAYER _STATE . IDLE ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Callback function for media status update from receiver
* @ param { ! Boolean } e true / false
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onMediaStatusUpdate = function ( e ) {
2014-08-17 11:12:17 -07:00
2014-07-07 19:27:17 -07:00
if ( e == false ) {
this . castPlayerState = PLAYER _STATE . IDLE ;
2014-08-16 22:38:13 -07:00
}
2014-08-17 20:00:37 -07:00
console . log ( "chromecast updating media: " + e ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Play media in Cast mode
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . playMedia = function ( ) {
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( ! this . currentMediaSession ) {
return ;
2014-08-16 22:38:13 -07:00
}
2014-08-19 15:28:35 -07:00
this . currentMediaSession . play ( null , this . mediaCommandSuccessCallback . bind ( this , "playing started for " + this . currentMediaSession . sessionId ) , this . errorHandler ) ;
//this.currentMediaSession.addUpdateListener(this.mediaStatusUpdateHandler);
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Pause media playback in Cast mode
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . pauseMedia = function ( ) {
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( ! this . currentMediaSession ) {
return ;
2014-08-16 22:38:13 -07:00
}
2014-08-19 15:28:35 -07:00
this . currentMediaSession . pause ( null , this . mediaCommandSuccessCallback . bind ( this , "paused " + this . currentMediaSession . sessionId ) , this . errorHandler ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Stop CC playback
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . stopMedia = function ( ) {
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( ! this . currentMediaSession ) {
return ;
2014-08-16 22:38:13 -07:00
}
this . currentMediaSession . stop ( null ,
this . mediaCommandSuccessCallback . bind ( this , "stopped " + this . currentMediaSession . sessionId ) ,
this . errorHandler ) ;
this . castPlayerState = PLAYER _STATE . STOPPED ;
} ;
/ * *
* Set media volume in Cast mode
* @ param { Boolean } mute A boolean
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . setReceiverVolume = function ( mute , vol ) {
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
if ( ! this . currentMediaSession ) {
return ;
2014-08-16 22:38:13 -07:00
}
2014-07-07 19:27:17 -07:00
if ( ! mute ) {
2014-08-17 20:00:37 -07:00
2014-08-21 08:55:35 -07:00
this . session . setReceiverVolumeLevel ( ( vol || 1 ) ,
2014-08-16 22:38:13 -07:00
this . mediaCommandSuccessCallback . bind ( this ) ,
2014-07-07 19:27:17 -07:00
this . errorHandler ) ;
2014-08-16 22:38:13 -07:00
}
2014-07-07 19:27:17 -07:00
else {
2014-08-16 22:38:13 -07:00
this . session . setReceiverMuted ( true ,
this . mediaCommandSuccessCallback . bind ( this ) ,
2014-07-07 19:27:17 -07:00
this . errorHandler ) ;
}
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Mute CC
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . mute = function ( ) {
2014-08-16 22:38:13 -07:00
this . audio = false ;
2014-07-07 19:27:17 -07:00
this . setReceiverVolume ( true ) ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* media seek function in either Cast or local mode
* @ param { Event } e An event object from seek
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . seekMedia = function ( event ) {
2014-08-18 20:25:56 -07:00
2014-08-16 22:38:13 -07:00
var pos = parseInt ( event ) ;
var curr = pos / 10000000 ;
2014-08-18 20:25:56 -07:00
if ( ! this . currentMediaSession ) {
2014-07-07 19:27:17 -07:00
return ;
2014-08-16 22:38:13 -07:00
}
var request = new chrome . cast . media . SeekRequest ( ) ;
2014-08-18 20:25:56 -07:00
request . currentTime = curr ;
2014-08-16 22:38:13 -07:00
this . currentMediaSession . seek ( request ,
this . onSeekSuccess . bind ( this , 'media seek done' ) ,
this . errorHandler ) ;
2014-08-18 20:25:56 -07:00
2014-07-07 19:27:17 -07:00
this . castPlayerState = PLAYER _STATE . SEEKING ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Callback function for seek success
* @ param { String } info A string that describe seek event
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . onSeekSuccess = function ( info ) {
2014-08-16 22:38:13 -07:00
console . log ( info ) ;
2014-07-07 19:27:17 -07:00
this . castPlayerState = PLAYER _STATE . PLAYING ;
2014-08-16 22:38:13 -07:00
} ;
/ * *
* Callback function for media command success
* /
2014-07-07 19:27:17 -07:00
CastPlayer . prototype . mediaCommandSuccessCallback = function ( info , e ) {
console . log ( info ) ;
2014-08-16 22:38:13 -07:00
} ;
// Create Cast Player
var castPlayer = new CastPlayer ( ) ;
function chromecastPlayer ( ) {
var self = this ;
// MediaController needs this
self . name = PlayerName ;
self . getItemsForPlayback = function ( query ) {
var userId = Dashboard . getCurrentUserId ( ) ;
query . Limit = query . Limit || 100 ;
query . ExcludeLocationTypes = "Virtual" ;
return ApiClient . getItems ( userId , query ) ;
2014-07-07 19:27:17 -07:00
} ;
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
$ ( castPlayer ) . on ( "connect" , function ( e ) {
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
console . log ( 'cc: connect' ) ;
// Reset this so the next query doesn't make it appear like content is playing.
self . lastPlayerData = { } ;
} ) ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
$ ( castPlayer ) . on ( "playbackstart" , function ( e , data ) {
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
console . log ( 'cc: playbackstart' ) ;
2014-08-18 19:49:16 -07:00
castPlayer . initializeCastPlayer ( ) ;
2014-08-17 20:00:37 -07:00
var state = self . getPlayerStateInternal ( data ) ;
$ ( self ) . trigger ( "playbackstart" , [ state ] ) ;
} ) ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
$ ( castPlayer ) . on ( "playbackstop" , function ( e , data ) {
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
console . log ( 'cc: playbackstop' ) ;
var state = self . getPlayerStateInternal ( data ) ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
$ ( self ) . trigger ( "playbackstop" , [ state ] ) ;
2014-08-18 07:20:02 -07:00
// Reset this so the next query doesn't make it appear like content is playing.
self . lastPlayerData = { } ;
2014-08-17 20:00:37 -07:00
} ) ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
$ ( castPlayer ) . on ( "playbackprogress" , function ( e , data ) {
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
console . log ( 'cc: positionchange' ) ;
var state = self . getPlayerStateInternal ( data ) ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
$ ( self ) . trigger ( "positionchange" , [ state ] ) ;
} ) ;
2014-08-09 22:29:45 -07:00
2014-07-07 19:27:17 -07:00
self . play = function ( options ) {
2014-08-09 22:29:45 -07:00
Dashboard . getCurrentUser ( ) . done ( function ( user ) {
if ( options . items ) {
2014-08-18 07:20:02 -07:00
self . playWithCommand ( options , 'PlayNow' ) ;
2014-08-09 22:29:45 -07:00
} else {
self . getItemsForPlayback ( {
Ids : options . ids . join ( ',' )
} ) . done ( function ( result ) {
2014-08-18 07:20:02 -07:00
options . items = result . Items ;
self . playWithCommand ( options , 'PlayNow' ) ;
2014-08-09 22:29:45 -07:00
} ) ;
}
} ) ;
} ;
self . playWithCommand = function ( options , command ) {
2014-08-16 22:38:13 -07:00
if ( ! options . items ) {
2014-08-17 20:00:37 -07:00
ApiClient . getItem ( Dashboard . getCurrentUserId ( ) , options . ids [ 0 ] ) . done ( function ( item ) {
2014-08-16 22:38:13 -07:00
options . items = [ item ] ;
self . playWithCommand ( options , command ) ;
} ) ;
return ;
}
castPlayer . loadMedia ( options , command ) ;
} ;
2014-07-07 19:27:17 -07:00
self . unpause = function ( ) {
castPlayer . playMedia ( ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . pause = function ( ) {
castPlayer . pauseMedia ( ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . shuffle = function ( id ) {
2014-08-09 22:29:45 -07:00
var userId = Dashboard . getCurrentUserId ( ) ;
2014-07-07 19:27:17 -07:00
ApiClient . getItem ( userId , id ) . done ( function ( item ) {
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
self . playWithCommand ( {
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
items : [ item ]
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
} , 'Shuffle' ) ;
2014-08-09 22:29:45 -07:00
2014-07-07 19:27:17 -07:00
} ) ;
2014-08-09 22:29:45 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . instantMix = function ( id ) {
2014-08-09 22:29:45 -07:00
var userId = Dashboard . getCurrentUserId ( ) ;
2014-07-07 19:27:17 -07:00
ApiClient . getItem ( userId , id ) . done ( function ( item ) {
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
self . playWithCommand ( {
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
items : [ item ]
2014-08-09 22:29:45 -07:00
2014-08-18 07:20:02 -07:00
} , 'InstantMix' ) ;
2014-08-09 22:29:45 -07:00
2014-07-07 19:27:17 -07:00
} ) ;
2014-08-09 22:29:45 -07:00
} ;
2014-08-16 22:38:13 -07:00
2014-07-07 19:27:17 -07:00
self . canQueueMediaType = function ( mediaType ) {
return mediaType == "Audio" ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . queue = function ( options ) {
2014-08-09 22:29:45 -07:00
self . playWithCommnd ( options , 'PlayLast' ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . queueNext = function ( options ) {
2014-08-09 22:29:45 -07:00
self . playWithCommand ( options , 'PlayNext' ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . stop = function ( ) {
castPlayer . stopMedia ( ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . displayContent = function ( options ) {
2014-08-16 22:38:13 -07:00
2014-08-18 19:49:16 -07:00
castPlayer . sendMessage ( {
options : options ,
command : 'DisplayContent'
} ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . mute = function ( ) {
castPlayer . mute ( ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . unMute = function ( ) {
2014-08-21 08:55:35 -07:00
self . setVolume ( getCurrentVolume ( ) + 2 ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . toggleMute = function ( ) {
2014-08-21 08:55:35 -07:00
var state = self . lastPlayerData || { } ;
state = state . PlayState || { } ;
if ( state . IsMuted ) {
self . unMute ( ) ;
} else {
self . mute ( ) ;
}
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . getTargets = function ( ) {
2014-08-16 22:38:13 -07:00
var targets = [ ] ;
2014-07-07 19:27:17 -07:00
if ( castPlayer . hasReceivers ) {
targets . push ( self . getCurrentTargetInfo ( ) ) ;
2014-08-16 22:38:13 -07:00
}
2014-07-07 19:27:17 -07:00
return targets ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . getCurrentTargetInfo = function ( ) {
2014-08-16 22:38:13 -07:00
var appName = null ;
2014-07-07 19:27:17 -07:00
if ( castPlayer . session && castPlayer . session . receiver && castPlayer . session . receiver . friendlyName ) {
appName = castPlayer . session . receiver . friendlyName ;
2014-08-16 22:38:13 -07:00
}
2014-07-07 19:27:17 -07:00
return {
2014-08-16 22:38:13 -07:00
name : PlayerName ,
id : PlayerName ,
playerName : PlayerName ,
playableMediaTypes : [ "Audio" , "Video" ] ,
isLocalPlayer : false ,
appName : PlayerName ,
deviceName : appName ,
supportedCommands : [ "VolumeUp" ,
"VolumeDown" ,
"Mute" ,
"Unmute" ,
"ToggleMute" ,
2014-08-21 08:55:35 -07:00
"SetVolume" ,
"SetAudioStreamIndex" ,
"SetSubtitleStreamIndex" ,
"DisplayContent" ]
2014-07-07 19:27:17 -07:00
} ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . seek = function ( position ) {
castPlayer . seekMedia ( position ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-08-21 08:55:35 -07:00
self . setAudioStreamIndex = function ( index ) {
castPlayer . sendMessage ( {
options : {
index : index
} ,
command : 'SetAudioStreamIndex'
} ) ;
} ;
self . setSubtitleStreamIndex = function ( index ) {
castPlayer . sendMessage ( {
options : {
index : index
} ,
command : 'SetSubtitleStreamIndex'
} ) ;
} ;
2014-07-07 19:27:17 -07:00
self . nextTrack = function ( ) {
2014-08-18 20:25:56 -07:00
castPlayer . sendMessage ( {
options : { } ,
command : 'NextTrack'
} ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . previousTrack = function ( ) {
2014-08-18 20:25:56 -07:00
castPlayer . sendMessage ( {
options : { } ,
command : 'PreviousTrack'
} ) ;
2014-08-16 22:38:13 -07:00
} ;
self . beginPlayerUpdates = function ( ) {
// Setup polling here
} ;
self . endPlayerUpdates = function ( ) {
// Stop polling here
} ;
2014-08-18 18:42:53 -07:00
function getCurrentVolume ( ) {
var state = self . lastPlayerData || { } ;
state = state . PlayState || { } ;
return state . VolumeLevel == null ? 100 : state . VolumeLevel ;
}
2014-07-07 19:27:17 -07:00
self . volumeDown = function ( ) {
2014-08-18 18:42:53 -07:00
self . setVolume ( getCurrentVolume ( ) - 2 ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . volumeUp = function ( ) {
2014-08-18 18:42:53 -07:00
self . setVolume ( getCurrentVolume ( ) + 2 ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . setVolume = function ( vol ) {
2014-08-18 18:42:53 -07:00
vol = Math . min ( vol , 100 ) ;
vol = Math . max ( vol , 0 ) ;
castPlayer . setReceiverVolume ( false , ( vol / 100 ) ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-07-07 19:27:17 -07:00
self . getPlayerState = function ( ) {
2014-08-16 22:38:13 -07:00
var deferred = $ . Deferred ( ) ;
var result = self . getPlayerStateInternal ( ) ;
deferred . resolveWith ( null , [ result ] ) ;
2014-07-07 19:27:17 -07:00
return deferred . promise ( ) ;
2014-08-16 22:38:13 -07:00
} ;
2014-08-17 20:00:37 -07:00
self . lastPlayerData = { } ;
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
self . getPlayerStateInternal = function ( data ) {
2014-08-16 22:38:13 -07:00
2014-08-17 20:00:37 -07:00
data = data || self . lastPlayerData ;
self . lastPlayerData = data ;
2014-08-18 19:49:16 -07:00
2014-08-17 20:00:37 -07:00
console . log ( JSON . stringify ( data ) ) ;
return data ;
2014-07-07 19:27:17 -07:00
} ;
2014-08-16 22:38:13 -07:00
}
MediaController . registerPlayer ( new chromecastPlayer ( ) ) ;
$ ( MediaController ) . on ( 'playerchange' , function ( ) {
if ( MediaController . getPlayerInfo ( ) . name == PlayerName ) {
if ( castPlayer . deviceState != DEVICE _STATE . ACTIVE && castPlayer . isInitialized ) {
castPlayer . launchApp ( ) ;
}
}
} ) ;
2014-02-22 22:52:30 -07:00
} ) ( window , window . chrome , console ) ;