mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
add new mirror mode
This commit is contained in:
parent
2835534c6d
commit
9f83edf9ec
18 changed files with 316 additions and 191 deletions
|
@ -106,7 +106,7 @@
|
||||||
|
|
||||||
#mediaPlayer .ui-slider-track, .nowPlayingBar .ui-slider-track {
|
#mediaPlayer .ui-slider-track, .nowPlayingBar .ui-slider-track {
|
||||||
border-color: #2ad !important;
|
border-color: #2ad !important;
|
||||||
height: 8px!important;
|
height: 2px!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mediaPlayer .ui-slider-handle, .nowPlayingBar .ui-slider-handle {
|
#mediaPlayer .ui-slider-handle, .nowPlayingBar .ui-slider-handle {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Now playing bar */
|
/* Now playing bar */
|
||||||
.nowPlayingBar {
|
.nowPlayingBar {
|
||||||
padding: 10px 0 14px 0;
|
padding: 6px 0 14px 0;
|
||||||
border-top: 2px solid green;
|
border-top: 2px solid green;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingDoubleText {
|
.nowPlayingDoubleText {
|
||||||
top: 0;
|
top: -3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingImage {
|
.nowPlayingImage {
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingBar .currentTime {
|
.nowPlayingBar .currentTime {
|
||||||
top: -12px;
|
top: -15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mediaSlider {
|
.mediaSlider {
|
||||||
|
@ -75,8 +75,8 @@
|
||||||
width: 130px;
|
width: 130px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nowPlayingBar .positionSliderContainer {
|
#nowPlayingBar .sliderContainer {
|
||||||
margin-top: 10px;
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.volumeSliderContainer {
|
.volumeSliderContainer {
|
||||||
|
|
|
@ -1267,6 +1267,10 @@
|
||||||
castPlayer.stopMedia();
|
castPlayer.stopMedia();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.displayContent = function (options) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
self.mute = function () {
|
self.mute = function () {
|
||||||
castPlayer.mute();
|
castPlayer.mute();
|
||||||
};
|
};
|
||||||
|
@ -1280,12 +1284,19 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getTargets = function () {
|
self.getTargets = function () {
|
||||||
|
|
||||||
var targets = [];
|
var targets = [];
|
||||||
targets.push(self.getCurrentTargetInfo());
|
|
||||||
|
if (castPlayer.hasReceivers) {
|
||||||
|
targets.push(self.getCurrentTargetInfo());
|
||||||
|
}
|
||||||
|
|
||||||
return targets;
|
return targets;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getCurrentTargetInfo = function () {
|
self.getCurrentTargetInfo = function () {
|
||||||
|
|
||||||
var appName = null;
|
var appName = null;
|
||||||
if (castPlayer.session && castPlayer.session.receiver && castPlayer.session.friendlyName) {
|
if (castPlayer.session && castPlayer.session.receiver && castPlayer.session.friendlyName) {
|
||||||
appName = castPlayer.session.friendlyName;
|
appName = castPlayer.session.friendlyName;
|
||||||
|
@ -1297,7 +1308,8 @@
|
||||||
playerName: self.name,
|
playerName: self.name,
|
||||||
playableMediaTypes: ["Audio", "Video"],
|
playableMediaTypes: ["Audio", "Video"],
|
||||||
isLocalPlayer: false,
|
isLocalPlayer: false,
|
||||||
appName: appName
|
appName: appName,
|
||||||
|
supportedCommands: []
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -66,18 +66,11 @@
|
||||||
renderDetails(page, item);
|
renderDetails(page, item);
|
||||||
renderTabs(page, item);
|
renderTabs(page, item);
|
||||||
|
|
||||||
if (ApiClient.isWebSocketOpen()) {
|
$(page).trigger('displayingitem', [{
|
||||||
|
|
||||||
var vals = [item.Type, item.Id, item.Name];
|
item: item,
|
||||||
|
context: getParameterByName('context')
|
||||||
var context = getParameterByName('context');
|
}]);
|
||||||
|
|
||||||
if (context) {
|
|
||||||
vals.push(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
|
||||||
}
|
|
||||||
|
|
||||||
Dashboard.getCurrentUser().done(function (user) {
|
Dashboard.getCurrentUser().done(function (user) {
|
||||||
|
|
||||||
|
@ -403,7 +396,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
query = $.extend(query, options || {});
|
query = $.extend(query, options || {});
|
||||||
|
|
||||||
if (query.IncludeItemTypes == "Audio") {
|
if (query.IncludeItemTypes == "Audio") {
|
||||||
query.SortBy = "Album,SortName";
|
query.SortBy = "Album,SortName";
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,11 +75,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.LocalTrailerCount && item.RemoteTrailers.length && item.PlayAccess == 'Full') {
|
if (!item.LocalTrailerCount && item.RemoteTrailers.length && item.PlayAccess == 'Full') {
|
||||||
|
|
||||||
$('.btnPlayExternalTrailer', page).removeClass('hide').attr('href', item.RemoteTrailers[0].Url);
|
$('.btnPlayExternalTrailer', page).removeClass('hide').attr('href', item.RemoteTrailers[0].Url);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$('.btnPlayExternalTrailer', page).addClass('hide').attr('href', '#');
|
$('.btnPlayExternalTrailer', page).addClass('hide').attr('href', '#');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,9 +120,11 @@
|
||||||
|
|
||||||
setPeopleHeader(page, item);
|
setPeopleHeader(page, item);
|
||||||
|
|
||||||
if (ApiClient.isWebSocketOpen()) {
|
$(page).trigger('displayingitem', [{
|
||||||
ApiClient.sendWebSocketMessage("Context", [item.Type, item.Id, item.Name, context].join('|'));
|
|
||||||
}
|
item: item,
|
||||||
|
context: context
|
||||||
|
}]);
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
Dashboard.hideLoadingMsg();
|
||||||
});
|
});
|
||||||
|
|
|
@ -93,9 +93,10 @@
|
||||||
|
|
||||||
Dashboard.setPageTitle(name);
|
Dashboard.setPageTitle(name);
|
||||||
|
|
||||||
if (ApiClient.isWebSocketOpen()) {
|
$(page).trigger('displayingitem', [{
|
||||||
ApiClient.sendWebSocketMessage("Context", [item.Type, item.Id, item.Name].join('|'));
|
|
||||||
}
|
item: item
|
||||||
|
}]);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -203,7 +204,7 @@
|
||||||
}).on('pageshow', "#itemListPage", function () {
|
}).on('pageshow', "#itemListPage", function () {
|
||||||
|
|
||||||
var page = this;
|
var page = this;
|
||||||
|
|
||||||
query.Limit = LibraryBrowser.getDefaultPageSize();
|
query.Limit = LibraryBrowser.getDefaultPageSize();
|
||||||
query.ParentId = getParameterByName('parentId');
|
query.ParentId = getParameterByName('parentId');
|
||||||
query.Filters = "";
|
query.Filters = "";
|
||||||
|
|
|
@ -672,7 +672,7 @@
|
||||||
html += '<a data-itemid="' + item.Id + '" class="' + cssClass + '" data-mediasourcecount="' + mediaSourceCount + '" href="' + href + '">';
|
html += '<a data-itemid="' + item.Id + '" class="' + cssClass + '" data-mediasourcecount="' + mediaSourceCount + '" href="' + href + '">';
|
||||||
|
|
||||||
var style = "";
|
var style = "";
|
||||||
|
options.lazy = false;
|
||||||
if (imgUrl && !options.lazy) {
|
if (imgUrl && !options.lazy) {
|
||||||
style += 'background-image:url(\'' + imgUrl + '\');';
|
style += 'background-image:url(\'' + imgUrl + '\');';
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,14 +135,11 @@
|
||||||
|
|
||||||
$('.userDataIcons', page).html(LibraryBrowser.getUserDataIconsHtml(item));
|
$('.userDataIcons', page).html(LibraryBrowser.getUserDataIconsHtml(item));
|
||||||
|
|
||||||
if (ApiClient.isWebSocketOpen()) {
|
$(page).trigger('displayingitem', [{
|
||||||
|
|
||||||
var vals = [item.Type, item.Id, item.Name];
|
item: item,
|
||||||
|
context: 'livetv'
|
||||||
vals.push('livetv');
|
}]);
|
||||||
|
|
||||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
|
||||||
}
|
|
||||||
|
|
||||||
Dashboard.getCurrentUser().done(function (user) {
|
Dashboard.getCurrentUser().done(function (user) {
|
||||||
|
|
||||||
|
|
|
@ -50,14 +50,11 @@
|
||||||
|
|
||||||
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', page), item);
|
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', page), item);
|
||||||
|
|
||||||
if (ApiClient.isWebSocketOpen()) {
|
$(page).trigger('displayingitem', [{
|
||||||
|
|
||||||
var vals = [item.Type, item.Id, item.Name];
|
item: item,
|
||||||
|
context: 'livetv'
|
||||||
vals.push('livetv');
|
}]);
|
||||||
|
|
||||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.TimerId) {
|
if (item.TimerId) {
|
||||||
$('#cancelRecordingButtonContainer', page).show();
|
$('#cancelRecordingButtonContainer', page).show();
|
||||||
|
|
|
@ -55,14 +55,11 @@
|
||||||
|
|
||||||
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', page), item);
|
LiveTvHelpers.renderMiscProgramInfo($('.miscTvProgramInfo', page), item);
|
||||||
|
|
||||||
if (ApiClient.isWebSocketOpen()) {
|
$(page).trigger('displayingitem', [{
|
||||||
|
|
||||||
var vals = [item.Type, item.Id, item.Name];
|
item: item,
|
||||||
|
context: 'livetv'
|
||||||
vals.push('livetv');
|
}]);
|
||||||
|
|
||||||
ApiClient.sendWebSocketMessage("Context", vals.join('|'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.recordingStatus', page).html('Status: ' + item.Status);
|
$('.recordingStatus', page).html('Status: ' + item.Status);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,26 @@
|
||||||
(function ($, window) {
|
(function ($, window) {
|
||||||
|
|
||||||
|
var enableMirrorMode;
|
||||||
|
var currentDisplayInfo;
|
||||||
|
|
||||||
|
function mirrorItem(info) {
|
||||||
|
|
||||||
|
var item = info.item;
|
||||||
|
|
||||||
|
MediaController.getCurrentPlayer().displayContent({
|
||||||
|
|
||||||
|
itemName: item.Name,
|
||||||
|
itemId: item.Id,
|
||||||
|
itemType: item.Type,
|
||||||
|
context: info.context
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function mediaController() {
|
function mediaController() {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var currentPlayer;
|
var currentPlayer;
|
||||||
var currentTargetInfo;
|
var currentTargetInfo;
|
||||||
|
|
||||||
var players = [];
|
var players = [];
|
||||||
|
|
||||||
self.registerPlayer = function (player) {
|
self.registerPlayer = function (player) {
|
||||||
|
@ -308,11 +323,11 @@
|
||||||
else if (cmd.Name === 'ToggleMute') {
|
else if (cmd.Name === 'ToggleMute') {
|
||||||
localPlayer.toggleMute();
|
localPlayer.toggleMute();
|
||||||
}
|
}
|
||||||
else if (msg.Data.Command === 'Fullscreen') {
|
else if (cmd.Name === 'Fullscreen') {
|
||||||
localPlayer.remoteFullscreen();
|
localPlayer.remoteFullscreen();
|
||||||
}
|
}
|
||||||
else if (msg.Data.Command === 'SetVolume') {
|
else if (cmd.Name === 'SetVolume') {
|
||||||
localPlayer.setVolume(cmd.Arguments.Volume);
|
localPlayer.setVolume(parseFloat(cmd.Arguments.Volume));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +339,9 @@
|
||||||
var playerInfo = MediaController.getPlayerInfo();
|
var playerInfo = MediaController.getPlayerInfo();
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
html += '<h3>Select Player:</h3>';
|
html += '<form>';
|
||||||
|
|
||||||
|
html += '<form><h3>Select Player:</h3>';
|
||||||
html += '<fieldset data-role="controlgroup" data-mini="true">';
|
html += '<fieldset data-role="controlgroup" data-mini="true">';
|
||||||
|
|
||||||
for (var i = 0, length = targets.length; i < length; i++) {
|
for (var i = 0, length = targets.length; i < length; i++) {
|
||||||
|
@ -336,7 +353,9 @@
|
||||||
var isChecked = target.id == playerInfo.id;
|
var isChecked = target.id == playerInfo.id;
|
||||||
var checkedHtml = isChecked ? ' checked="checked"' : '';
|
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 + '>';
|
var mirror = (!target.isLocalPlayer && target.supportedCommands.indexOf('DisplayContent') != -1) ? 'true' : 'false';
|
||||||
|
|
||||||
|
html += '<input type="radio" class="radioSelectPlayerTarget" name="radioSelectPlayerTarget" data-mirror="' + mirror + '" 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;
|
html += '<label for="' + id + '" style="font-weight:normal;">' + target.name;
|
||||||
|
|
||||||
if (target.appName) {
|
if (target.appName) {
|
||||||
|
@ -350,6 +369,11 @@
|
||||||
|
|
||||||
html += '<p class="fieldDescription">All plays will be sent to the selected player.</p>';
|
html += '<p class="fieldDescription">All plays will be sent to the selected player.</p>';
|
||||||
|
|
||||||
|
var checkedHtml = enableMirrorMode ? ' checked="checked"' : '';
|
||||||
|
html += '<div style="margin-top:1.5em;" class="fldMirrorMode"><label for="chkEnableMirrorMode">Enable Mirror Mode</label><input type="checkbox" class="chkEnableMirrorMode" id="chkEnableMirrorMode" data-mini="true"' + checkedHtml + ' /></div>';
|
||||||
|
|
||||||
|
html += '</form>';
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,8 +398,36 @@
|
||||||
|
|
||||||
$('.players', elem).html(getTargetsHtml(targets)).trigger('create');
|
$('.players', elem).html(getTargetsHtml(targets)).trigger('create');
|
||||||
|
|
||||||
|
$('.chkEnableMirrorMode', elem).on().on('change', function () {
|
||||||
|
enableMirrorMode = this.checked;
|
||||||
|
|
||||||
|
if (this.checked && currentDisplayInfo) {
|
||||||
|
|
||||||
|
mirrorItem(currentDisplayInfo);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
$('.radioSelectPlayerTarget', elem).on('change', function () {
|
$('.radioSelectPlayerTarget', elem).on('change', function () {
|
||||||
|
|
||||||
|
var supportsMirror = this.getAttribute('data-mirror') == 'true';
|
||||||
|
|
||||||
|
if (supportsMirror) {
|
||||||
|
$('.fldMirrorMode', elem).show();
|
||||||
|
} else {
|
||||||
|
$('.fldMirrorMode', elem).hide();
|
||||||
|
$('.chkEnableMirrorMode', elem).checked(false).trigger('change').checkboxradio('refresh');
|
||||||
|
}
|
||||||
|
|
||||||
|
}).each(function () {
|
||||||
|
|
||||||
|
if (this.checked) {
|
||||||
|
$(this).trigger('change');
|
||||||
|
}
|
||||||
|
|
||||||
|
}).on('change', function () {
|
||||||
|
|
||||||
var playerName = this.getAttribute('data-playername');
|
var playerName = this.getAttribute('data-playername');
|
||||||
var targetId = this.getAttribute('data-targetid');
|
var targetId = this.getAttribute('data-targetid');
|
||||||
var targetName = this.getAttribute('data-targetname');
|
var targetName = this.getAttribute('data-targetname');
|
||||||
|
@ -401,4 +453,21 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).on('pagebeforeshow', ".page", function () {
|
||||||
|
|
||||||
|
var page = this;
|
||||||
|
|
||||||
|
currentDisplayInfo = null;
|
||||||
|
|
||||||
|
}).on('displayingitem', ".libraryPage", function (e, info) {
|
||||||
|
|
||||||
|
var page = this;
|
||||||
|
|
||||||
|
currentDisplayInfo = info;
|
||||||
|
|
||||||
|
if (enableMirrorMode) {
|
||||||
|
mirrorItem(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
})(jQuery, window);
|
})(jQuery, window);
|
|
@ -28,7 +28,8 @@
|
||||||
id: ApiClient.deviceId(),
|
id: ApiClient.deviceId(),
|
||||||
playerName: self.name,
|
playerName: self.name,
|
||||||
playableMediaTypes: ['Audio', 'Video'],
|
playableMediaTypes: ['Audio', 'Video'],
|
||||||
isLocalPlayer: true
|
isLocalPlayer: true,
|
||||||
|
supportedCommands: Dashboard.getSupportedRemoteCommands()
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return targets;
|
return targets;
|
||||||
|
@ -521,19 +522,60 @@
|
||||||
url = "css/images/items/detail/video.png";
|
url = "css/images/items/detail/video.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = state.itemName;
|
|
||||||
|
|
||||||
var nowPlayingTextElement = $('.nowPlayingText', mediaControls);
|
var nowPlayingTextElement = $('.nowPlayingText', mediaControls);
|
||||||
|
var nameHtml = self.getNowPlayingNameHtml(state);
|
||||||
|
|
||||||
if (state.itemSubName) {
|
if (nameHtml.indexOf('<br/>') != -1) {
|
||||||
name += '<br/>' + state.itemSubName;
|
|
||||||
nowPlayingTextElement.addClass('nowPlayingDoubleText');
|
nowPlayingTextElement.addClass('nowPlayingDoubleText');
|
||||||
} else {
|
} else {
|
||||||
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
|
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.nowPlayingImage', mediaControls).html('<img src="' + url + '" />');
|
$('.nowPlayingImage', mediaControls).html('<img src="' + url + '" />');
|
||||||
nowPlayingTextElement.html(name);
|
nowPlayingTextElement.html(nameHtml);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getNowPlayingNameHtml = function (playerState) {
|
||||||
|
|
||||||
|
var topText = playerState.itemName;
|
||||||
|
|
||||||
|
if (playerState.mediaType == 'Video') {
|
||||||
|
if (playerState.indexNumber != null) {
|
||||||
|
topText = playerState.indexNumber + " - " + topText;
|
||||||
|
}
|
||||||
|
if (playerState.parentIndexNumber != null) {
|
||||||
|
topText = playerState.parentIndexNumber + "." + topText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var bottomText = '';
|
||||||
|
|
||||||
|
if (playerState.artists && playerState.artists.length) {
|
||||||
|
bottomText = topText;
|
||||||
|
topText = playerState.artists[0];
|
||||||
|
}
|
||||||
|
else if (playerState.seriesName || playerState.album) {
|
||||||
|
bottomText = topText;
|
||||||
|
topText = playerState.seriesName || playerState.album;
|
||||||
|
}
|
||||||
|
else if (playerState.productionYear) {
|
||||||
|
bottomText = playerState.productionYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bottomText ? topText + '<br/>' + bottomText : topText;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.displayContent = function (options) {
|
||||||
|
|
||||||
|
// Handle it the same as a remote control command
|
||||||
|
Dashboard.onBrowseCommand({
|
||||||
|
|
||||||
|
ItemName: options.itemName,
|
||||||
|
ItemType: options.itemType,
|
||||||
|
ItemId: options.itemId,
|
||||||
|
Context: options.context
|
||||||
|
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getItemsForPlayback = function (query) {
|
self.getItemsForPlayback = function (query) {
|
||||||
|
@ -894,7 +936,7 @@
|
||||||
return currentMediaElement;
|
return currentMediaElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getPlayerState = function() {
|
self.getPlayerState = function () {
|
||||||
|
|
||||||
var deferred = $.Deferred();
|
var deferred = $.Deferred();
|
||||||
|
|
||||||
|
@ -930,41 +972,15 @@
|
||||||
state.itemId = item.Id;
|
state.itemId = item.Id;
|
||||||
state.mediaType = item.MediaType;
|
state.mediaType = item.MediaType;
|
||||||
state.itemType = item.Type;
|
state.itemType = item.Type;
|
||||||
|
state.indexNumber = item.IndexNumber;
|
||||||
var itemName = '';
|
state.indexNumberEnd = item.IndexNumberEnd;
|
||||||
var itemSubName = '';
|
state.parentIndexNumber = item.ParentIndexNumber;
|
||||||
|
state.productionYear = item.ProductionYear;
|
||||||
var name = item.Name;
|
state.premiereDate = item.PremiereDate;
|
||||||
var seriesName = '';
|
state.seriesName = item.SeriesName;
|
||||||
|
state.album = item.Album;
|
||||||
// Channel number
|
state.itemName = item.Name;
|
||||||
if (item.Number) {
|
state.artists = item.Artists;
|
||||||
name = item.Number + ' ' + name;
|
|
||||||
}
|
|
||||||
if (item.IndexNumber != null) {
|
|
||||||
name = item.IndexNumber + " - " + name;
|
|
||||||
}
|
|
||||||
if (item.ParentIndexNumber != null) {
|
|
||||||
name = item.ParentIndexNumber + "." + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.CurrentProgram) {
|
|
||||||
seriesName = item.CurrentProgram.Name;
|
|
||||||
}
|
|
||||||
else if (item.SeriesName || item.Album) {
|
|
||||||
seriesName = item.SeriesName || item.Album;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seriesName) {
|
|
||||||
itemName = seriesName;
|
|
||||||
itemSubName = name;
|
|
||||||
} else {
|
|
||||||
itemName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itemSubName && item.ProductionYear) {
|
|
||||||
itemSubName = item.ProductionYear;
|
|
||||||
}
|
|
||||||
|
|
||||||
var imageTags = item.ImageTags || {};
|
var imageTags = item.ImageTags || {};
|
||||||
|
|
||||||
|
@ -973,6 +989,16 @@
|
||||||
state.primaryImageItemId = item.Id;
|
state.primaryImageItemId = item.Id;
|
||||||
state.primaryImageTag = imageTags.Primary;
|
state.primaryImageTag = imageTags.Primary;
|
||||||
}
|
}
|
||||||
|
else if (item.AlbumPrimaryImageTag) {
|
||||||
|
|
||||||
|
state.primaryImageItemId = item.AlbumId;
|
||||||
|
state.primaryImageTag = item.AlbumPrimaryImageTag;
|
||||||
|
}
|
||||||
|
else if (item.SeriesPrimaryImageTag) {
|
||||||
|
|
||||||
|
state.primaryImageItemId = item.SeriesId;
|
||||||
|
state.primaryImageTag = item.SeriesPrimaryImageTag;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||||
|
|
||||||
|
@ -985,9 +1011,6 @@
|
||||||
state.thumbItemId = item.Id;
|
state.thumbItemId = item.Id;
|
||||||
state.thumbImageTag = imageTags.Thumb;
|
state.thumbImageTag = imageTags.Thumb;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.itemName = itemName;
|
|
||||||
state.itemSubName = itemSubName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -1123,6 +1146,7 @@
|
||||||
return $('.mediaPlayerAudio');
|
return $('.mediaPlayerAudio');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var supportsAac = document.createElement('audio').canPlayType('audio/aac').replace(/no/, '');
|
||||||
function playAudio(item, mediaSource, startPositionTicks) {
|
function playAudio(item, mediaSource, startPositionTicks) {
|
||||||
|
|
||||||
startPositionTicks = startPositionTicks || 0;
|
startPositionTicks = startPositionTicks || 0;
|
||||||
|
@ -1134,29 +1158,35 @@
|
||||||
mediaSourceId: mediaSource.Id
|
mediaSourceId: mediaSource.Id
|
||||||
};
|
};
|
||||||
|
|
||||||
var mp3Url = ApiClient.getUrl('Audio/' + item.Id + '/stream.mp3', $.extend({}, baseParams, {
|
var sourceContainer = (mediaSource.Container || '').toLowerCase();
|
||||||
audioCodec: 'mp3'
|
var isStatic = false;
|
||||||
|
|
||||||
|
if (sourceContainer == 'mp3' ||
|
||||||
|
(sourceContainer == 'aac' && supportsAac)) {
|
||||||
|
|
||||||
|
for (var i = 0, length = mediaSource.MediaStreams.length; i < length; i++) {
|
||||||
|
|
||||||
|
var stream = mediaSource.MediaStreams[i];
|
||||||
|
|
||||||
|
if (stream.Type == "Audio") {
|
||||||
|
|
||||||
|
// Stream statically when possible
|
||||||
|
if (stream.BitRate <= 256000) {
|
||||||
|
isStatic = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputContainer = isStatic ? sourceContainer : 'mp3';
|
||||||
|
var audioUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.' + outputContainer, $.extend({}, baseParams, {
|
||||||
|
audioCodec: outputContainer
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var mediaStreams = mediaSource.MediaStreams;
|
if (isStatic) {
|
||||||
|
var seekParam = startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
|
||||||
var isStatic = false;
|
audioUrl += "&static=true" + seekParam;
|
||||||
var seekParam = startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
|
|
||||||
|
|
||||||
for (var i = 0, length = mediaStreams.length; i < length; i++) {
|
|
||||||
|
|
||||||
var stream = mediaStreams[i];
|
|
||||||
|
|
||||||
if (stream.Type == "Audio") {
|
|
||||||
|
|
||||||
var container = (mediaSource.Container || '').toLowerCase();
|
|
||||||
// Stream statically when possible
|
|
||||||
if (container == 'mp3' && stream.BitRate <= 256000) {
|
|
||||||
mp3Url += "&static=true" + seekParam;
|
|
||||||
isStatic = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.startTimeTicksOffset = isStatic ? 0 : startPositionTicks;
|
self.startTimeTicksOffset = isStatic ? 0 : startPositionTicks;
|
||||||
|
@ -1165,7 +1195,7 @@
|
||||||
|
|
||||||
return getAudioElement().each(function () {
|
return getAudioElement().each(function () {
|
||||||
|
|
||||||
this.src = mp3Url;
|
this.src = audioUrl;
|
||||||
this.volume = initialVolume;
|
this.volume = initialVolume;
|
||||||
this.play();
|
this.play();
|
||||||
|
|
||||||
|
|
|
@ -222,18 +222,18 @@
|
||||||
updateNowPlayingInfo(state);
|
updateNowPlayingInfo(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentImgUrl;
|
||||||
function updateNowPlayingInfo(state) {
|
function updateNowPlayingInfo(state) {
|
||||||
|
|
||||||
var name = state.itemName;
|
var nameHtml = MediaPlayer.getNowPlayingNameHtml(state);
|
||||||
|
|
||||||
if (state.itemSubName) {
|
if (nameHtml.indexOf('<br/>') != -1) {
|
||||||
name += '<br/>' + state.itemSubName;
|
|
||||||
nowPlayingTextElement.addClass('nowPlayingDoubleText');
|
nowPlayingTextElement.addClass('nowPlayingDoubleText');
|
||||||
} else {
|
} else {
|
||||||
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
|
nowPlayingTextElement.removeClass('nowPlayingDoubleText');
|
||||||
}
|
}
|
||||||
|
|
||||||
nowPlayingTextElement.html(name);
|
nowPlayingTextElement.html(nameHtml);
|
||||||
|
|
||||||
var url;
|
var url;
|
||||||
|
|
||||||
|
@ -273,6 +273,12 @@
|
||||||
url = "css/images/items/detail/video.png";
|
url = "css/images/items/detail/video.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (url == currentImgUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentImgUrl = url;
|
||||||
|
|
||||||
nowPlayingImageElement.html('<img src="' + url + '" />');
|
nowPlayingImageElement.html('<img src="' + url + '" />');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -529,6 +529,18 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.displayContent = function (options) {
|
||||||
|
|
||||||
|
sendCommand('DisplayContent', {
|
||||||
|
|
||||||
|
ItemName: options.itemName,
|
||||||
|
ItemType: options.itemType,
|
||||||
|
ItemId: options.itemId,
|
||||||
|
Context: options.context
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.getPlayerState = function () {
|
self.getPlayerState = function () {
|
||||||
|
|
||||||
var deferred = $.Deferred();
|
var deferred = $.Deferred();
|
||||||
|
@ -615,7 +627,8 @@
|
||||||
playerName: self.name,
|
playerName: self.name,
|
||||||
appName: s.Client,
|
appName: s.Client,
|
||||||
playableMediaTypes: s.PlayableMediaTypes,
|
playableMediaTypes: s.PlayableMediaTypes,
|
||||||
isLocalPlayer: false
|
isLocalPlayer: false,
|
||||||
|
supportedCommands: s.SupportedCommands
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -648,13 +661,17 @@
|
||||||
if (item) {
|
if (item) {
|
||||||
|
|
||||||
state.itemId = item.Id;
|
state.itemId = item.Id;
|
||||||
state.itemType = item.Type;
|
|
||||||
state.mediaType = item.MediaType;
|
state.mediaType = item.MediaType;
|
||||||
state.runtimeTicks = item.RunTimeTicks;
|
state.itemType = item.Type;
|
||||||
state.mediaSource = item.MediaSourceId;
|
state.indexNumber = item.IndexNumber;
|
||||||
state.positionTicks = session.NowPlayingPositionTicks || 0;
|
state.indexNumberEnd = item.IndexNumberEnd;
|
||||||
|
state.parentIndexNumber = item.ParentIndexNumber;
|
||||||
|
state.productionYear = item.ProductionYear;
|
||||||
|
state.premiereDate = item.PremiereDate;
|
||||||
|
state.seriesName = item.SeriesName;
|
||||||
|
state.album = item.Album;
|
||||||
state.itemName = item.Name;
|
state.itemName = item.Name;
|
||||||
|
state.artists = item.Artists;
|
||||||
|
|
||||||
state.primaryImageItemId = item.PrimaryImageItemId;
|
state.primaryImageItemId = item.PrimaryImageItemId;
|
||||||
state.primaryImageTag = item.PrimaryImageTag;
|
state.primaryImageTag = item.PrimaryImageTag;
|
||||||
|
@ -664,6 +681,10 @@
|
||||||
|
|
||||||
state.thumbItemId = item.ThumbItemId;
|
state.thumbItemId = item.ThumbItemId;
|
||||||
state.thumbImageTag = item.ThumbImageTag;
|
state.thumbImageTag = item.ThumbImageTag;
|
||||||
|
|
||||||
|
state.mediaSource = item.MediaSourceId;
|
||||||
|
state.positionTicks = session.NowPlayingPositionTicks || 0;
|
||||||
|
state.runtimeTicks = item.RunTimeTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -263,6 +263,8 @@ var Dashboard = {
|
||||||
|
|
||||||
var html = '<span style="margin-right: 1em;">Please refresh this page to receive new updates from the server.</span>';
|
var html = '<span style="margin-right: 1em;">Please refresh this page to receive new updates from the server.</span>';
|
||||||
|
|
||||||
|
html += '<button type="button" data-icon="refresh" onclick="$(this).buttonEnabled(false);Dashboard.reloadPage();" data-theme="b" data-inline="true" data-mini="true">Refresh</button>';
|
||||||
|
|
||||||
Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false });
|
Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -801,6 +803,16 @@ var Dashboard = {
|
||||||
ApiClient.openWebSocket(webSocketUrl);
|
ApiClient.openWebSocket(webSocketUrl);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onWebSocketOpened: function () {
|
||||||
|
|
||||||
|
ApiClient.reportCapabilities({
|
||||||
|
PlayableMediaTypes: "Audio,Video",
|
||||||
|
|
||||||
|
SupportedCommands: Dashboard.getSupportedRemoteCommands().join(',')
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
onWebSocketMessageReceived: function (e, data) {
|
onWebSocketMessageReceived: function (e, data) {
|
||||||
|
|
||||||
var msg = data;
|
var msg = data;
|
||||||
|
@ -878,10 +890,6 @@ var Dashboard = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (msg.MessageType === "Browse") {
|
|
||||||
|
|
||||||
Dashboard.onBrowseCommand(msg.Data);
|
|
||||||
}
|
|
||||||
else if (msg.MessageType === "GeneralCommand") {
|
else if (msg.MessageType === "GeneralCommand") {
|
||||||
|
|
||||||
var cmd = msg.Data;
|
var cmd = msg.Data;
|
||||||
|
@ -892,6 +900,9 @@ var Dashboard = {
|
||||||
else if (cmd.Name === 'GoToSettings') {
|
else if (cmd.Name === 'GoToSettings') {
|
||||||
Dashboard.navigate('dashboard.html');
|
Dashboard.navigate('dashboard.html');
|
||||||
}
|
}
|
||||||
|
else if (cmd.Name === 'DisplayContent') {
|
||||||
|
Dashboard.onBrowseCommand(cmd.Arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (msg.MessageType === "MessageCommand") {
|
else if (msg.MessageType === "MessageCommand") {
|
||||||
|
|
||||||
|
@ -1237,6 +1248,27 @@ var Dashboard = {
|
||||||
}
|
}
|
||||||
|
|
||||||
$(select).html(html).selectmenu("refresh");
|
$(select).html(html).selectmenu("refresh");
|
||||||
|
},
|
||||||
|
|
||||||
|
getSupportedRemoteCommands: function () {
|
||||||
|
|
||||||
|
// Full list
|
||||||
|
// https://github.com/MediaBrowser/MediaBrowser/blob/master/MediaBrowser.Model/Session/GeneralCommand.cs
|
||||||
|
return [
|
||||||
|
"GoHome",
|
||||||
|
"GoToSettings",
|
||||||
|
"VolumeUp",
|
||||||
|
"VolumeDown",
|
||||||
|
"Mute",
|
||||||
|
"Unmute",
|
||||||
|
"ToggleMute",
|
||||||
|
"SetVolume",
|
||||||
|
"ToggleFullscreen",
|
||||||
|
"SetAudioStreamIndex",
|
||||||
|
"SetSubtitleStreamIndex",
|
||||||
|
"DisplayContent"
|
||||||
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1252,7 +1284,7 @@ else if (!IsStorageEnabled()) {
|
||||||
|
|
||||||
var ApiClient = MediaBrowser.ApiClient.create("Dashboard", window.dashboardVersion);
|
var ApiClient = MediaBrowser.ApiClient.create("Dashboard", window.dashboardVersion);
|
||||||
|
|
||||||
$(ApiClient).on("websocketmessage", Dashboard.onWebSocketMessageReceived);
|
$(ApiClient).on("websocketopen", Dashboard.onWebSocketOpened).on("websocketmessage", Dashboard.onWebSocketMessageReceived);
|
||||||
|
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
@ -1327,7 +1359,7 @@ $(function () {
|
||||||
mediaPlayerElem.trigger('create');
|
mediaPlayerElem.trigger('create');
|
||||||
|
|
||||||
var footerHtml = '<div id="footer" data-theme="b" class="ui-bar-b">';
|
var footerHtml = '<div id="footer" data-theme="b" class="ui-bar-b">';
|
||||||
|
|
||||||
footerHtml += '<div id="footerNotifications"></div>';
|
footerHtml += '<div id="footerNotifications"></div>';
|
||||||
footerHtml += '</div>';
|
footerHtml += '</div>';
|
||||||
|
|
||||||
|
@ -1335,7 +1367,7 @@ $(function () {
|
||||||
|
|
||||||
var footerElem = $('#footer', document.body);
|
var footerElem = $('#footer', document.body);
|
||||||
footerElem.trigger('create');
|
footerElem.trigger('create');
|
||||||
|
|
||||||
$(window).on("beforeunload", function () {
|
$(window).on("beforeunload", function () {
|
||||||
|
|
||||||
// Close the connection gracefully when possible
|
// Close the connection gracefully when possible
|
||||||
|
|
|
@ -1,29 +1,11 @@
|
||||||
var SupporterPage = {
|
(function () {
|
||||||
|
|
||||||
onPageShow: function () {
|
$(document).on('pageshow', "#supporterPage", function () {
|
||||||
SupporterPage.load();
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageHide: function () {
|
var page = this;
|
||||||
|
|
||||||
|
$('#paypalReturnUrl', page).val(ApiClient.getUrl("supporterkey.html"));
|
||||||
|
|
||||||
},
|
});
|
||||||
|
|
||||||
load: function() {
|
})();
|
||||||
Dashboard.showLoadingMsg();
|
|
||||||
var page = $.mobile.activePage;
|
|
||||||
|
|
||||||
ApiClient.getPluginSecurityInfo().done(function (info) {
|
|
||||||
$('#txtSupporterKey', page).val(info.SupporterKey);
|
|
||||||
if (info.IsMBSupporter) {
|
|
||||||
$('.supporterOnly', page).show();
|
|
||||||
} else {
|
|
||||||
$('.supporterOnly', page).hide();
|
|
||||||
}
|
|
||||||
$('#paypalReturnUrl', page).val(ApiClient.getUrl("supporterkey.html"));
|
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$(document).on('pageshow', "#supporterPage", SupporterPage.onPageShow)
|
|
||||||
.on('pagehide', "#supporterPage", SupporterPage.onPageHide);
|
|
|
@ -18,15 +18,9 @@
|
||||||
</div>
|
</div>
|
||||||
<h3>Support the Media Browser Team</h3>
|
<h3>Support the Media Browser Team</h3>
|
||||||
<p>
|
<p>
|
||||||
Help ensure the continued development of this product by donating a minimum of $10 (greater amounts greatly appreciated). A portion of all donations will be contributed to other <a href="about.html">free tools</a> we depend on.
|
Help ensure the continued development of this project by donating. A portion of all donations will be contributed to other <a href="about.html">free tools</a> we depend on.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p style="display: none; padding: 1em; border-radius: 5px; font-weight: normal;" class="ui-bar-a supporterOnly">
|
|
||||||
<strong>Thank You</strong> for your past support of the Media Browser Team. Users like you make it possible for
|
|
||||||
Media Browser to exist and keep getting better and better. You can always support us again if you feel you are getting maximum
|
|
||||||
value from the product.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<br />
|
<br />
|
||||||
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr"
|
<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr"
|
||||||
method="post">
|
method="post">
|
||||||
|
|
|
@ -1728,6 +1728,16 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.reportCapabilities = function (options) {
|
||||||
|
|
||||||
|
var url = self.getUrl("Sessions/Capabilities", options);
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
self.updateItemImageIndex = function (itemId, itemType, itemName, imageType, imageIndex, newIndex) {
|
self.updateItemImageIndex = function (itemId, itemType, itemName, imageType, imageIndex, newIndex) {
|
||||||
|
|
||||||
if (!imageType) {
|
if (!imageType) {
|
||||||
|
@ -3758,24 +3768,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
self.sendBrowseCommand = function (sessionId, options) {
|
|
||||||
|
|
||||||
if (!sessionId) {
|
|
||||||
throw new Error("null sessionId");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options) {
|
|
||||||
throw new Error("null options");
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = self.getUrl("Sessions/" + sessionId + "/Viewing", options);
|
|
||||||
|
|
||||||
return self.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.sendPlayCommand = function (sessionId, options) {
|
self.sendPlayCommand = function (sessionId, options) {
|
||||||
|
|
||||||
if (!sessionId) {
|
if (!sessionId) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue