diff --git a/ApiClient.js b/ApiClient.js index 97c26ec78a..47719df8d2 100644 --- a/ApiClient.js +++ b/ApiClient.js @@ -2191,20 +2191,6 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }); }; - /** - * Gets a list of all available conrete BaseItem types from the server - */ - self.getItemTypes = function (options) { - - var url = self.getUrl("Library/ItemTypes", options); - - return self.ajax({ - type: "GET", - url: url, - dataType: "json" - }); - }; - /** * Constructs a url for a user image * @param {String} userId @@ -3805,7 +3791,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi * @param {String} userId * @param {String} itemId */ - self.reportPlaybackStart = function (userId, itemId, canSeek, queueableMediaTypes) { + self.reportPlaybackStart = function (userId, itemId, mediaVersionId, canSeek, queueableMediaTypes) { if (!userId) { throw new Error("null userId"); @@ -3823,6 +3809,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var deferred = $.Deferred(); var msg = [itemId, canSeek, queueableMediaTypes]; + + if (mediaVersionId) { + msg.push(mediaVersionId); + } self.sendWebSocketMessage("PlaybackStart", msg.join('|')); @@ -3830,10 +3820,16 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi return deferred.promise(); } - var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, { + var params = { CanSeek: canSeek, QueueableMediaTypes: queueableMediaTypes - }); + }; + + if (mediaVersionId) { + params.mediaVersionId = mediaVersionId; + } + + var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, params); return self.ajax({ type: "POST", @@ -3846,7 +3842,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi * @param {String} userId * @param {String} itemId */ - self.reportPlaybackProgress = function (userId, itemId, positionTicks, isPaused, isMuted) { + self.reportPlaybackProgress = function (userId, itemId, mediaVersionId, positionTicks, isPaused, isMuted) { if (!userId) { throw new Error("null userId"); @@ -3860,7 +3856,12 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var deferred = $.Deferred(); - var msgData = itemId + "|" + (positionTicks == null ? "" : positionTicks) + "|" + (isPaused == null ? "" : isPaused) + "|" + (isMuted == null ? "" : isMuted); + var msgData = itemId; + + msgData += "|" + (positionTicks == null ? "" : positionTicks); + msgData += "|" + (isPaused == null ? "" : isPaused); + msgData += "|" + (isMuted == null ? "" : isMuted); + msgData += "|" + (mediaVersionId == null ? "" : mediaVersionId); self.sendWebSocketMessage("PlaybackProgress", msgData); @@ -3877,6 +3878,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi params.positionTicks = positionTicks; } + if (mediaVersionId) { + params.mediaVersionId = mediaVersionId; + } + var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId + "/Progress", params); return self.ajax({ @@ -3890,7 +3895,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi * @param {String} userId * @param {String} itemId */ - self.reportPlaybackStopped = function (userId, itemId, positionTicks) { + self.reportPlaybackStopped = function (userId, itemId, mediaVersionId, positionTicks) { if (!userId) { throw new Error("null userId"); @@ -3904,20 +3909,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var deferred = $.Deferred(); - self.sendWebSocketMessage("PlaybackStopped", itemId + "|" + (positionTicks == null ? "" : positionTicks)); + var msg = itemId; + msg += "|" + (positionTicks == null ? "" : positionTicks); + msg += "|" + (mediaVersionId == null ? "" : mediaVersionId); + + self.sendWebSocketMessage("PlaybackStopped", msg); deferred.resolveWith(null, []); return deferred.promise(); } - var params = { - - }; + var params = {}; if (positionTicks) { params.positionTicks = positionTicks; } + if (mediaVersionId) { + params.mediaVersionId = mediaVersionId; + } + var url = self.getUrl("Users/" + userId + "/PlayingItems/" + itemId, params); return self.ajax({ diff --git a/dashboard-ui/css/librarybrowser.css b/dashboard-ui/css/librarybrowser.css index e210b0f657..0d148ea157 100644 --- a/dashboard-ui/css/librarybrowser.css +++ b/dashboard-ui/css/librarybrowser.css @@ -866,7 +866,6 @@ a.itemTag:hover { } .mediaInfoStreamType { - font-size: 16px; display: block; color: #fff; } @@ -874,14 +873,12 @@ a.itemTag:hover { .mediaInfoAttribute { color: #fff; display: inline-block; - width: 110px; } .mediaInfoLabel { color: #aaa; margin-right: 1em; display: inline-block; - width: 90px; } .posterRibbon { diff --git a/dashboard-ui/css/mediaplayer-video.css b/dashboard-ui/css/mediaplayer-video.css index 56dff52da7..51156157a1 100644 --- a/dashboard-ui/css/mediaplayer-video.css +++ b/dashboard-ui/css/mediaplayer-video.css @@ -33,7 +33,7 @@ #videoControls { z-index: 99999; - padding: 0 20px 10px; + padding: 0 20px 5px; height: 80px; position: absolute; top: auto; diff --git a/dashboard-ui/scripts/itembynamedetailpage.js b/dashboard-ui/scripts/itembynamedetailpage.js index ba20a2787a..b1d7b4901a 100644 --- a/dashboard-ui/scripts/itembynamedetailpage.js +++ b/dashboard-ui/scripts/itembynamedetailpage.js @@ -398,7 +398,8 @@ Recursive: true, Fields: "AudioInfo,SeriesInfo,ParentId,PrimaryImageAspectRatio", Limit: LibraryBrowser.getDefaultPageSize(), - StartIndex: 0 + StartIndex: 0, + CollapseBoxSetItems: false }; query = $.extend(query, options || {}); diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index 6bf282d884..2fa7883a9a 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -214,11 +214,7 @@ renderMediaVersions(page, item); } - var primaryVersion = (item.MediaVersions || []).filter(function (v) { - return v.IsPrimaryVersion; - - })[0]; - var chapters = primaryVersion ? (primaryVersion.Chapters || []) : []; + var chapters = item.Chapters || []; if (!chapters.length) { $('#scenesCollapsible', page).hide(); @@ -350,7 +346,7 @@ tabsHtml += ''; } - if (item.MediaType == "Audio" || item.MediaType == "Video") { + if (item.MediaVersions && item.MediaVersions.length) { tabsHtml += ''; tabsHtml += ''; } @@ -1023,11 +1019,7 @@ function renderScenes(page, item, user, limit) { var html = ''; - var primaryVersion = (item.MediaVersions || []).filter(function (v) { - return v.IsPrimaryVersion; - - })[0]; - var chapters = primaryVersion ? (primaryVersion.Chapters || []) : []; + var chapters = item.Chapters || []; for (var i = 0, length = chapters.length; i < length; i++) { diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 722a954baf..2ee0fbd93d 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -6,7 +6,7 @@ getDefaultPageSize: function () { - var saved = localStorage.getItem('pagesize'); + var saved = localStorage.getItem('pagesize_'); if (saved) { return parseInt(saved); diff --git a/dashboard-ui/scripts/libraryreport.js b/dashboard-ui/scripts/libraryreport.js index bc894428a6..0cc02dc1a8 100644 --- a/dashboard-ui/scripts/libraryreport.js +++ b/dashboard-ui/scripts/libraryreport.js @@ -207,19 +207,29 @@ function getItemCellsHtml(item, headercells) { + var primaryVersion = (item.MediaVersions || []).filter(function (v) { + return v.IsPrimaryVersion; + })[0] || {}; + + var mediaStreams = primaryVersion.MediaStreams || []; + + var videoStream = mediaStreams.filter(function (s) { + + return s.Type == 'Video'; + + })[0]; + + var audioStream = mediaStreams.filter(function (s) { + + return s.Type == 'Audio'; + + })[0]; + return headercells.map(function (cell) { var html = ''; html += ''; - var stream; - - var primaryVersion = (item.MediaVersions || []).filter(function(v) { - return v.IsPrimaryVersion; - })[0] || {}; - - var mediaStreams = primaryVersion.MediaStreams || []; - switch (cell.type || cell.name) { case 'Album Artist': @@ -264,52 +274,30 @@ } case 'Audio': { - stream = mediaStreams.filter(function (s) { + if (audioStream) { - return s.Type == 'Audio'; - - })[0]; - - if (stream) { - - var name = (stream.Codec || '').toUpperCase(); - html += name == 'DCA' ? (stream.Profile || '').toUpperCase() : name; + var name = (audioStream.Codec || '').toUpperCase(); + html += name == 'DCA' ? (audioStream.Profile || '').toUpperCase() : name; } break; } case 'Video': { - stream = mediaStreams.filter(function (s) { - - return s.Type == 'Video'; - - })[0]; - - if (stream) { - html += (stream.Codec || '').toUpperCase(); + if (videoStream) { + html += (videoStream.Codec || '').toUpperCase(); } break; } case 'Resolution': { - stream = mediaStreams.filter(function (s) { - - return s.Type == 'Video'; - - })[0]; - - if (stream && stream.Width) { - html += stream.Width + "*" + (stream.Height || "-"); + if (videoStream && videoStream.Width) { + html += videoStream.Width + "*" + (videoStream.Height || "-"); } break; } case 'Embedded Image': { - if (mediaStreams.filter(function (s) { - - return s.Type == 'Video'; - - }).length) { + if (videoStream) { html += '
'; } break; diff --git a/dashboard-ui/scripts/mediaplayer-video.js b/dashboard-ui/scripts/mediaplayer-video.js index 0a7b6a5095..3a74bce72f 100644 --- a/dashboard-ui/scripts/mediaplayer-video.js +++ b/dashboard-ui/scripts/mediaplayer-video.js @@ -319,7 +319,7 @@ var currentTicks = self.getCurrentTicks(); - var chapters = currentMediaVersion.Chapters || []; + var chapters = currentItem.Chapters || []; for (var i = 0, length = chapters.length; i < length; i++) { @@ -344,7 +344,7 @@ if (chapter.ImageTag) { - imgUrl = ApiClient.getImageUrl(currentMediaVersion.ItemId, { + imgUrl = ApiClient.getImageUrl(currentItem.Id, { maxwidth: 200, tag: chapter.ImageTag, type: "Chapter", @@ -706,7 +706,8 @@ SubtitleStreamIndex: getInitialSubtitleStreamIndex(mediaStreams, user), AudioStreamIndex: getInitialAudioStreamIndex(mediaStreams, user), deviceId: ApiClient.deviceId(), - Static: false + Static: false, + mediaVersionId: mediaVersion.Id }; var mp4Quality = getVideoQualityOptions(mediaStreams).filter(function (opt) { @@ -733,7 +734,7 @@ var seekParam = isStatic && startPosition ? '#t=' + (startPosition / 10000000) : ''; - var mp4VideoUrl = ApiClient.getUrl('Videos/' + mediaVersion.ItemId + '/stream.mp4', $.extend({}, baseParams, { + var mp4VideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.mp4', $.extend({}, baseParams, { profile: 'baseline', level: 3, Static: isStatic, @@ -745,7 +746,7 @@ })) + seekParam; - var webmVideoUrl = ApiClient.getUrl('Videos/' + mediaVersion.ItemId + '/stream.webm', $.extend({}, baseParams, { + var webmVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.webm', $.extend({}, baseParams, { VideoCodec: 'vpx', AudioCodec: 'Vorbis', @@ -755,7 +756,7 @@ })) + seekParam; - var hlsVideoUrl = ApiClient.getUrl('Videos/' + mediaVersion.ItemId + '/stream.m3u8', $.extend({}, baseParams, { + var hlsVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.m3u8', $.extend({}, baseParams, { profile: 'baseline', level: 3, timeStampOffsetMs: 0, @@ -835,7 +836,7 @@ $('#video-subtitleButton', videoControls).hide(); } - if (mediaVersion.Chapters && mediaVersion.Chapters.length) { + if (item.Chapters && item.Chapters.length) { $('#video-chaptersButton', videoControls).show(); } else { $('#video-chaptersButton', videoControls).hide(); @@ -882,9 +883,9 @@ videoElement.off("playing.once"); - ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), mediaVersion.ItemId, true, item.MediaType); + ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), item.Id, mediaVersion.Id, true, item.MediaType); - self.startProgressInterval(mediaVersion.ItemId); + self.startProgressInterval(item.Id, mediaVersion.Id); }).on("pause", function (e) { diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index 4aaf83d412..b67efc3c1d 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -54,7 +54,7 @@ var position = Math.floor(10000000 * endTime) + self.startTimeTicksOffset; - ApiClient.reportPlaybackStopped(Dashboard.getCurrentUserId(), currentMediaVersion.ItemId, position); + ApiClient.reportPlaybackStopped(Dashboard.getCurrentUserId(), currentItem.Id, currentMediaVersion.Id, position); if (currentItem.MediaType == "Video") { ApiClient.stopActiveEncodings(); @@ -72,7 +72,7 @@ self.nextTrack(); }; - self.startProgressInterval = function (itemId) { + self.startProgressInterval = function (itemId, mediaVersionId) { clearProgressInterval(); @@ -81,7 +81,7 @@ currentProgressInterval = setInterval(function () { if (currentMediaElement) { - sendProgressUpdate(itemId); + sendProgressUpdate(itemId, mediaVersionId); } }, intervalTime); @@ -156,8 +156,8 @@ $(this).off('play.onceafterseek').on('ended.playbackstopped', self.onPlaybackStopped).on('ended.playnext', self.playNextAfterEnded); - self.startProgressInterval(currentMediaVersion.ItemId); - sendProgressUpdate(currentMediaVersion.ItemId); + self.startProgressInterval(currentItem.Id, currentMediaVersion.Id); + sendProgressUpdate(currentItem.Id, currentMediaVersion.Id); }); @@ -957,7 +957,7 @@ var position = Math.floor(10000000 * endTime) + self.startTimeTicksOffset; - ApiClient.reportPlaybackStopped(Dashboard.getCurrentUserId(), currentMediaVersion.ItemId, position); + ApiClient.reportPlaybackStopped(Dashboard.getCurrentUserId(), currentItem.Id, currentMediaVersion.Id, position); } }); @@ -984,9 +984,9 @@ return url + '&' + param + "=" + value; }; - function sendProgressUpdate(itemId) { + function sendProgressUpdate(itemId, mediaVersionId) { - ApiClient.reportPlaybackProgress(Dashboard.getCurrentUserId(), itemId, self.getCurrentTicks(), currentMediaElement.paused, currentMediaElement.volume == 0); + ApiClient.reportPlaybackProgress(Dashboard.getCurrentUserId(), itemId, mediaVersionId, self.getCurrentTicks(), currentMediaElement.paused, currentMediaElement.volume == 0); }; function clearProgressInterval() { @@ -1029,18 +1029,19 @@ var baseParams = { audioChannels: 2, audioBitrate: 128000, - StartTimeTicks: startPositionTicks + StartTimeTicks: startPositionTicks, + mediaVersionId: mediaVersion.Id }; - var mp3Url = ApiClient.getUrl('Audio/' + mediaVersion.ItemId + '/stream.mp3', $.extend({}, baseParams, { + var mp3Url = ApiClient.getUrl('Audio/' + item.Id + '/stream.mp3', $.extend({}, baseParams, { audioCodec: 'mp3' })); - var aacUrl = ApiClient.getUrl('Audio/' + mediaVersion.ItemId + '/stream.aac', $.extend({}, baseParams, { + var aacUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.aac', $.extend({}, baseParams, { audioCodec: 'aac' })); - var webmUrl = ApiClient.getUrl('Audio/' + mediaVersion.ItemId + '/stream.webm', $.extend({}, baseParams, { + var webmUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.webm', $.extend({}, baseParams, { audioCodec: 'Vorbis' })); @@ -1131,9 +1132,9 @@ audioElement.off("play.once"); - ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), mediaVersion.ItemId, true, item.MediaType); + ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), item.Id, mediaVersion.Id, true, item.MediaType); - self.startProgressInterval(mediaVersion.ItemId); + self.startProgressInterval(item.Id, mediaVersion.Id); }).on("pause", function () { @@ -1200,7 +1201,7 @@ return (trunc(titles[0], 30) + "
" + trunc(titles[1], 30)).replace("---", " "); }; - var getItemFields = "MediaVersions"; + var getItemFields = "MediaVersions,Chapters"; } window.MediaPlayer = new mediaPlayer(); diff --git a/packages.config b/packages.config index 0bdea523e3..bbc2c0f068 100644 --- a/packages.config +++ b/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file