2016-03-07 12:13:58 -07:00
|
|
|
|
define(['appStorage'], function (appStorage) {
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
2014-08-25 19:30:52 -07:00
|
|
|
|
var currentDisplayInfo;
|
2014-04-13 10:27:13 -07:00
|
|
|
|
function mirrorItem(info) {
|
|
|
|
|
|
|
|
|
|
var item = info.item;
|
2014-04-15 19:17:48 -07:00
|
|
|
|
|
2014-04-13 10:27:13 -07:00
|
|
|
|
MediaController.getCurrentPlayer().displayContent({
|
|
|
|
|
|
2014-08-21 08:55:35 -07:00
|
|
|
|
ItemName: item.Name,
|
|
|
|
|
ItemId: item.Id,
|
|
|
|
|
ItemType: item.Type,
|
|
|
|
|
Context: info.context
|
2014-04-13 10:27:13 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
function mirrorIfEnabled(info) {
|
2015-08-01 14:17:46 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
info = info || currentDisplayInfo;
|
2014-08-25 19:30:52 -07:00
|
|
|
|
|
2015-08-01 14:17:46 -07:00
|
|
|
|
if (info && MediaController.enableDisplayMirroring()) {
|
2014-08-25 19:30:52 -07:00
|
|
|
|
|
|
|
|
|
var player = MediaController.getPlayerInfo();
|
|
|
|
|
|
|
|
|
|
if (!player.isLocalPlayer && player.supportedCommands.indexOf('DisplayContent') != -1) {
|
|
|
|
|
mirrorItem(info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-22 17:50:47 -07:00
|
|
|
|
function monitorPlayer(player) {
|
|
|
|
|
|
2015-06-29 11:45:42 -07:00
|
|
|
|
Events.on(player, 'playbackstart', function (e, state) {
|
2014-04-22 17:50:47 -07:00
|
|
|
|
|
2014-04-30 20:24:55 -07:00
|
|
|
|
var info = {
|
2014-04-22 17:50:47 -07:00
|
|
|
|
QueueableMediaTypes: state.NowPlayingItem.MediaType,
|
|
|
|
|
ItemId: state.NowPlayingItem.Id,
|
|
|
|
|
NowPlayingItem: state.NowPlayingItem
|
|
|
|
|
};
|
|
|
|
|
|
2016-03-16 13:38:01 -07:00
|
|
|
|
info = Object.assign(info, state.PlayState);
|
2014-04-30 20:24:55 -07:00
|
|
|
|
|
2014-04-22 17:50:47 -07:00
|
|
|
|
ApiClient.reportPlaybackStart(info);
|
2014-04-30 20:24:55 -07:00
|
|
|
|
|
2015-06-28 07:45:21 -07:00
|
|
|
|
});
|
|
|
|
|
|
2015-06-29 11:45:42 -07:00
|
|
|
|
Events.on(player, 'playbackstop', function (e, state) {
|
2014-04-22 17:50:47 -07:00
|
|
|
|
|
2015-03-29 11:38:18 -07:00
|
|
|
|
var stopInfo = {
|
2014-04-22 17:50:47 -07:00
|
|
|
|
itemId: state.NowPlayingItem.Id,
|
|
|
|
|
mediaSourceId: state.PlayState.MediaSourceId,
|
|
|
|
|
positionTicks: state.PlayState.PositionTicks
|
2015-03-29 11:38:18 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (state.PlayState.LiveStreamId) {
|
|
|
|
|
stopInfo.LiveStreamId = state.PlayState.LiveStreamId;
|
|
|
|
|
}
|
2014-04-22 17:50:47 -07:00
|
|
|
|
|
2015-04-01 14:55:50 -07:00
|
|
|
|
if (state.PlayState.PlaySessionId) {
|
|
|
|
|
stopInfo.PlaySessionId = state.PlayState.PlaySessionId;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-29 11:38:18 -07:00
|
|
|
|
ApiClient.reportPlaybackStopped(stopInfo);
|
2014-04-22 17:50:47 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-09 11:05:12 -07:00
|
|
|
|
function showPlayerSelection(button, enableHistory) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
|
|
|
|
var playerInfo = MediaController.getPlayerInfo();
|
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
if (!playerInfo.isLocalPlayer) {
|
|
|
|
|
showActivePlayerMenu(playerInfo);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-07-27 18:27:00 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
Dashboard.showLoadingMsg();
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
MediaController.getTargets().then(function (targets) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
var menuItems = targets.map(function (t) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
var name = t.name;
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
if (t.appName && t.appName != t.name) {
|
|
|
|
|
name += " - " + t.appName;
|
|
|
|
|
}
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
return {
|
|
|
|
|
name: name,
|
|
|
|
|
id: t.id,
|
2016-02-22 09:00:17 -07:00
|
|
|
|
ironIcon: playerInfo.id == t.id ? 'check' : null
|
2015-08-30 10:26:30 -07:00
|
|
|
|
};
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
});
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-01-30 21:04:00 -07:00
|
|
|
|
require(['actionsheet'], function (actionsheet) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
Dashboard.hideLoadingMsg();
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-01-30 21:04:00 -07:00
|
|
|
|
actionsheet.show({
|
2015-08-30 10:26:30 -07:00
|
|
|
|
title: Globalize.translate('HeaderSelectPlayer'),
|
|
|
|
|
items: menuItems,
|
2015-12-14 08:43:03 -07:00
|
|
|
|
positionTo: button,
|
2016-02-09 11:05:12 -07:00
|
|
|
|
enableHistory: enableHistory !== false,
|
2015-08-30 10:26:30 -07:00
|
|
|
|
callback: function (id) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
var target = targets.filter(function (t) {
|
|
|
|
|
return t.id == id;
|
|
|
|
|
})[0];
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
MediaController.trySetActivePlayer(target.playerName, target);
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
mirrorIfEnabled();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
function showActivePlayerMenu(playerInfo) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
require(['dialogHelper', 'paper-checkbox', ], function (dialogHelper) {
|
|
|
|
|
showActivePlayerMenuInternal(dialogHelper, playerInfo);
|
2015-12-14 08:43:03 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
function showActivePlayerMenuInternal(dialogHelper, playerInfo) {
|
2015-12-14 08:43:03 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
var html = '';
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
var dialogOptions = {
|
|
|
|
|
removeOnClose: true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
dialogOptions.modal = false;
|
|
|
|
|
dialogOptions.entryAnimationDuration = 160;
|
|
|
|
|
dialogOptions.exitAnimationDuration = 160;
|
|
|
|
|
dialogOptions.autoFocus = false;
|
|
|
|
|
|
|
|
|
|
var dlg = dialogHelper.createDialog(dialogOptions);
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
html += '<h2>';
|
|
|
|
|
html += (playerInfo.deviceName || playerInfo.name);
|
|
|
|
|
html += '</h2>';
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
html += '<div style="padding:0 2em;">';
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
if (playerInfo.supportedCommands.indexOf('DisplayContent') != -1) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
html += '<div>';
|
|
|
|
|
var checkedHtml = MediaController.enableDisplayMirroring() ? ' checked' : '';
|
|
|
|
|
html += '<paper-checkbox class="chkMirror"' + checkedHtml + '>' + Globalize.translate('OptionEnableDisplayMirroring') + '</paper-checkbox>';
|
|
|
|
|
html += '</div>';
|
|
|
|
|
}
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
|
|
|
|
html += '</div>';
|
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
html += '<div class="buttons">';
|
2015-09-02 18:40:47 -07:00
|
|
|
|
|
|
|
|
|
// On small layouts papepr dialog doesn't respond very well. this button isn't that important here anyway.
|
|
|
|
|
if (screen.availWidth >= 600) {
|
2016-03-28 11:20:43 -07:00
|
|
|
|
html += '<paper-button class="btnRemoteControl">' + Globalize.translate('ButtonRemoteControl') + '</paper-button>';
|
2015-09-02 18:40:47 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
html += '<paper-button class="btnDisconnect">' + Globalize.translate('ButtonDisconnect') + '</paper-button>';
|
|
|
|
|
html += '<paper-button class="btnCancel">' + Globalize.translate('ButtonCancel') + '</paper-button>';
|
2015-08-30 10:26:30 -07:00
|
|
|
|
html += '</div>';
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-16 13:38:01 -07:00
|
|
|
|
dlg.innerHTML = html;
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-16 13:38:01 -07:00
|
|
|
|
document.body.appendChild(dlg);
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
var chkMirror = dlg.querySelector('.chkMirror');
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
if (chkMirror) {
|
|
|
|
|
chkMirror.addEventListener('change', onMirrorChange);
|
|
|
|
|
}
|
2016-03-26 20:49:09 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
var destination = '';
|
|
|
|
|
|
2016-03-28 11:30:29 -07:00
|
|
|
|
var btnRemoteControl = dlg.querySelector('.btnRemoteControl');
|
|
|
|
|
if (btnRemoteControl) {
|
|
|
|
|
btnRemoteControl.addEventListener('click', function () {
|
|
|
|
|
destination = 'nowplaying.html';
|
|
|
|
|
dialogHelper.close(dlg);
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
dlg.querySelector('.btnDisconnect').addEventListener('click', function () {
|
|
|
|
|
MediaController.disconnectFromPlayer();
|
|
|
|
|
dialogHelper.close(dlg);
|
|
|
|
|
});
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
dlg.querySelector('.btnCancel').addEventListener('click', function () {
|
|
|
|
|
dialogHelper.close(dlg);
|
|
|
|
|
});
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2016-03-28 11:20:43 -07:00
|
|
|
|
dialogHelper.open(dlg).then(function () {
|
|
|
|
|
if (destination) {
|
|
|
|
|
Dashboard.navigate(destination);
|
|
|
|
|
}
|
|
|
|
|
});
|
2015-08-30 10:26:30 -07:00
|
|
|
|
}
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
function onMirrorChange() {
|
|
|
|
|
MediaController.enableDisplayMirroring(this.checked);
|
2015-06-26 08:53:49 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bindKeys(controller) {
|
|
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
var keyResult = {};
|
|
|
|
|
|
|
|
|
|
self.keyBinding = function (e) {
|
|
|
|
|
|
|
|
|
|
if (bypass()) return;
|
|
|
|
|
|
2015-12-23 10:46:01 -07:00
|
|
|
|
console.log("keyCode", e.keyCode);
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
|
|
|
|
if (keyResult[e.keyCode]) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
keyResult[e.keyCode](e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.keyPrevent = function (e) {
|
|
|
|
|
|
|
|
|
|
if (bypass()) return;
|
|
|
|
|
|
|
|
|
|
var codes = [32, 38, 40, 37, 39, 81, 77, 65, 84, 83, 70];
|
|
|
|
|
|
|
|
|
|
if (codes.indexOf(e.keyCode) != -1) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
keyResult[32] = function () { // spacebar
|
|
|
|
|
|
|
|
|
|
var player = controller.getCurrentPlayer();
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
player.getPlayerState().then(function (result) {
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
|
|
|
|
var state = result;
|
|
|
|
|
|
|
|
|
|
if (state.NowPlayingItem && state.PlayState) {
|
|
|
|
|
if (state.PlayState.IsPaused) {
|
|
|
|
|
player.unpause();
|
|
|
|
|
} else {
|
|
|
|
|
player.pause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var bypass = function () {
|
|
|
|
|
// Get active elem to see what type it is
|
|
|
|
|
var active = document.activeElement;
|
|
|
|
|
var type = active.type || active.tagName.toLowerCase();
|
|
|
|
|
return (type === "text" || type === "select" || type === "textarea" || type == "password");
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
function mediaController() {
|
|
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
var currentPlayer;
|
2014-03-29 09:58:49 -07:00
|
|
|
|
var currentTargetInfo;
|
2014-03-29 08:40:32 -07:00
|
|
|
|
var players = [];
|
2014-05-30 12:23:56 -07:00
|
|
|
|
|
2014-05-04 20:05:46 -07:00
|
|
|
|
var keys = new bindKeys(self);
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
window.addEventListener('keydown', keys.keyBinding);
|
|
|
|
|
window.addEventListener('keypress', keys.keyPrevent);
|
|
|
|
|
window.addEventListener('keyup', keys.keyPrevent);
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
|
|
|
|
self.registerPlayer = function (player) {
|
|
|
|
|
|
|
|
|
|
players.push(player);
|
2014-04-22 17:50:47 -07:00
|
|
|
|
|
|
|
|
|
if (player.isLocalPlayer) {
|
|
|
|
|
monitorPlayer(player);
|
|
|
|
|
}
|
2015-09-20 11:17:57 -07:00
|
|
|
|
|
|
|
|
|
Events.on(player, 'playbackstop', onPlaybackStop);
|
2015-09-25 19:31:13 -07:00
|
|
|
|
Events.on(player, 'beforeplaybackstart', onBeforePlaybackStart);
|
2014-03-29 09:58:49 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-09-25 19:31:13 -07:00
|
|
|
|
function onBeforePlaybackStart(e, state) {
|
2015-12-14 08:43:03 -07:00
|
|
|
|
Events.trigger(self, 'beforeplaybackstart', [state, this]);
|
2015-09-23 19:31:40 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-20 11:17:57 -07:00
|
|
|
|
function onPlaybackStop(e, state) {
|
2015-12-14 08:43:03 -07:00
|
|
|
|
Events.trigger(self, 'playbackstop', [state, this]);
|
2015-09-20 11:17:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-29 09:58:49 -07:00
|
|
|
|
self.getPlayerInfo = function () {
|
|
|
|
|
|
2015-07-12 10:13:35 -07:00
|
|
|
|
var player = currentPlayer || {};
|
|
|
|
|
var target = currentTargetInfo || {};
|
|
|
|
|
|
2014-03-29 09:58:49 -07:00
|
|
|
|
return {
|
|
|
|
|
|
2015-07-12 10:13:35 -07:00
|
|
|
|
name: player.name,
|
|
|
|
|
isLocalPlayer: player.isLocalPlayer,
|
|
|
|
|
id: target.id,
|
|
|
|
|
deviceName: target.deviceName,
|
|
|
|
|
playableMediaTypes: target.playableMediaTypes,
|
|
|
|
|
supportedCommands: target.supportedCommands
|
2014-03-29 09:58:49 -07:00
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2015-12-25 21:08:25 -07:00
|
|
|
|
function triggerPlayerChange(newPlayer, newTarget, previousPlayer) {
|
2015-05-22 12:16:14 -07:00
|
|
|
|
|
2015-12-25 21:08:25 -07:00
|
|
|
|
Events.trigger(self, 'playerchange', [newPlayer, newTarget, previousPlayer]);
|
2015-05-18 15:23:03 -07:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-29 09:58:49 -07:00
|
|
|
|
self.setActivePlayer = function (player, targetInfo) {
|
|
|
|
|
|
|
|
|
|
if (typeof (player) === 'string') {
|
|
|
|
|
player = players.filter(function (p) {
|
|
|
|
|
return p.name == player;
|
|
|
|
|
})[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!player) {
|
|
|
|
|
throw new Error('null player');
|
|
|
|
|
}
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
2015-12-25 21:08:25 -07:00
|
|
|
|
var previousPlayer = currentPlayer;
|
|
|
|
|
|
2015-06-18 21:23:55 -07:00
|
|
|
|
currentPairingId = null;
|
2014-03-29 09:58:49 -07:00
|
|
|
|
currentPlayer = player;
|
2015-05-18 09:40:20 -07:00
|
|
|
|
currentTargetInfo = targetInfo;
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2015-12-23 10:46:01 -07:00
|
|
|
|
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
|
2014-08-17 20:00:37 -07:00
|
|
|
|
|
2015-12-25 21:08:25 -07:00
|
|
|
|
triggerPlayerChange(player, targetInfo, previousPlayer);
|
2014-03-29 09:58:49 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-05-27 22:51:48 -07:00
|
|
|
|
var currentPairingId = null;
|
2015-05-18 09:40:20 -07:00
|
|
|
|
self.trySetActivePlayer = function (player, targetInfo) {
|
|
|
|
|
|
|
|
|
|
if (typeof (player) === 'string') {
|
|
|
|
|
player = players.filter(function (p) {
|
|
|
|
|
return p.name == player;
|
|
|
|
|
})[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!player) {
|
|
|
|
|
throw new Error('null player');
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-27 22:51:48 -07:00
|
|
|
|
if (currentPairingId == targetInfo.id) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentPairingId = targetInfo.id;
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
player.tryPair(targetInfo).then(function () {
|
2015-05-22 12:16:14 -07:00
|
|
|
|
|
2015-12-25 21:08:25 -07:00
|
|
|
|
var previousPlayer = currentPlayer;
|
|
|
|
|
|
2015-05-18 09:40:20 -07:00
|
|
|
|
currentPlayer = player;
|
|
|
|
|
currentTargetInfo = targetInfo;
|
|
|
|
|
|
2015-12-23 10:46:01 -07:00
|
|
|
|
console.log('Active player: ' + JSON.stringify(currentTargetInfo));
|
2015-05-18 09:40:20 -07:00
|
|
|
|
|
2015-12-25 21:08:25 -07:00
|
|
|
|
triggerPlayerChange(player, targetInfo, previousPlayer);
|
2015-05-18 09:40:20 -07:00
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2015-08-01 14:17:46 -07:00
|
|
|
|
self.trySetActiveDeviceName = function (name) {
|
|
|
|
|
|
|
|
|
|
function normalizeName(t) {
|
|
|
|
|
return t.toLowerCase().replace(' ', '');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name = normalizeName(name);
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
self.getTargets().then(function (result) {
|
2015-08-01 14:17:46 -07:00
|
|
|
|
|
|
|
|
|
var target = result.filter(function (p) {
|
|
|
|
|
return normalizeName(p.name) == name;
|
|
|
|
|
})[0];
|
|
|
|
|
|
|
|
|
|
if (target) {
|
|
|
|
|
self.trySetActivePlayer(target.playerName, target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2014-04-12 10:27:53 -07:00
|
|
|
|
self.setDefaultPlayerActive = function () {
|
2015-05-18 09:40:20 -07:00
|
|
|
|
|
|
|
|
|
var player = self.getDefaultPlayer();
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
player.getTargets().then(function (targets) {
|
|
|
|
|
|
|
|
|
|
self.setActivePlayer(player, targets[0]);
|
|
|
|
|
});
|
2014-04-05 10:01:04 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.removeActivePlayer = function (name) {
|
2014-04-12 10:27:53 -07:00
|
|
|
|
|
2014-04-05 10:01:04 -07:00
|
|
|
|
if (self.getPlayerInfo().name == name) {
|
2014-04-06 10:53:23 -07:00
|
|
|
|
self.setDefaultPlayerActive();
|
2014-04-05 10:01:04 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2015-05-19 12:15:40 -07:00
|
|
|
|
self.removeActiveTarget = function (id) {
|
|
|
|
|
|
|
|
|
|
if (self.getPlayerInfo().id == id) {
|
|
|
|
|
self.setDefaultPlayerActive();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-08-30 10:26:30 -07:00
|
|
|
|
self.disconnectFromPlayer = function () {
|
|
|
|
|
|
|
|
|
|
var playerInfo = self.getPlayerInfo();
|
|
|
|
|
|
|
|
|
|
if (playerInfo.supportedCommands.indexOf('EndSession') != -1) {
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
var menuItems = [];
|
2015-08-30 10:26:30 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
menuItems.push({
|
|
|
|
|
name: Globalize.translate('ButtonYes'),
|
|
|
|
|
id: 'yes'
|
|
|
|
|
});
|
|
|
|
|
menuItems.push({
|
|
|
|
|
name: Globalize.translate('ButtonNo'),
|
|
|
|
|
id: 'no'
|
|
|
|
|
});
|
|
|
|
|
menuItems.push({
|
|
|
|
|
name: Globalize.translate('ButtonCancel'),
|
|
|
|
|
id: 'cancel'
|
|
|
|
|
});
|
2015-08-30 10:26:30 -07:00
|
|
|
|
|
2016-01-30 21:04:00 -07:00
|
|
|
|
require(['actionsheet'], function (actionsheet) {
|
2015-12-14 08:43:03 -07:00
|
|
|
|
|
2016-01-30 21:04:00 -07:00
|
|
|
|
actionsheet.show({
|
2015-12-14 08:43:03 -07:00
|
|
|
|
items: menuItems,
|
|
|
|
|
//positionTo: positionTo,
|
|
|
|
|
title: Globalize.translate('ConfirmEndPlayerSession'),
|
|
|
|
|
callback: function (id) {
|
|
|
|
|
|
|
|
|
|
switch (id) {
|
|
|
|
|
|
|
|
|
|
case 'yes':
|
|
|
|
|
MediaController.getCurrentPlayer().endSession();
|
|
|
|
|
self.setDefaultPlayerActive();
|
|
|
|
|
break;
|
|
|
|
|
case 'no':
|
|
|
|
|
self.setDefaultPlayerActive();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-08-30 10:26:30 -07:00
|
|
|
|
}
|
2015-12-14 08:43:03 -07:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|
2015-08-30 10:26:30 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
self.setDefaultPlayerActive();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-05-22 12:16:14 -07:00
|
|
|
|
self.getPlayers = function () {
|
2015-05-08 20:48:43 -07:00
|
|
|
|
return players;
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-29 09:58:49 -07:00
|
|
|
|
self.getTargets = function () {
|
|
|
|
|
|
|
|
|
|
var promises = players.map(function (p) {
|
|
|
|
|
return p.getTargets();
|
|
|
|
|
});
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
return Promise.all(promises).then(function (responses) {
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
|
|
|
|
var targets = [];
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
for (var i = 0; i < responses.length; i++) {
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
var subTargets = responses[i];
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
|
|
|
|
for (var j = 0; j < subTargets.length; j++) {
|
|
|
|
|
|
|
|
|
|
targets.push(subTargets[j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-12 10:27:53 -07:00
|
|
|
|
targets = targets.sort(function (a, b) {
|
2014-04-05 10:01:04 -07:00
|
|
|
|
|
|
|
|
|
var aVal = a.isLocalPlayer ? 0 : 1;
|
|
|
|
|
var bVal = b.isLocalPlayer ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
aVal = aVal.toString() + a.name;
|
|
|
|
|
bVal = bVal.toString() + b.name;
|
|
|
|
|
|
|
|
|
|
return aVal.localeCompare(bVal);
|
|
|
|
|
});
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
return targets;
|
2014-03-29 09:58:49 -07:00
|
|
|
|
});
|
2014-03-29 08:40:32 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-09-25 19:31:13 -07:00
|
|
|
|
function doWithPlaybackValidation(player, fn) {
|
|
|
|
|
|
|
|
|
|
if (!player.isLocalPlayer) {
|
|
|
|
|
fn();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-05-22 12:16:14 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
requirejs(["registrationservices"], function () {
|
|
|
|
|
|
|
|
|
|
self.playbackTimeLimitMs = null;
|
|
|
|
|
|
|
|
|
|
RegistrationServices.validateFeature('playback').then(fn, function () {
|
|
|
|
|
|
|
|
|
|
self.playbackTimeLimitMs = lockedTimeLimitMs;
|
|
|
|
|
startAutoStopTimer();
|
|
|
|
|
fn();
|
|
|
|
|
});
|
2015-05-22 12:16:14 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
var autoStopTimeout;
|
|
|
|
|
var lockedTimeLimitMs = 60000;
|
|
|
|
|
function startAutoStopTimer() {
|
|
|
|
|
stopAutoStopTimer();
|
|
|
|
|
autoStopTimeout = setTimeout(onAutoStopTimeout, lockedTimeLimitMs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onAutoStopTimeout() {
|
|
|
|
|
stopAutoStopTimer();
|
|
|
|
|
MediaController.stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function stopAutoStopTimer() {
|
|
|
|
|
|
|
|
|
|
var timeout = autoStopTimeout;
|
|
|
|
|
if (timeout) {
|
|
|
|
|
clearTimeout(timeout);
|
|
|
|
|
autoStopTimeout = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-01 14:17:46 -07:00
|
|
|
|
self.toggleDisplayMirroring = function () {
|
|
|
|
|
self.enableDisplayMirroring(!self.enableDisplayMirroring());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.enableDisplayMirroring = function (enabled) {
|
|
|
|
|
|
|
|
|
|
if (enabled != null) {
|
|
|
|
|
|
|
|
|
|
var val = enabled ? '1' : '0';
|
|
|
|
|
appStorage.setItem('displaymirror--' + Dashboard.getCurrentUserId(), val);
|
|
|
|
|
|
|
|
|
|
if (enabled) {
|
|
|
|
|
mirrorIfEnabled();
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (appStorage.getItem('displaymirror--' + Dashboard.getCurrentUserId()) || '') != '0';
|
|
|
|
|
};
|
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
self.play = function (options) {
|
|
|
|
|
|
2015-09-25 19:31:13 -07:00
|
|
|
|
doWithPlaybackValidation(currentPlayer, function () {
|
2015-05-22 12:16:14 -07:00
|
|
|
|
if (typeof (options) === 'string') {
|
|
|
|
|
options = { ids: [options] };
|
|
|
|
|
}
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
2015-05-22 12:16:14 -07:00
|
|
|
|
currentPlayer.play(options);
|
|
|
|
|
});
|
2014-03-29 08:40:32 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.shuffle = function (id) {
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2015-09-25 19:31:13 -07:00
|
|
|
|
doWithPlaybackValidation(currentPlayer, function () {
|
2015-05-22 12:16:14 -07:00
|
|
|
|
currentPlayer.shuffle(id);
|
|
|
|
|
});
|
2014-03-29 08:40:32 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.instantMix = function (id) {
|
2015-09-25 19:31:13 -07:00
|
|
|
|
doWithPlaybackValidation(currentPlayer, function () {
|
2015-05-22 12:16:14 -07:00
|
|
|
|
currentPlayer.instantMix(id);
|
|
|
|
|
});
|
2014-03-29 08:40:32 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.queue = function (options) {
|
|
|
|
|
|
|
|
|
|
if (typeof (options) === 'string') {
|
|
|
|
|
options = { ids: [options] };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentPlayer.queue(options);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.queueNext = function (options) {
|
|
|
|
|
|
|
|
|
|
if (typeof (options) === 'string') {
|
|
|
|
|
options = { ids: [options] };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentPlayer.queueNext(options);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.canPlay = function (item) {
|
|
|
|
|
|
2015-03-25 11:29:21 -07:00
|
|
|
|
return self.canPlayByAttributes(item.Type, item.MediaType, item.PlayAccess, item.LocationType);
|
2014-07-19 21:46:29 -07:00
|
|
|
|
};
|
|
|
|
|
|
2015-03-25 11:29:21 -07:00
|
|
|
|
self.canPlayByAttributes = function (itemType, mediaType, playAccess, locationType) {
|
2014-07-19 21:46:29 -07:00
|
|
|
|
|
|
|
|
|
if (playAccess != 'Full') {
|
2014-03-29 08:40:32 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-25 11:29:21 -07:00
|
|
|
|
if (locationType == "Virtual") {
|
2014-03-29 08:40:32 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-04 20:01:37 -07:00
|
|
|
|
if (itemType == "Program") {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-02 19:16:37 -07:00
|
|
|
|
if (itemType == "MusicGenre" || itemType == "Season" || itemType == "Series" || itemType == "BoxSet" || itemType == "MusicAlbum" || itemType == "MusicArtist" || itemType == "Playlist") {
|
2014-03-29 08:40:32 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-19 21:46:29 -07:00
|
|
|
|
return self.getPlayerInfo().playableMediaTypes.indexOf(mediaType) != -1;
|
2014-03-29 08:40:32 -07:00
|
|
|
|
};
|
|
|
|
|
|
2014-07-15 12:16:16 -07:00
|
|
|
|
self.canQueueMediaType = function (mediaType, itemType) {
|
|
|
|
|
|
|
|
|
|
if (itemType == 'MusicAlbum' || itemType == 'MusicArtist' || itemType == 'MusicGenre') {
|
|
|
|
|
mediaType = 'Audio';
|
|
|
|
|
}
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
|
|
|
|
return currentPlayer.canQueueMediaType(mediaType);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.getLocalPlayer = function () {
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
return currentPlayer.isLocalPlayer ?
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
currentPlayer :
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
players.filter(function (p) {
|
|
|
|
|
return p.isLocalPlayer;
|
|
|
|
|
})[0];
|
|
|
|
|
};
|
2014-04-06 10:53:23 -07:00
|
|
|
|
|
|
|
|
|
self.getDefaultPlayer = function () {
|
|
|
|
|
|
|
|
|
|
return currentPlayer.isLocalPlayer ?
|
|
|
|
|
|
|
|
|
|
currentPlayer :
|
|
|
|
|
|
|
|
|
|
players.filter(function (p) {
|
|
|
|
|
return p.isDefaultPlayer;
|
|
|
|
|
})[0];
|
|
|
|
|
};
|
2014-04-09 16:58:09 -07:00
|
|
|
|
|
2014-04-11 08:36:25 -07:00
|
|
|
|
self.getCurrentPlayer = function () {
|
|
|
|
|
|
|
|
|
|
return currentPlayer;
|
|
|
|
|
};
|
|
|
|
|
|
2014-04-09 16:58:09 -07:00
|
|
|
|
self.pause = function () {
|
|
|
|
|
currentPlayer.pause();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.stop = function () {
|
|
|
|
|
currentPlayer.stop();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.unpause = function () {
|
|
|
|
|
currentPlayer.unpause();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.seek = function (position) {
|
2014-04-11 08:36:25 -07:00
|
|
|
|
currentPlayer.seek(position);
|
2014-04-09 16:58:09 -07:00
|
|
|
|
};
|
2014-04-09 21:12:04 -07:00
|
|
|
|
|
|
|
|
|
self.currentPlaylistIndex = function (i) {
|
2015-09-14 21:31:12 -07:00
|
|
|
|
|
|
|
|
|
if (i == null) {
|
2015-09-17 18:51:22 -07:00
|
|
|
|
// TODO: Get this implemented in all of the players
|
|
|
|
|
return currentPlayer.currentPlaylistIndex ? currentPlayer.currentPlaylistIndex() : -1;
|
2015-09-14 21:31:12 -07:00
|
|
|
|
}
|
|
|
|
|
|
2014-04-10 04:12:48 -07:00
|
|
|
|
currentPlayer.currentPlaylistIndex(i);
|
2014-04-09 21:12:04 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.removeFromPlaylist = function (i) {
|
2014-04-10 04:12:48 -07:00
|
|
|
|
currentPlayer.removeFromPlaylist(i);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.nextTrack = function () {
|
|
|
|
|
currentPlayer.nextTrack();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.previousTrack = function () {
|
|
|
|
|
currentPlayer.previousTrack();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.mute = function () {
|
|
|
|
|
currentPlayer.mute();
|
|
|
|
|
};
|
|
|
|
|
|
2014-04-15 20:49:49 -07:00
|
|
|
|
self.unMute = function () {
|
|
|
|
|
currentPlayer.unMute();
|
2014-04-10 04:12:48 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.toggleMute = function () {
|
|
|
|
|
currentPlayer.toggleMute();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.volumeDown = function () {
|
|
|
|
|
currentPlayer.volumeDown();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.volumeUp = function () {
|
|
|
|
|
currentPlayer.volumeUp();
|
|
|
|
|
};
|
|
|
|
|
|
2015-07-26 14:02:23 -07:00
|
|
|
|
self.setRepeatMode = function (mode) {
|
|
|
|
|
currentPlayer.setRepeatMode(mode);
|
|
|
|
|
};
|
|
|
|
|
|
2014-06-21 22:52:31 -07:00
|
|
|
|
self.playlist = function () {
|
2014-06-04 15:58:12 -07:00
|
|
|
|
return currentPlayer.playlist || [];
|
|
|
|
|
};
|
|
|
|
|
|
2014-04-30 20:24:55 -07:00
|
|
|
|
self.sendCommand = function (cmd, player) {
|
|
|
|
|
|
|
|
|
|
player = player || self.getLocalPlayer();
|
|
|
|
|
|
|
|
|
|
// Full list
|
|
|
|
|
// https://github.com/MediaBrowser/MediaBrowser/blob/master/MediaBrowser.Model/Session/GeneralCommand.cs#L23
|
2015-12-23 10:46:01 -07:00
|
|
|
|
console.log('MediaController received command: ' + cmd.Name);
|
2014-04-30 20:24:55 -07:00
|
|
|
|
switch (cmd.Name) {
|
|
|
|
|
|
2015-07-26 14:02:23 -07:00
|
|
|
|
case 'SetRepeatMode':
|
|
|
|
|
player.setRepeatMode(cmd.Arguments.RepeatMode);
|
|
|
|
|
break;
|
2014-04-30 20:24:55 -07:00
|
|
|
|
case 'VolumeUp':
|
|
|
|
|
player.volumeUp();
|
|
|
|
|
break;
|
|
|
|
|
case 'VolumeDown':
|
|
|
|
|
player.volumeDown();
|
|
|
|
|
break;
|
|
|
|
|
case 'Mute':
|
|
|
|
|
player.mute();
|
|
|
|
|
break;
|
|
|
|
|
case 'Unmute':
|
|
|
|
|
player.unMute();
|
|
|
|
|
break;
|
|
|
|
|
case 'ToggleMute':
|
|
|
|
|
player.toggleMute();
|
|
|
|
|
break;
|
|
|
|
|
case 'SetVolume':
|
|
|
|
|
player.setVolume(cmd.Arguments.Volume);
|
|
|
|
|
break;
|
|
|
|
|
case 'SetAudioStreamIndex':
|
2014-05-07 22:04:39 -07:00
|
|
|
|
player.setAudioStreamIndex(parseInt(cmd.Arguments.Index));
|
2014-04-30 20:24:55 -07:00
|
|
|
|
break;
|
|
|
|
|
case 'SetSubtitleStreamIndex':
|
2014-05-07 22:04:39 -07:00
|
|
|
|
player.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index));
|
2014-04-30 20:24:55 -07:00
|
|
|
|
break;
|
|
|
|
|
case 'ToggleFullscreen':
|
|
|
|
|
player.toggleFullscreen();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
if (player.isLocalPlayer) {
|
|
|
|
|
// Not player-related
|
|
|
|
|
Dashboard.processGeneralCommand(cmd);
|
|
|
|
|
} else {
|
|
|
|
|
player.sendCommand(cmd);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2015-05-08 20:48:43 -07:00
|
|
|
|
|
|
|
|
|
// TOOD: This doesn't really belong here
|
2015-05-13 10:53:26 -07:00
|
|
|
|
self.getNowPlayingNameHtml = function (nowPlayingItem, includeNonNameInfo) {
|
2015-05-08 20:48:43 -07:00
|
|
|
|
|
|
|
|
|
var topText = nowPlayingItem.Name;
|
|
|
|
|
|
|
|
|
|
if (nowPlayingItem.MediaType == 'Video') {
|
|
|
|
|
if (nowPlayingItem.IndexNumber != null) {
|
|
|
|
|
topText = nowPlayingItem.IndexNumber + " - " + topText;
|
|
|
|
|
}
|
|
|
|
|
if (nowPlayingItem.ParentIndexNumber != null) {
|
|
|
|
|
topText = nowPlayingItem.ParentIndexNumber + "." + topText;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var bottomText = '';
|
|
|
|
|
|
|
|
|
|
if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) {
|
|
|
|
|
bottomText = topText;
|
|
|
|
|
topText = nowPlayingItem.Artists[0];
|
|
|
|
|
}
|
|
|
|
|
else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) {
|
|
|
|
|
bottomText = topText;
|
|
|
|
|
topText = nowPlayingItem.SeriesName || nowPlayingItem.Album;
|
|
|
|
|
}
|
2015-05-13 10:53:26 -07:00
|
|
|
|
else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) {
|
2015-05-08 20:48:43 -07:00
|
|
|
|
bottomText = nowPlayingItem.ProductionYear;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bottomText ? topText + '<br/>' + bottomText : topText;
|
|
|
|
|
};
|
2015-05-19 12:15:40 -07:00
|
|
|
|
|
2015-05-22 12:16:14 -07:00
|
|
|
|
self.showPlaybackInfoErrorMessage = function (errorCode) {
|
2015-05-19 12:15:40 -07:00
|
|
|
|
|
2016-02-26 13:29:27 -07:00
|
|
|
|
require(['alert'], function (alert) {
|
|
|
|
|
alert({
|
|
|
|
|
title: Globalize.translate('HeaderPlaybackError'),
|
|
|
|
|
text: Globalize.translate('MessagePlaybackError' + errorCode),
|
|
|
|
|
type: 'error'
|
2015-05-19 12:15:40 -07:00
|
|
|
|
});
|
2016-02-26 13:29:27 -07:00
|
|
|
|
});
|
2015-05-19 12:15:40 -07:00
|
|
|
|
|
|
|
|
|
};
|
2015-05-25 10:32:22 -07:00
|
|
|
|
|
2015-06-02 22:30:14 -07:00
|
|
|
|
function getPlaybackInfoFromLocalMediaSource(itemId, deviceProfile, startPosition, mediaSource) {
|
|
|
|
|
|
|
|
|
|
mediaSource.SupportsDirectPlay = true;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
|
|
MediaSources: [mediaSource],
|
|
|
|
|
|
|
|
|
|
// Just dummy this up
|
|
|
|
|
PlaySessionId: new Date().getTime().toString()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-25 10:32:22 -07:00
|
|
|
|
self.getPlaybackInfo = function (itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId) {
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
return new Promise(function (resolve, reject) {
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
require(['localassetmanager'], function () {
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
var serverInfo = ApiClient.serverInfo();
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
if (serverInfo.Id) {
|
|
|
|
|
LocalAssetManager.getLocalMediaSource(serverInfo.Id, itemId).then(function (localMediaSource) {
|
|
|
|
|
// Use the local media source if a specific one wasn't requested, or the smae one was requested
|
|
|
|
|
if (localMediaSource && (!mediaSource || mediaSource.Id == localMediaSource.Id)) {
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
var playbackInfo = getPlaybackInfoFromLocalMediaSource(itemId, deviceProfile, startPosition, localMediaSource);
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
resolve(playbackInfo);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
getPlaybackInfoWithoutLocalMediaSource(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId, resolve, reject);
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-06-02 22:30:14 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
getPlaybackInfoWithoutLocalMediaSource(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId, resolve, reject);
|
|
|
|
|
});
|
2015-06-02 22:30:14 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
function getPlaybackInfoWithoutLocalMediaSource(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId, resolve, reject) {
|
|
|
|
|
self.getPlaybackInfoInternal(itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId).then(resolve, reject);
|
2015-09-15 11:09:44 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-06-02 22:30:14 -07:00
|
|
|
|
self.getPlaybackInfoInternal = function (itemId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex, liveStreamId) {
|
|
|
|
|
|
2015-05-25 10:32:22 -07:00
|
|
|
|
var postData = {
|
|
|
|
|
DeviceProfile: deviceProfile
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var query = {
|
|
|
|
|
UserId: Dashboard.getCurrentUserId(),
|
|
|
|
|
StartTimeTicks: startPosition || 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (audioStreamIndex != null) {
|
|
|
|
|
query.AudioStreamIndex = audioStreamIndex;
|
|
|
|
|
}
|
|
|
|
|
if (subtitleStreamIndex != null) {
|
|
|
|
|
query.SubtitleStreamIndex = subtitleStreamIndex;
|
|
|
|
|
}
|
|
|
|
|
if (mediaSource) {
|
|
|
|
|
query.MediaSourceId = mediaSource.Id;
|
|
|
|
|
}
|
|
|
|
|
if (liveStreamId) {
|
|
|
|
|
query.LiveStreamId = liveStreamId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ApiClient.ajax({
|
|
|
|
|
url: ApiClient.getUrl('Items/' + itemId + '/PlaybackInfo', query),
|
|
|
|
|
type: 'POST',
|
|
|
|
|
data: JSON.stringify(postData),
|
|
|
|
|
contentType: "application/json",
|
|
|
|
|
dataType: "json"
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.getLiveStream = function (itemId, playSessionId, deviceProfile, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) {
|
|
|
|
|
|
|
|
|
|
var postData = {
|
|
|
|
|
DeviceProfile: deviceProfile,
|
|
|
|
|
OpenToken: mediaSource.OpenToken
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var query = {
|
|
|
|
|
UserId: Dashboard.getCurrentUserId(),
|
|
|
|
|
StartTimeTicks: startPosition || 0,
|
|
|
|
|
ItemId: itemId,
|
|
|
|
|
PlaySessionId: playSessionId
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (audioStreamIndex != null) {
|
|
|
|
|
query.AudioStreamIndex = audioStreamIndex;
|
|
|
|
|
}
|
|
|
|
|
if (subtitleStreamIndex != null) {
|
|
|
|
|
query.SubtitleStreamIndex = subtitleStreamIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ApiClient.ajax({
|
|
|
|
|
url: ApiClient.getUrl('LiveStreams/Open', query),
|
|
|
|
|
type: 'POST',
|
|
|
|
|
data: JSON.stringify(postData),
|
|
|
|
|
contentType: "application/json",
|
|
|
|
|
dataType: "json"
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
self.supportsDirectPlay = function (mediaSource) {
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
|
|
|
if (mediaSource.SupportsDirectPlay) {
|
2015-05-25 10:32:22 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
if (mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) {
|
2015-05-25 10:32:22 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
// If this is the only way it can be played, then allow it
|
|
|
|
|
if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) {
|
|
|
|
|
resolve(true);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
var val = mediaSource.Path.toLowerCase().replace('https:', 'http').indexOf(ApiClient.serverAddress().toLowerCase().replace('https:', 'http').substring(0, 14)) == 0;
|
|
|
|
|
resolve(val);
|
|
|
|
|
}
|
2015-09-10 11:28:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
if (mediaSource.Protocol == 'File') {
|
2015-09-10 11:28:22 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
require(['localassetmanager'], function () {
|
2015-09-20 09:16:06 -07:00
|
|
|
|
|
2015-12-30 13:25:17 -07:00
|
|
|
|
LocalAssetManager.fileExists(mediaSource.Path).then(function (exists) {
|
|
|
|
|
console.log('LocalAssetManager.fileExists: path: ' + mediaSource.Path + ' result: ' + exists);
|
|
|
|
|
resolve(exists);
|
|
|
|
|
});
|
2015-09-20 09:16:06 -07:00
|
|
|
|
});
|
2015-12-30 13:25:17 -07:00
|
|
|
|
}
|
2015-09-10 11:28:22 -07:00
|
|
|
|
}
|
2015-12-30 13:25:17 -07:00
|
|
|
|
else {
|
|
|
|
|
resolve(false);
|
|
|
|
|
}
|
|
|
|
|
});
|
2015-05-25 10:32:22 -07:00
|
|
|
|
};
|
2015-06-26 08:53:49 -07:00
|
|
|
|
|
|
|
|
|
self.showPlayerSelection = showPlayerSelection;
|
2014-03-29 08:40:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.MediaController = new mediaController();
|
|
|
|
|
|
2014-03-29 11:20:42 -07:00
|
|
|
|
function onWebSocketMessageReceived(e, msg) {
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
2014-04-12 10:27:53 -07:00
|
|
|
|
var localPlayer;
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
|
|
|
|
if (msg.MessageType === "Play") {
|
|
|
|
|
|
2014-04-12 10:27:53 -07:00
|
|
|
|
localPlayer = MediaController.getLocalPlayer();
|
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
if (msg.Data.PlayCommand == "PlayNext") {
|
|
|
|
|
localPlayer.queueNext({ ids: msg.Data.ItemIds });
|
|
|
|
|
}
|
|
|
|
|
else if (msg.Data.PlayCommand == "PlayLast") {
|
|
|
|
|
localPlayer.queue({ ids: msg.Data.ItemIds });
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
localPlayer.play({ ids: msg.Data.ItemIds, startPositionTicks: msg.Data.StartPositionTicks });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2014-04-06 10:53:23 -07:00
|
|
|
|
else if (msg.MessageType === "ServerShuttingDown") {
|
|
|
|
|
MediaController.setDefaultPlayerActive();
|
|
|
|
|
}
|
|
|
|
|
else if (msg.MessageType === "ServerRestarting") {
|
|
|
|
|
MediaController.setDefaultPlayerActive();
|
|
|
|
|
}
|
2014-03-29 08:40:32 -07:00
|
|
|
|
else if (msg.MessageType === "Playstate") {
|
|
|
|
|
|
2014-04-12 10:27:53 -07:00
|
|
|
|
localPlayer = MediaController.getLocalPlayer();
|
|
|
|
|
|
2014-03-29 08:40:32 -07:00
|
|
|
|
if (msg.Data.Command === 'Stop') {
|
|
|
|
|
localPlayer.stop();
|
|
|
|
|
}
|
|
|
|
|
else if (msg.Data.Command === 'Pause') {
|
|
|
|
|
localPlayer.pause();
|
|
|
|
|
}
|
|
|
|
|
else if (msg.Data.Command === 'Unpause') {
|
|
|
|
|
localPlayer.unpause();
|
|
|
|
|
}
|
|
|
|
|
else if (msg.Data.Command === 'Seek') {
|
|
|
|
|
localPlayer.seek(msg.Data.SeekPositionTicks);
|
|
|
|
|
}
|
|
|
|
|
else if (msg.Data.Command === 'NextTrack') {
|
|
|
|
|
localPlayer.nextTrack();
|
|
|
|
|
}
|
|
|
|
|
else if (msg.Data.Command === 'PreviousTrack') {
|
|
|
|
|
localPlayer.previousTrack();
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-31 14:04:22 -07:00
|
|
|
|
else if (msg.MessageType === "GeneralCommand") {
|
|
|
|
|
|
|
|
|
|
var cmd = msg.Data;
|
|
|
|
|
|
2014-04-12 10:27:53 -07:00
|
|
|
|
localPlayer = MediaController.getLocalPlayer();
|
|
|
|
|
|
2014-04-30 20:24:55 -07:00
|
|
|
|
MediaController.sendCommand(cmd, localPlayer);
|
2014-03-31 14:04:22 -07:00
|
|
|
|
}
|
2014-03-29 08:40:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2014-10-25 11:32:58 -07:00
|
|
|
|
function initializeApiClient(apiClient) {
|
2015-12-23 10:46:01 -07:00
|
|
|
|
Events.off(apiClient, "websocketmessage", onWebSocketMessageReceived);
|
|
|
|
|
Events.on(apiClient, "websocketmessage", onWebSocketMessageReceived);
|
2014-10-25 11:32:58 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
MediaController.init = function () {
|
2016-01-19 18:10:46 -07:00
|
|
|
|
|
|
|
|
|
console.log('Beginning MediaController.init');
|
2015-05-19 12:15:40 -07:00
|
|
|
|
if (window.ApiClient) {
|
|
|
|
|
initializeApiClient(window.ApiClient);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-23 10:46:01 -07:00
|
|
|
|
Events.on(ConnectionManager, 'apiclientcreated', function (e, apiClient) {
|
2015-05-19 12:15:40 -07:00
|
|
|
|
initializeApiClient(apiClient);
|
|
|
|
|
});
|
2015-12-14 08:43:03 -07:00
|
|
|
|
};
|
2014-03-29 08:40:32 -07:00
|
|
|
|
|
2015-06-29 11:45:42 -07:00
|
|
|
|
function onCastButtonClicked() {
|
2015-07-03 04:51:45 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
showPlayerSelection(this);
|
2015-06-29 11:45:42 -07:00
|
|
|
|
}
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
document.addEventListener('headercreated', function () {
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2016-03-16 13:38:01 -07:00
|
|
|
|
var btnCast = document.querySelector('.viewMenuBar .btnCast');
|
|
|
|
|
btnCast.removeEventListener('click', onCastButtonClicked);
|
|
|
|
|
btnCast.addEventListener('click', onCastButtonClicked);
|
2015-12-14 08:43:03 -07:00
|
|
|
|
});
|
2014-03-29 09:58:49 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
pageClassOn('pagebeforeshow', "page", function () {
|
2014-04-13 10:27:13 -07:00
|
|
|
|
|
|
|
|
|
var page = this;
|
|
|
|
|
|
|
|
|
|
currentDisplayInfo = null;
|
2015-12-14 08:43:03 -07:00
|
|
|
|
});
|
2014-04-13 10:27:13 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
pageClassOn('displayingitem', "libraryPage", function (e) {
|
2014-04-13 10:27:13 -07:00
|
|
|
|
|
2015-12-14 08:43:03 -07:00
|
|
|
|
var info = e.detail;
|
2014-08-25 19:30:52 -07:00
|
|
|
|
mirrorIfEnabled(info);
|
2014-04-13 10:27:13 -07:00
|
|
|
|
});
|
|
|
|
|
|
2016-03-07 12:13:58 -07:00
|
|
|
|
});
|