1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
This commit is contained in:
Tavares André 2015-04-30 18:20:10 +02:00
commit bb77192e8c
21 changed files with 404 additions and 151 deletions

View file

@ -336,8 +336,7 @@
var player = this;
var bitrateSetting = AppSettings.maxStreamingBitrate();
bitrateSetting = Math.min(bitrateSetting, 10000000);
var bitrateSetting = AppSettings.maxChromecastBitrate();
var receiverName = null;

View file

@ -155,49 +155,49 @@
if (item.MovieCount) {
html += '<input type="radio" name="ibnItems" id="radioMovies" class="context-movies" value="on">';
html += '<label for="radioMovies">'+Globalize.translate('TabMovies')+'</label>';
html += '<label for="radioMovies">' + Globalize.translate('TabMovies') + '</label>';
}
if (item.SeriesCount) {
html += '<input type="radio" name="ibnItems" id="radioShows" class="context-tv" value="on">';
html += '<label for="radioShows">'+Globalize.translate('TabSeries')+'</label>';
html += '<label for="radioShows">' + Globalize.translate('TabSeries') + '</label>';
}
if (item.EpisodeCount) {
html += '<input type="radio" name="ibnItems" id="radioEpisodes" class="context-tv" value="on">';
html += '<label for="radioEpisodes">'+Globalize.translate('TabEpisodes')+'</label>';
html += '<label for="radioEpisodes">' + Globalize.translate('TabEpisodes') + '</label>';
}
if (item.TrailerCount) {
html += '<input type="radio" name="ibnItems" id="radioTrailers" class="context-movies" value="on">';
html += '<label for="radioTrailers">'+Globalize.translate('TabTrailers')+'</label>';
html += '<label for="radioTrailers">' + Globalize.translate('TabTrailers') + '</label>';
}
if (item.GameCount) {
html += '<input type="radio" name="ibnItems" id="radioGames" class="context-games" value="on">';
html += '<label for="radioGames">'+Globalize.translate('TabGames')+'</label>';
html += '<label for="radioGames">' + Globalize.translate('TabGames') + '</label>';
}
if (item.AlbumCount) {
html += '<input type="radio" name="ibnItems" id="radioAlbums" class="context-music" value="on">';
html += '<label for="radioAlbums">'+Globalize.translate('TabAlbums')+'</label>';
html += '<label for="radioAlbums">' + Globalize.translate('TabAlbums') + '</label>';
}
if (item.SongCount) {
html += '<input type="radio" name="ibnItems" id="radioSongs" class="context-music" value="on">';
html += '<label for="radioSongs">'+Globalize.translate('TabSongs')+'</label>';
html += '<label for="radioSongs">' + Globalize.translate('TabSongs') + '</label>';
}
if (item.MusicVideoCount) {
html += '<input type="radio" name="ibnItems" id="radioMusicVideos" class="context-music" value="on">';
html += '<label for="radioMusicVideos">'+Globalize.translate('TabMusicVideos')+'</label>';
html += '<label for="radioMusicVideos">' + Globalize.translate('TabMusicVideos') + '</label>';
}
html += '</fieldset>';
@ -385,7 +385,7 @@
}
}
function getItemsFunction(options) {
function getQuery(options) {
var query = {
@ -407,6 +407,13 @@
addCurrentItemToQuery(query);
return query;
}
function getItemsFunction(options) {
var query = getQuery(options);
return function (index, limit, fields) {
query.StartIndex = index;
@ -424,27 +431,10 @@
Dashboard.showLoadingMsg();
_childrenItemsFunction = getItemsFunction(options);
var query = {
SortBy: "SortName",
SortOrder: "Ascending",
IncludeItemTypes: "",
Recursive: true,
Fields: "AudioInfo,SeriesInfo,ParentId,PrimaryImageAspectRatio,SyncInfo",
Limit: LibraryBrowser.getDefaultPageSize(),
StartIndex: 0,
CollapseBoxSetItems: false
};
var query = getQuery(options);
query = $.extend(query, options || {});
if (query.IncludeItemTypes == "Audio") {
query.SortBy = "AlbumArtist,Album,SortName";
}
addCurrentItemToQuery(query);
ApiClient.getItems(Dashboard.getCurrentUserId(), query).done(function (result) {
getItemsFunction(options)(options.StartIndex, options.Limit, options.Fields).done(function (result) {
var html = '';

View file

@ -282,6 +282,9 @@
$('.lnkMovies', page).addClass('ui-btn-active');
}
}
else if (context == 'channels') {
elem = $('.channelTabs', page).show();
}
else if (item.Type == "MusicAlbum") {
$('#albumTabs', page).show();
}
@ -627,6 +630,7 @@
promise = ApiClient.getSimilarTrailers(item.Id, options);
}
else if (item.Type == "MusicAlbum") {
options.limit = 4;
promise = ApiClient.getSimilarAlbums(item.Id, options);
}
else if (item.Type == "Series") {
@ -1314,7 +1318,7 @@
if (stream.ChannelLayout) {
attributes.push(createAttribute(Globalize.translate('MediaInfoLayout'), stream.ChannelLayout));
}
else if (stream.Channels) {
if (stream.Channels) {
attributes.push(createAttribute(Globalize.translate('MediaInfoChannels'), stream.Channels + ' ch'));
}

View file

@ -4,6 +4,10 @@
var html = '<div class="viewMenuBar ui-bar-b">';
if ($.browser.safari && $.browser.mobile && window.navigator.standalone) {
html += '<a data-rel="back" data-role="none" href="#" class="headerButton headerButtonLeft headerBackButton"><div class="fa fa-arrow-circle-o-left"></div></a>';
}
html += '<button type="button" data-role="none" title="Menu" class="headerButton dashboardMenuButton barsMenuButton headerButtonLeft">';
html += '<div class="barMenuInner fa fa-bars">';
html += '</div>';
@ -46,7 +50,7 @@
var url = user.imageUrl;
if (user.supportsImageParams) {
url += "&height=" + userButtonHeight;
url += "&height=" + (userButtonHeight * Math.max(devicePixelRatio || 1, 2));
}
html += '<img src="' + url + '" style="border-radius: 1000px; height:' + userButtonHeight + 'px;" />';
@ -68,9 +72,24 @@
$('.viewMenuBar').trigger('create');
$(document).trigger('headercreated');
bindMenuEvents();
}
$('.libraryMenuButton').createHoverTouch().on('hovertouch', showLibraryMenu);
$('.dashboardMenuButton').createHoverTouch().on('hovertouch', showDashboardMenu);
function bindMenuEvents() {
if ($.browser.mobile) {
$('.libraryMenuButton').on('mousedown', function () {
showLibraryMenu(false);
});
$('.dashboardMenuButton').on('mousedown', function () {
showDashboardMenu(false);
});
} else {
$('.libraryMenuButton').createHoverTouch().on('hovertouch', showLibraryMenu);
$('.dashboardMenuButton').createHoverTouch().on('hovertouch', showDashboardMenu);
}
}
function getItemHref(item, context) {
@ -102,13 +121,16 @@
var page = $.mobile.activePage;
var panel;
panel = getLibraryMenu();
updateLibraryNavLinks(page);
ConnectionManager.user().done(function (user) {
$(panel).panel('toggle').off('mouseleave.librarymenu').on('mouseleave.librarymenu', function () {
panel = getLibraryMenu(user);
updateLibraryNavLinks(page);
$(this).panel("close");
$(panel).panel('toggle').off('mouseleave.librarymenu').on('mouseleave.librarymenu', function () {
$(this).panel("close");
});
});
}
@ -229,13 +251,42 @@
html += '<div data-role="panel" id="libraryPanel" class="libraryPanel" data-position="left" data-display="overlay" data-position-fixed="true" data-theme="b">';
html += '<div class="sidebarLinks librarySidebarLinks" style="margin-top: 0;margin-left: -1em;margin-right: -1em;">';
html += '<div class="sidebarLinks librarySidebarLinks">';
//var userHref = user.localUser && user.localUser.Policy.EnableUserPreferenceAccess ?
// 'mypreferencesdisplay.html?userId=' + user.localUser.Id :
// (user.localUser ? 'index.html' : '#');
//var paddingLeft = user.imageUrl ? 'padding-left:.7em;' : '';
//html += '<a style="margin-top:0;' + paddingLeft + 'display:block;color:#fff;text-decoration:none;font-size:16px;font-weight:400!important;background: #000;" href="' + userHref + '">';
//var imgWidth = 44;
//if (user.imageUrl) {
// var url = user.imageUrl;
// if (user.supportsImageParams) {
// url += "&width=" + (imgWidth * Math.max(devicePixelRatio || 1, 2));
// }
// html += '<img style="max-width:' + imgWidth + 'px;vertical-align:middle;margin-right:.8em;border-radius: 50px;" src="' + url + '" />';
//} else {
// html += '<span class="fa fa-user sidebarLinkIcon"></span>';
//}
//html += user.name;
//html += '</a>';
var homeHref = ConnectionManager.currentApiClient() ? 'index.html' : 'selectserver.html';
html += '<a class="lnkMediaFolder sidebarLink homeViewMenu" href="' + homeHref + '">' + Globalize.translate('ButtonHome') + '</a>';
html += '<a class="lnkMediaFolder sidebarLink" style="margin-top:.5em;padding-left:1em;display:block;color:#fff;text-decoration:none;" href="' + homeHref + '">';
html += '<div class="libraryMenuDivider"></div>';
html += '<img style="max-width:36px;vertical-align:middle;margin-right:1em;" src="css/images/mblogoicon.png" />';
html += Globalize.translate('ButtonHome');
html += '</a>';
html += '<div class="libraryMenuDivider" style="margin-top:0;"></div>';
html += getViewsHtml();
html += '</div>';

View file

@ -69,9 +69,6 @@
ApiClient.reportPlaybackStopped(stopInfo);
}).on('positionchange.mediacontroller', function (e, state) {
});
}

View file

@ -931,6 +931,31 @@
var streamInfo = self.createStreamInfo('Video', item, mediaSource, startPosition);
// Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts
// This will start the transcoding process before actually feeding the video url into the player
if ($.browser.safari && !mediaSource.RunTimeTicks) {
Dashboard.showLoadingMsg();
ApiClient.ajax({
type: 'GET',
url: streamInfo.url.replace('master.m3u8', 'live.m3u8')
}).always(function () {
Dashboard.hideLoadingMsg();
}).done(function () {
self.playVideoInternal(item, mediaSource, startPosition, streamInfo);
});
} else {
self.playVideoInternal(item, mediaSource, startPosition, streamInfo);
}
};
self.playVideoInternal = function (item, mediaSource, startPosition, streamInfo) {
var videoUrl = streamInfo.url;
var contentType = streamInfo.contentType;
var startPositionInSeekParam = streamInfo.startPositionInSeekParam;
@ -941,6 +966,31 @@
return s.Type == 'Subtitle';
});
// Get Video Poster (Code from librarybrowser.js)
var screenWidth = Math.max(screen.height, screen.width);
var posterCode = '';
if (item.BackdropImageTags && item.BackdropImageTags.length) {
posterCode = ' poster="' + ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
index: 0,
maxWidth: screenWidth,
tag: item.BackdropImageTags[0]
}) + '"';
}
else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
posterCode = ' poster="' + ApiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: 'Backdrop',
index: 0,
maxWidth: screenWidth,
tag: item.ParentBackdropImageTags[0]
}) + '"';
}
//======================================================================================>
// Create video player
@ -950,11 +1000,12 @@
// Can't autoplay in these browsers so we need to use the full controls
if (requiresNativeControls) {
html += '<video class="itemVideo" id="itemVideo" preload="none" autoplay="autoplay" crossorigin="anonymous" controls="controls">';
} else {
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" controls="controls"' + posterCode + '>';
}
else {
// Chrome 35 won't play with preload none
html += '<video class="itemVideo" id="itemVideo" preload="metadata" crossorigin="anonymous" autoplay>';
html += '<video class="itemVideo" id="itemVideo" preload="metadata" crossorigin="anonymous" autoplay' + posterCode + '>';
}
html += '<source type="' + contentType + '" src="' + videoUrl + '" />';
@ -1142,7 +1193,10 @@
$('body').addClass('bodyWithPopupOpen');
return video[0];
self.currentMediaElement = video[0];
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item);
};
self.updatePlaylistUi = function () {

View file

@ -208,13 +208,22 @@
profile.ContainerProfiles = [];
var audioConditions = [];
if ($.browser.msie) {
audioConditions.push({
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '2'
});
}
var videoAudioAacConditions = [];
var videoAudioMp3Conditions = [];
var maxAudioChannels = $.browser.msie || $.browser.safari ?
'2' :
'6';
var channelCondition = {
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: maxAudioChannels
};
audioConditions.push(channelCondition);
videoAudioAacConditions.push(channelCondition);
videoAudioMp3Conditions.push(channelCondition);
profile.CodecProfiles = [];
profile.CodecProfiles.push({
@ -222,21 +231,36 @@
Conditions: audioConditions
});
if (videoAudioMp3Conditions.length) {
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'mp3',
Conditions: videoAudioMp3Conditions
});
}
videoAudioAacConditions.push({
Condition: 'NotEquals',
Property: 'AudioProfile',
Value: 'LC'
});
videoAudioAacConditions.push({
Condition: 'NotEquals',
Property: 'AudioProfile',
Value: 'HE-AAC'
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Conditions: audioConditions
Codec: 'aac',
Conditions: videoAudioAacConditions
});
profile.CodecProfiles.push({
Type: 'Video',
Codec: 'h264',
Conditions: [
{
Condition: 'Equals',
Property: 'IsCabac',
Value: 'true',
IsRequired: false
},
{
Condition: 'NotEquals',
Property: 'IsAnamorphic',
@ -355,36 +379,6 @@
return false;
};
self.getVideoTranscodingExtension = function (currentSrc) {
if (currentSrc) {
return self.getCurrentMediaExtension(currentSrc);
}
// safari
if (self.canPlayHls()) {
return '.m3u8';
}
// Chrome, Firefox or IE with plugin installed
// For some reason in chrome pausing mp4 is causing the video to fail.
// So for now it will have to prioritize webm
if (self.canPlayWebm()) {
if ($.browser.msie) {
return '.webm';
}
if ($.browser.chrome) {
return '.webm';
}
// Firefox suddenly having trouble with our webm
return '.webm';
}
return '.mp4';
};
self.changeStream = function (ticks, params) {
var element = self.currentMediaElement;
@ -871,10 +865,7 @@
if (item.MediaType === "Video") {
self.currentMediaElement = self.playVideo(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item);
self.playVideo(item, self.currentMediaSource, startPosition);
} else if (item.MediaType === "Audio") {

View file

@ -400,7 +400,7 @@
// The button is created dynamically
$(page).on('click', '.btnNewCollection', function () {
showCollectionPanel(page, []);
showCollectionPanel([]);
});
});

View file

@ -4,7 +4,7 @@
var screenWidth = $(window).width();
return screenWidth >= 1920 ? 9 : 8;
return screenWidth >= 1920 ? 9 : (screenWidth >= 1200 ? 12 : (screenWidth >= 1000 ? 10 : 8));
}
function loadLatest(page, parentId) {

View file

@ -5,6 +5,7 @@
var externalPlayers = JSON.parse(store.getItem('externalplayers') || '[]');
$('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()).selectmenu("refresh");
$('#selectMaxChromecastBitrate', page).val(AppSettings.maxChromecastBitrate()).selectmenu("refresh");
$('.chkExternalPlayer', page).each(function () {
@ -66,6 +67,7 @@
store.setItem('externalplayers', JSON.stringify(externalPlayers));
AppSettings.maxStreamingBitrate($('#selectMaxBitrate', page).val());
AppSettings.maxChromecastBitrate($('#selectMaxChromecastBitrate', page).val());
var userId = getParameterByName('userId') || Dashboard.getCurrentUserId();
@ -122,6 +124,14 @@
}
return parseInt(store.getItem('preferredVideoBitrate') || '') || 1500000;
},
maxChromecastBitrate: function (val) {
if (val != null) {
store.setItem('chromecastBitrate', val);
}
return parseInt(store.getItem('chromecastBitrate') || '') || 3000000;
}
};

View file

@ -40,6 +40,8 @@
updateFilterControls(page);
var defaultAction = query.MediaTypes == 'Photo' ? 'photoslideshow' : null;
// Poster
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
@ -47,7 +49,8 @@
context: getParameterByName('context') || 'photos',
showTitle: false,
centerText: true,
lazy: true
lazy: true,
defaultAction: defaultAction
});
var elem = $('#items', page).html(html).lazyChildren();
@ -134,6 +137,50 @@
query.ParentId = getParameterByName('parentId') || LibraryMenu.getTopParentId();
}
function startSlideshow(page, index) {
index += (query.StartIndex || 0);
var userId = Dashboard.getCurrentUserId();
var localQuery = $.extend({}, query);
localQuery.StartIndex = 0;
localQuery.Limit = null;
localQuery.MediaTypes = "Photo";
localQuery.Recursive = true;
localQuery.Filters = "IsNotFolder";
ApiClient.getItems(userId, localQuery).done(function (result) {
showSlideshow(page, result.Items, index);
});
}
function showSlideshow(page, items, index) {
var slideshowItems = items.map(function (item) {
var imgUrl = ApiClient.getScaledImageUrl(item.Id, {
tag: item.ImageTags.Primary,
type: 'Primary'
});
return {
title: item.Name,
href: imgUrl
};
});
index = Math.max(index || 0, 0);
$.swipebox(slideshowItems, {
initialIndexOnArray: index,
hideBarsDelay: 30000
});
}
$(document).on('pageinit', "#photosPage", function () {
var page = this;
@ -197,6 +244,10 @@
reloadItems(page);
});
$('.itemsContainer', page).on('photoslideshow', function (e, index) {
startSlideshow(page, index);
});
}).on('pagebeforeshow', "#photosPage", function () {
var page = this;

View file

@ -577,14 +577,16 @@ var Dashboard = {
html += '<h3>';
var imgWidth = 48;
if (user.imageUrl) {
var url = user.imageUrl;
if (user.supportsImageParams) {
url += "&width=" + 28;
url += "&width=" + (imgWidth * Math.max(devicePixelRatio || 1, 2));
}
html += '<img style="max-width:28px;vertical-align:middle;margin-right:5px;" src="' + url + '" />';
html += '<img style="max-width:' + imgWidth + 'px;vertical-align:middle;margin-right:.5em;border-radius: 50px;" src="' + url + '" />';
}
html += user.name;
html += '</h3>';
@ -1385,6 +1387,27 @@ var Dashboard = {
if (window.ApiClient) {
Dashboard.importCss(ApiClient.getUrl('Branding/Css'));
ApiClient.getDefaultImageQuality = function (imageType) {
var quality = 90;
var isBackdrop = imageType.toLowerCase() == 'backdrop';
if (isBackdrop) {
quality -= 10;
}
if ($.browser.safari && $.browser.mobile) {
quality -= 10;
if (isBackdrop) {
quality -= 10;
}
}
return quality;
};
}
})();