jellyfin-web/dashboard-ui/scripts/mediacontroller.js

399 lines
11 KiB
JavaScript

(function ($, window) {
function mediaController() {
var self = this;
var currentPlayer;
var currentTargetInfo;
var players = [];
self.registerPlayer = function (player) {
players.push(player);
};
self.getPlayerInfo = function () {
return {
name: currentPlayer.name,
isLocalPlayer: currentPlayer.isLocalPlayer,
id: currentTargetInfo.id,
deviceName: currentTargetInfo.deviceName,
playableMediaTypes: currentTargetInfo.playableMediaTypes
};
};
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');
}
currentPlayer = player;
currentTargetInfo = targetInfo || player.getCurrentTargetInfo();
$(self).trigger('playerchange');
};
self.setDefaultPlayerActive = function() {
self.setActivePlayer(self.getDefaultPlayer());
};
self.removeActivePlayer = function (name) {
if (self.getPlayerInfo().name == name) {
self.setDefaultPlayerActive();
}
};
self.getTargets = function () {
var deferred = $.Deferred();
var promises = players.map(function (p) {
return p.getTargets();
});
$.when.apply($, promises).done(function () {
var targets = [];
for (var i = 0; i < arguments.length; i++) {
var subTargets = arguments[i];
for (var j = 0; j < subTargets.length; j++) {
targets.push(subTargets[j]);
}
}
targets = targets.sort(function(a,b) {
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);
});
deferred.resolveWith(null, [targets]);
});
return deferred.promise();
};
self.play = function (options) {
if (typeof (options) === 'string') {
options = { ids: [options] };
}
currentPlayer.play(options);
};
self.shuffle = function (id) {
currentPlayer.shuffle(id);
};
self.instantMix = function (id) {
currentPlayer.instantMix(id);
};
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) {
if (item.PlayAccess != 'Full') {
return false;
}
if (item.LocationType == "Virtual" || item.IsPlaceHolder) {
return false;
}
if (item.IsFolder || item.Type == "MusicGenre") {
return true;
}
return self.getPlayerInfo().playableMediaTypes.indexOf(item.MediaType) != -1;
};
self.canQueueMediaType = function (mediaType) {
return currentPlayer.canQueueMediaType(mediaType);
};
self.getLocalPlayer = function () {
return currentPlayer.isLocalPlayer ?
currentPlayer :
players.filter(function (p) {
return p.isLocalPlayer;
})[0];
};
self.getDefaultPlayer = function () {
return currentPlayer.isLocalPlayer ?
currentPlayer :
players.filter(function (p) {
return p.isDefaultPlayer;
})[0];
};
self.getCurrentPlayer = function () {
return currentPlayer;
};
self.pause = function () {
currentPlayer.pause();
};
self.stop = function () {
currentPlayer.stop();
};
self.unpause = function () {
currentPlayer.unpause();
};
self.seek = function (position) {
currentPlayer.seek(position);
};
self.currentPlaylistIndex = function (i) {
currentPlayer.currentPlaylistIndex(i);
};
self.removeFromPlaylist = function (i) {
currentPlayer.removeFromPlaylist(i);
};
self.nextTrack = function () {
currentPlayer.nextTrack();
};
self.previousTrack = function () {
currentPlayer.previousTrack();
};
self.mute = function () {
currentPlayer.mute();
};
self.unmute = function () {
currentPlayer.unmute();
};
self.toggleMute = function () {
currentPlayer.toggleMute();
};
self.volumeDown = function () {
currentPlayer.volumeDown();
};
self.volumeUp = function () {
currentPlayer.volumeUp();
};
self.shuffle = function (id) {
currentPlayer.shuffle(id);
};
}
window.MediaController = new mediaController();
function onWebSocketMessageReceived(e, msg) {
var localPlayer = msg.MessageType === "Play" ||
msg.MessageType === "Playstate" ||
msg.MessageType === "GeneralCommand" ?
MediaController.getLocalPlayer() :
null;
if (msg.MessageType === "Play") {
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 });
}
}
else if (msg.MessageType === "ServerShuttingDown") {
MediaController.setDefaultPlayerActive();
}
else if (msg.MessageType === "ServerRestarting") {
MediaController.setDefaultPlayerActive();
}
else if (msg.MessageType === "Playstate") {
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();
}
else if (msg.Data.Command === 'Fullscreen') {
localPlayer.remoteFullscreen();
}
}
else if (msg.MessageType === "GeneralCommand") {
var cmd = msg.Data;
if (cmd.Name === 'Mute') {
localPlayer.mute();
}
else if (cmd.Name === 'Unmute') {
localPlayer.unMute();
}
else if (cmd.Name === 'VolumeUp') {
localPlayer.volumeUp();
}
else if (cmd.Name === 'VolumeDown') {
localPlayer.volumeDown();
}
else if (cmd.Name === 'ToggleMute') {
localPlayer.toggleMute();
}
}
}
$(ApiClient).on("websocketmessage", onWebSocketMessageReceived);
function getTargetsHtml(targets) {
var playerInfo = MediaController.getPlayerInfo();
var html = '';
html += '<h3>Select Player:</h3>';
html += '<fieldset data-role="controlgroup" data-mini="true">';
for (var i = 0, length = targets.length; i < length; i++) {
var target = targets[i];
var id = 'radioPlayerTarget' + i;
var isChecked = target.id == playerInfo.id;
var checkedHtml = isChecked ? ' checked="checked"' : '';
html += '<input type="radio" class="radioSelectPlayerTarget" name="radioSelectPlayerTarget" data-mediatypes="' + target.playableMediaTypes.join(',') + '" data-playername="' + target.playerName + '" data-targetid="' + target.id + '" data-targetname="' + target.name + '" id="' + id + '" value="' + target.id + '"' + checkedHtml + '>';
html += '<label for="' + id + '" style="font-weight:normal;">' + target.name;
if (target.appName) {
html += '<br/><span style="color:#bbb;">' + target.appName + '</span>';
}
html += '</label>';
}
html += '</fieldset>';
html += '<p class="fieldDescription">All plays will be sent to the selected player.</p>';
return html;
}
function showPlayerSelection(page) {
var promise = MediaController.getTargets();
var html = '<div data-role="panel" data-position="right" data-display="overlay" data-position-fixed="true" id="playerSelectionPanel" class="playerSelectionPanel" data-theme="b">';
html += '<div class="players"></div>';
html += '</div>';
$(document.body).append(html);
var elem = $('#playerSelectionPanel').panel({}).trigger('create').panel("open").on("panelafterclose", function () {
$(this).off("panelafterclose").remove();
});
promise.done(function (targets) {
$('.players', elem).html(getTargetsHtml(targets)).trigger('create');
$('.radioSelectPlayerTarget', elem).on('change', function () {
var playerName = this.getAttribute('data-playername');
var targetId = this.getAttribute('data-targetid');
var targetName = this.getAttribute('data-targetname');
var playableMediaTypes = this.getAttribute('data-mediatypes').split(',');
MediaController.setActivePlayer(playerName, {
id: targetId,
name: targetName,
playableMediaTypes: playableMediaTypes
});
});
});
}
$(document).on('headercreated', ".libraryPage", function () {
var page = this;
$('.btnCast', page).on('click', function () {
showPlayerSelection(page);
});
});
})(jQuery, window);