diff --git a/dashboard-ui/scripts/backdrops.js b/dashboard-ui/scripts/backdrops.js index 479f9303eb..bd72a90d92 100644 --- a/dashboard-ui/scripts/backdrops.js +++ b/dashboard-ui/scripts/backdrops.js @@ -66,7 +66,7 @@ function showBackdrop(type, parentId) { - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (!apiClient) { return; diff --git a/dashboard-ui/scripts/chromecast.js b/dashboard-ui/scripts/chromecast.js index e07cca4334..5123b8c317 100644 --- a/dashboard-ui/scripts/chromecast.js +++ b/dashboard-ui/scripts/chromecast.js @@ -28,7 +28,7 @@ var PlayerName = 'Chromecast'; - var messageNamespace = 'urn:x-cast:com.google.cast.mediabrowser.v3'; + var messageNamespace = 'urn:x-cast:com.connectsdk'; var CastPlayer = function () { @@ -852,9 +852,8 @@ MediaController.registerPlayer(new chromecastPlayer()); - $(MediaController).on('playerchange', function () { - - if (MediaController.getPlayerInfo().name == PlayerName) { + $(MediaController).on('playerchange', function (e, newPlayer, newTarget) { + if (newPlayer.name == PlayerName) { if (castPlayer.deviceState != DEVICE_STATE.ACTIVE && castPlayer.isInitialized) { castPlayer.launchApp(); } diff --git a/dashboard-ui/scripts/connectlogin.js b/dashboard-ui/scripts/connectlogin.js index 5561d6e862..9c7991abc6 100644 --- a/dashboard-ui/scripts/connectlogin.js +++ b/dashboard-ui/scripts/connectlogin.js @@ -39,7 +39,7 @@ { var apiClient = result.ApiClient; - Dashboard.onLoggedIn(apiClient.serverAddress(), apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient); + Dashboard.onServerChanged(apiClient.serverAddress(), apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient); Dashboard.navigate('index.html'); } break; diff --git a/dashboard-ui/scripts/librarymenu.js b/dashboard-ui/scripts/librarymenu.js index 1f6a42403f..7d2861314b 100644 --- a/dashboard-ui/scripts/librarymenu.js +++ b/dashboard-ui/scripts/librarymenu.js @@ -138,7 +138,7 @@ var page = $.mobile.activePage; var panel; - ConnectionManager.user().done(function (user) { + ConnectionManager.user(window.ApiClient).done(function (user) { panel = getLibraryMenu(user); updateLibraryNavLinks(page); @@ -165,7 +165,7 @@ function updateLibraryMenu(panel) { - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (!apiClient) { @@ -302,7 +302,7 @@ html += '
'; } - var homeHref = ConnectionManager.currentApiClient() ? 'index.html' : 'selectserver.html'; + var homeHref = window.ApiClient ? 'index.html' : 'selectserver.html'; if (showUserAtTop) { html += '' + Globalize.translate('ButtonHome') + ''; @@ -508,7 +508,7 @@ var viewMenuBar = $('.viewMenuBar'); if (!$('.viewMenuBar').length) { - ConnectionManager.user().done(function (user) { + ConnectionManager.user(window.ApiClient).done(function (user) { renderHeader(user); updateViewMenuBarHeadroom(page, $('.viewMenuBar')); @@ -592,7 +592,12 @@ $(ConnectionManager).on('apiclientcreated', function (e, apiClient) { + requiresLibraryMenuRefresh = true; initializeApiClient(apiClient); + + }).on('localusersignedin localusersignedout', function () { + + requiresLibraryMenuRefresh = true; }); $(function () { diff --git a/dashboard-ui/scripts/loginpage.js b/dashboard-ui/scripts/loginpage.js index 7d1a4d31e8..4625249511 100644 --- a/dashboard-ui/scripts/loginpage.js +++ b/dashboard-ui/scripts/loginpage.js @@ -110,7 +110,7 @@ newUrl = "index.html?u=" + user.Id + '&t=' + result.AccessToken; } - Dashboard.onLoggedIn(apiClient.serverAddress(), user.Id, result.AccessToken, apiClient); + Dashboard.onServerChanged(apiClient.serverAddress(), user.Id, result.AccessToken, apiClient); Dashboard.navigate(newUrl); }).fail(function () { diff --git a/dashboard-ui/scripts/mediacontroller.js b/dashboard-ui/scripts/mediacontroller.js index ac8143ef73..ec7b0564b4 100644 --- a/dashboard-ui/scripts/mediacontroller.js +++ b/dashboard-ui/scripts/mediacontroller.js @@ -105,6 +105,11 @@ }; }; + function triggerPlayerChange(newPlayer, newTarget) { + + $(self).trigger('playerchange', [newPlayer, newTarget]); + } + self.setActivePlayer = function (player, targetInfo) { if (typeof (player) === 'string') { @@ -122,7 +127,7 @@ console.log('Active player: ' + JSON.stringify(currentTargetInfo)); - $(self).trigger('playerchange'); + triggerPlayerChange(player, targetInfo); }; self.trySetActivePlayer = function (player, targetInfo) { @@ -144,7 +149,7 @@ console.log('Active player: ' + JSON.stringify(currentTargetInfo)); - $(self).trigger('playerchange'); + triggerPlayerChange(player, targetInfo); }); }; @@ -599,7 +604,7 @@ }); - $('.radioSelectPlayerTarget', elem).on('change', function () { + $('.radioSelectPlayerTarget', elem).off('change').on('change', function () { var supportsMirror = this.getAttribute('data-mirror') == 'true'; @@ -609,14 +614,6 @@ $('.fldMirrorMode', elem).hide(); } - }).each(function () { - - if (this.checked) { - $(this).trigger('change'); - } - - }).on('change', function () { - var playerName = this.getAttribute('data-playername'); var targetId = this.getAttribute('data-targetid'); var targetName = this.getAttribute('data-targetname'); @@ -639,6 +636,12 @@ } }); + + if ($('.radioSelectPlayerTarget:checked', elem).attr('data-mirror') == 'true') { + $('.fldMirrorMode', elem).show(); + } else { + $('.fldMirrorMode', elem).hide(); + } }); } diff --git a/dashboard-ui/scripts/notifications.js b/dashboard-ui/scripts/notifications.js index 196c5f6720..49e6dc6097 100644 --- a/dashboard-ui/scripts/notifications.js +++ b/dashboard-ui/scripts/notifications.js @@ -10,7 +10,7 @@ self.getNotificationsSummary = function () { - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (!apiClient) { return; @@ -107,7 +107,7 @@ function refreshNotifications(startIndex, limit, elem, btn, showPaging) { - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (apiClient) { return apiClient.getNotifications(Dashboard.getCurrentUserId(), { StartIndex: startIndex, Limit: limit }).done(function (result) { @@ -219,7 +219,7 @@ $(document).on('headercreated', function (e) { - if (ConnectionManager.currentApiClient()) { + if (window.ApiClient) { $('').insertAfter($('.headerSearchButton')).on('click', Notifications.showNotificationsFlyout); Notifications.updateNotificationCount(); diff --git a/dashboard-ui/scripts/remotecontrol.js b/dashboard-ui/scripts/remotecontrol.js index a698f8c44f..c5973906b0 100644 --- a/dashboard-ui/scripts/remotecontrol.js +++ b/dashboard-ui/scripts/remotecontrol.js @@ -164,7 +164,7 @@ var deferred = $.Deferred(); - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (apiClient) { apiClient.getSessions().done(function (sessions) { @@ -242,7 +242,7 @@ ControllableByUserId: Dashboard.getCurrentUserId() }; - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (apiClient) { apiClient.getSessions(sessionQuery).done(function (sessions) { diff --git a/dashboard-ui/scripts/selectserver.js b/dashboard-ui/scripts/selectserver.js index 5267b2b684..71f91e5ee3 100644 --- a/dashboard-ui/scripts/selectserver.js +++ b/dashboard-ui/scripts/selectserver.js @@ -8,20 +8,22 @@ Dashboard.hideLoadingMsg(); + var apiClient = result.ApiClient; + switch (result.State) { case MediaBrowser.ConnectionState.SignedIn: { - var apiClient = result.ApiClient; - - Dashboard.onLoggedIn(apiClient.serverAddress(), apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient); + Dashboard.onServerChanged(apiClient.serverAddress(), apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient); Dashboard.navigate('index.html'); } break; case MediaBrowser.ConnectionState.ServerSignIn: { if (Dashboard.isRunningInCordova()) { - window.location.href = 'login.html?serverid=' + result.Servers[0].Id; + + Dashboard.onServerChanged(apiClient.serverAddress(), null, null, apiClient); + Dashboard.navigate('login.html?serverid=' + result.Servers[0].Id); } else { showServerConnectionFailure(); } @@ -401,15 +403,19 @@ loadInvitations(page); } - $(document).on('pagebeforecreate', "#selectServerPage", function () { + function updatePageStyle(page) { + + if (ConnectionManager.isLoggedIntoConnect()) { + $(page).addClass('libraryPage').addClass('noSecondaryNavPage').removeClass('standalonePage'); + } else { + $(page).removeClass('libraryPage').removeClass('noSecondaryNavPage').addClass('standalonePage'); + } + } + + $(document).on('pagebeforecreate pageinit pagebeforeshow', "#selectServerPage", function () { var page = this; - - if (ConnectionManager.isLoggedIntoConnect()) { - $(page).addClass('libraryPage').addClass(' noSecondaryNavPage').removeClass('standalonePage'); - } else { - $(page).removeClass('libraryPage').removeClass(' noSecondaryNavPage').addClass('standalonePage'); - } + updatePageStyle(page); }).on('pagebeforeshow', "#selectServerPage", function () { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 5f10a5b428..579e41bf6a 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -113,7 +113,7 @@ var Dashboard = { if (!Dashboard.getUserPromise) { - Dashboard.getUserPromise = ConnectionManager.currentApiClient().getCurrentUser().fail(Dashboard.logout); + Dashboard.getUserPromise = window.ApiClient.getCurrentUser().fail(Dashboard.logout); } return Dashboard.getUserPromise; @@ -192,7 +192,7 @@ var Dashboard = { store.setItem("userId", userId); store.setItem("token", token); - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (apiClient) { apiClient.setCurrentUserId(userId, token); @@ -644,7 +644,7 @@ var Dashboard = { showUserFlyout: function (context) { - ConnectionManager.user().done(function (user) { + ConnectionManager.user(window.ApiClient).done(function (user) { var html = '
'; @@ -1488,14 +1488,14 @@ var Dashboard = { return deferred.promise(); }, - onLoggedIn: function (serverAddress, userId, accessToken, apiClient) { + onServerChanged: function (serverAddress, userId, accessToken, apiClient) { + window.ApiClient = apiClient; if (Dashboard.isConnectMode()) { Dashboard.serverAddress(serverAddress); } Dashboard.setCurrentUser(userId, accessToken); - window.ApiClient = apiClient; } }; @@ -1787,7 +1787,7 @@ var AppInfo = {}; $(window).on("beforeunload", function () { - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; // Close the connection gracefully when possible if (apiClient && apiClient.isWebSocketOpen()) { @@ -1925,7 +1925,7 @@ $(document).on('pagecreate', ".page", function () { var page = $(this); - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (Dashboard.getAccessToken() && Dashboard.getCurrentUserId()) { diff --git a/dashboard-ui/scripts/sync.js b/dashboard-ui/scripts/sync.js index 3bc85d28b2..bd7cd1f057 100644 --- a/dashboard-ui/scripts/sync.js +++ b/dashboard-ui/scripts/sync.js @@ -359,7 +359,7 @@ function showSyncButtonsPerUser(page) { - var apiClient = ConnectionManager.currentApiClient(); + var apiClient = window.ApiClient; if (!apiClient) { return; diff --git a/dashboard-ui/thirdparty/apiclient/apiclient.js b/dashboard-ui/thirdparty/apiclient/apiclient.js index 810da7493a..7e85ef63b6 100644 --- a/dashboard-ui/thirdparty/apiclient/apiclient.js +++ b/dashboard-ui/thirdparty/apiclient/apiclient.js @@ -558,6 +558,8 @@ self.logout = function () { + self.closeWebSocket(); + var done = function () { self.setCurrentUserId(null, null); }; diff --git a/dashboard-ui/thirdparty/apiclient/connectionmanager.js b/dashboard-ui/thirdparty/apiclient/connectionmanager.js index 0bf246fff2..025f29c6e3 100644 --- a/dashboard-ui/thirdparty/apiclient/connectionmanager.js +++ b/dashboard-ui/thirdparty/apiclient/connectionmanager.js @@ -91,11 +91,6 @@ return deviceId; }; - self.currentApiClient = function () { - - return apiClients[0]; - }; - self.connectUserId = function () { return credentialProvider.credentials().ConnectUserId; }; @@ -409,7 +404,7 @@ }; } - self.user = function () { + self.user = function (apiClient) { var deferred = DeferredBuilder.Deferred(); @@ -431,7 +426,6 @@ function onEnsureConnectUserDone() { - var apiClient = self.currentApiClient(); if (apiClient && apiClient.getCurrentUserId()) { apiClient.getCurrentUser().done(function (u) { localUser = u; @@ -443,7 +437,7 @@ var credentials = credentialProvider.credentials(); - if (credentials.ConnectUserId && credentials.ConnectAccessToken && !(self.currentApiClient() && self.currentApiClient().getCurrentUserId())) { + if (credentials.ConnectUserId && credentials.ConnectAccessToken && !(apiClient && apiClient.getCurrentUserId())) { ensureConnectUser(credentials).always(onEnsureConnectUserDone); } else { onEnsureConnectUserDone(); diff --git a/dashboard-ui/thirdparty/cordova/chromecast.js b/dashboard-ui/thirdparty/cordova/chromecast.js index fb2ff33e90..984280731d 100644 --- a/dashboard-ui/thirdparty/cordova/chromecast.js +++ b/dashboard-ui/thirdparty/cordova/chromecast.js @@ -2,7 +2,10 @@ var PlayerName = "Chromecast"; var ApplicationID = "F4EB2E8E"; - var currentDevice; + var currentPairingDeviceId; + var currentPairedDeviceId; + var currentDeviceFriendlyName; + var currentWebAppSession; function chromecastPlayer() { @@ -34,8 +37,6 @@ console.log('cc: playbackstart'); - castPlayer.initializeCastPlayer(); - var state = self.getPlayerStateInternal(data); $(self).trigger("playbackstart", [state]); }); @@ -59,6 +60,54 @@ $(self).trigger("positionchange", [state]); }); + 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; + }); + } + + function sendMessageToDevice(message) { + + var bitrateSetting = AppSettings.maxChromecastBitrate(); + + message = $.extend(message, { + userId: Dashboard.getCurrentUserId(), + deviceId: ApiClient.deviceId(), + accessToken: ApiClient.accessToken(), + serverAddress: ApiClient.serverAddress(), + maxBitrate: bitrateSetting, + receiverName: currentDeviceFriendlyName + }); + + getEndpointInfo().done(function (endpoint) { + + if (endpoint.IsLocal || endpoint.IsInNetwork) { + ApiClient.getSystemInfo().done(function (info) { + + message.serverAddress = info.LocalAddress; + sendMessageInternal(message); + }); + } else { + sendMessageInternal(message); + } + }); + + } + + function sendMessageInternal(message) { + currentWebAppSession.sendText(JSON.stringify(message)); + } + self.play = function (options) { Dashboard.getCurrentUser().done(function (user) { @@ -97,15 +146,34 @@ return; } - castPlayer.loadMedia(options, command); + // 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 + }; + }); + + sendMessageToDevice({ + options: options, + command: command + }); }; self.unpause = function () { - castPlayer.playMedia(); + sendMessageToDevice({ + command: 'unpause' + }); }; self.pause = function () { - castPlayer.pauseMedia(); + sendMessageToDevice({ + command: 'pause' + }); }; self.shuffle = function (id) { @@ -153,19 +221,23 @@ }; self.stop = function () { - castPlayer.stopMedia(); + sendMessageToDevice({ + command: 'stop' + }); }; self.displayContent = function (options) { - castPlayer.sendMessage({ + sendMessageToDevice({ options: options, command: 'DisplayContent' }); }; self.mute = function () { - castPlayer.mute(); + sendMessageToDevice({ + command: 'mute' + }); }; self.unMute = function () { @@ -216,19 +288,39 @@ return target; } + function isChromecast(name) { + + var validTokens = ['nexusplayer', 'chromecast', 'eurekadongle']; + + return validTokens.filter(function (t) { + + return name.toLowerCase().replace(' ', '').indexOf(t) != -1; + + }).length > 0; + } + self.getTargets = function () { var manager = ConnectSDK.discoveryManager; - return manager.getDeviceList().map(convertDeviceToTarget); + return manager.getDeviceList().filter(function (d) { + + return isChromecast(d.getModelName()) || isChromecast(d.getFriendlyName()); + + }).map(convertDeviceToTarget); }; self.seek = function (position) { - castPlayer.seekMedia(position); + sendMessageToDevice({ + options: { + position: position + }, + command: 'Seek' + }); }; self.setAudioStreamIndex = function (index) { - castPlayer.sendMessage({ + sendMessageToDevice({ options: { index: index }, @@ -237,7 +329,7 @@ }; self.setSubtitleStreamIndex = function (index) { - castPlayer.sendMessage({ + sendMessageToDevice({ options: { index: index }, @@ -246,14 +338,14 @@ }; self.nextTrack = function () { - castPlayer.sendMessage({ + sendMessageToDevice({ options: {}, command: 'NextTrack' }); }; self.previousTrack = function () { - castPlayer.sendMessage({ + sendMessageToDevice({ options: {}, command: 'PreviousTrack' }); @@ -289,7 +381,12 @@ vol = Math.min(vol, 100); vol = Math.max(vol, 0); - castPlayer.setReceiverVolume(false, (vol / 100)); + sendMessageToDevice({ + options: { + volume: (vol / 100) + }, + command: 'SetVolume' + }); }; self.getPlayerState = function () { @@ -314,33 +411,186 @@ return data; }; + function onMessage(message) { + + if (message.type == 'playbackerror') { + + var errorCode = message.data; + + setTimeout(function () { + Dashboard.alert({ + message: Globalize.translate('MessagePlaybackError' + errorCode), + title: Globalize.translate('HeaderPlaybackError') + }); + }, 300); + + } + else if (message.type == 'connectionerror') { + + setTimeout(function () { + Dashboard.alert({ + message: Globalize.translate('MessageChromecastConnectionError'), + title: Globalize.translate('HeaderError') + }); + }, 300); + + } + else if (message.type && message.type.indexOf('playback') == 0) { + $(castPlayer).trigger(message.type, [message.data]); + } + } + + function onSessionConnected(device, session) { + + // hold on to a reference + currentWebAppSession = session.acquire(); + + session.connect().success(function () { + + console.log('session.connect succeeded'); + + MediaController.setActivePlayer(PlayerName, convertDeviceToTarget(device)); + currentDeviceFriendlyName = device.getFriendlyName(); + currentPairedDeviceId = device.getId(); + + $(castPlayer).trigger('connect'); + + sendMessageToDevice({ + options: {}, + command: 'Identify' + }); + }); + + session.on('message', function (message) { + // message could be either a string or an object + if (typeof message === 'string') { + onMessage(JSON.parse(message)); + } else { + onMessage(message); + } + }); + + session.on('disconnect', function () { + + console.log("session disconnected"); + + if (currentPairedDeviceId == device.getId()) { + onDisconnected(); + MediaController.removeActivePlayer(PlayerName); + } + + }); + + } + + function onDisconnected() { + currentWebAppSession = null; + currentPairedDeviceId = null; + currentDeviceFriendlyName = null; + } + + function launchWebApp(device) { + device.getWebAppLauncher().launchWebApp(ApplicationID).success(function (session) { + + console.log('launchWebApp success. calling onSessionConnected'); + onSessionConnected(device, session); + + }).error(function (err) { + + console.log('launchWebApp error: ' + JSON.stringify(err) + '. calling joinWebApp'); + + device.getWebAppLauncher().joinWebApp(ApplicationID).success(function (session) { + + console.log('joinWebApp success. calling onSessionConnected'); + onSessionConnected(device, session); + + }).error(function (err1) { + + console.log('joinWebApp error:' + JSON.stringify(err1)); + + }); + + }); + } + + function onDeviceReady(device) { + + if (currentPairingDeviceId != device.getId()) { + console.log('device ready fired for a different device. ignoring.'); + return; + } + + console.log('calling launchWebApp'); + + setTimeout(function () { + + launchWebApp(device); + + }, 0); + } + + var boundHandlers = []; + self.tryPair = function (target) { var deferred = $.Deferred(); - deferred.resolve(); + + var manager = ConnectSDK.discoveryManager; + + var device = manager.getDeviceList().filter(function (d) { + + return d.getId() == target.id; + })[0]; + + if (device) { + + var deviceId = device.getId(); + currentPairingDeviceId = deviceId; + + console.log('Will attempt to connect to Chromecast'); + + if (device.isReady()) { + console.log('Device is already ready, calling onDeviceReady'); + onDeviceReady(device); + } else { + + console.log('Binding device ready handler'); + + if (boundHandlers.indexOf(deviceId) == -1) { + + boundHandlers.push(deviceId); + device.on("ready", function () { + console.log('device.ready fired'); + onDeviceReady(device); + }); + } + + console.log('Calling device.connect'); + device.connect(); + } + //deferred.resolve(); + + } else { + deferred.reject(); + } + return deferred.promise(); }; - } - function onDeviceLost() { + $(MediaController).on('playerchange', function (e, newPlayer, newTarget) { + if (newPlayer.name != PlayerName || newTarget.id != currentPairedDeviceId) { + if (currentWebAppSession) { + currentWebAppSession.disconnect(); + onDisconnected(); + } + } + }); } function initSdk() { - var manager = ConnectSDK.discoveryManager; - - manager.addListener('devicelost', onDeviceLost); - MediaController.registerPlayer(new chromecastPlayer()); - - $(MediaController).on('playerchange', function () { - - if (MediaController.getPlayerInfo().name == PlayerName) { - - // launch app if needed - } - }); } initSdk(); diff --git a/dashboard-ui/thirdparty/cordova/connectsdk.js b/dashboard-ui/thirdparty/cordova/connectsdk.js index bd58636556..ee2f3d7b23 100644 --- a/dashboard-ui/thirdparty/cordova/connectsdk.js +++ b/dashboard-ui/thirdparty/cordova/connectsdk.js @@ -1,12 +1,14 @@ (function () { - function onDeviceFound() { + function onDeviceFound(e) { + console.log('device found'); } - function onDeviceLost() { + function onDeviceLost(e) { + console.log('device lost'); } function initSdk() { @@ -17,13 +19,15 @@ manager.setAirPlayServiceMode(ConnectSDK.AirPlayServiceMode.Media); // Show devices that support playing videos and pausing - manager.setCapabilityFilters([ - new ConnectSDK.CapabilityFilter(["MediaPlayer.Display.Video", "MediaControl.Pause"]) - ]); + //manager.setCapabilityFilters([ + // new ConnectSDK.CapabilityFilter(["MediaPlayer.Display.Video", "MediaControl.Pause"]) + //]); manager.addListener('devicefound', onDeviceFound); manager.addListener('devicelost', onDeviceLost); + manager.startDiscovery(); + requirejs(['thirdparty/cordova/chromecast']); }