diff --git a/ApiClient.js b/ApiClient.js
index 97c26ec78a..765cae6128 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, mediaSourceId, 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 (mediaSourceId) {
+ msg.push(mediaSourceId);
+ }
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 (mediaSourceId) {
+ params.mediaSourceId = mediaSourceId;
+ }
+
+ 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, mediaSourceId, 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 += "|" + (mediaSourceId == null ? "" : mediaSourceId);
self.sendWebSocketMessage("PlaybackProgress", msgData);
@@ -3877,6 +3878,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
params.positionTicks = positionTicks;
}
+ if (mediaSourceId) {
+ params.mediaSourceId = mediaSourceId;
+ }
+
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, mediaSourceId, 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 += "|" + (mediaSourceId == null ? "" : mediaSourceId);
+
+ self.sendWebSocketMessage("PlaybackStopped", msg);
deferred.resolveWith(null, []);
return deferred.promise();
}
- var params = {
-
- };
+ var params = {};
if (positionTicks) {
params.positionTicks = positionTicks;
}
+ if (mediaSourceId) {
+ params.mediaSourceId = mediaSourceId;
+ }
+
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..ba6615ba09 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 {
@@ -929,7 +926,7 @@ a.itemTag:hover {
background-color: transparent !important;
}
-.mediaVersionIndicator {
+.mediaSourceIndicator {
display: block;
position: absolute;
top: 5px;
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/css/mediaplayer.css b/dashboard-ui/css/mediaplayer.css
index 3ed4d78b89..5070af2039 100644
--- a/dashboard-ui/css/mediaplayer.css
+++ b/dashboard-ui/css/mediaplayer.css
@@ -1,13 +1,13 @@
/* Now playing bar */
.nowPlayingBar {
- padding: 6px 0 24px 0;
+ padding: 6px 0 20px 0;
border-top: 2px solid green;
}
.nowPlayingBar .barBackground {
border-top: 2px solid green;
position: absolute;
- margin: -8px -0.5em -26px !important;
+ margin: -8px -0.5em -22px !important;
width: 100%;
height: 100%;
}
@@ -251,4 +251,4 @@ input[type="range"]::-ms-fill-upper {
.positionSliderContainer {
width: 300px;
}
-}
\ No newline at end of file
+}
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..ddd8f02ef2 100644
--- a/dashboard-ui/scripts/itemdetailpage.js
+++ b/dashboard-ui/scripts/itemdetailpage.js
@@ -73,7 +73,7 @@
$('#btnPlayExternalTrailer', page).attr('href', '#');
}
- if (user.Configuration.IsAdministrator && item.MediaVersions && item.MediaVersions.length > 1) {
+ if (user.Configuration.IsAdministrator && item.MediaSources && item.MediaSources.length > 1) {
$('.splitVersionContainer', page).show();
} else {
$('.splitVersionContainer', page).hide();
@@ -210,15 +210,11 @@
$('#childrenCollapsible', page).addClass('hide');
}
- if (item.MediaVersions && item.MediaVersions.length) {
- renderMediaVersions(page, item);
+ if (item.MediaSources && item.MediaSources.length) {
+ renderMediaSources(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();
@@ -247,13 +243,6 @@
renderAdditionalParts(page, item, user);
}
- if (!item.AlternateVersionCount) {
- $('#alternateVersionsCollapsible', page).addClass('hide');
- } else {
- $('#alternateVersionsCollapsible', page).removeClass('hide');
- renderAlternateVersions(page, item, user);
- }
-
$('#themeSongsCollapsible', page).hide();
$('#themeVideosCollapsible', page).hide();
@@ -350,7 +339,7 @@
tabsHtml += '';
}
- if (item.MediaType == "Audio" || item.MediaType == "Video") {
+ if (item.MediaSources && item.MediaSources.length) {
tabsHtml += '';
tabsHtml += '';
}
@@ -985,49 +974,10 @@
});
}
- function renderAlternateVersions(page, item, user) {
-
- var url = ApiClient.getUrl("Videos/" + item.Id + "/Versions", {
- userId: user.Id
- });
-
- $.getJSON(url).done(function (items) {
-
- if (items.length) {
-
- $('#alternateVersionsCollapsible', page).show();
-
- var html = LibraryBrowser.getPosterViewHtml({
- items: items.map(function (i) {
- var extended = $.extend({}, item, i);
- extended.Id = item.Id;
- return extended;
- }),
- shape: "portrait",
- context: 'movies',
- useAverageAspectRatio: true,
- showTitle: true,
- centerText: true,
- linkItem: false,
- showProgress: false,
- showUnplayedIndicator: false
- });
-
- $('#alternateVersionsContent', page).html(html).trigger('create');
- } else {
- $('#alternateVersionsCollapsible', page).hide();
- }
- });
- }
-
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++) {
@@ -1077,26 +1027,26 @@
$('#scenesContent', page).html(html).trigger('create');
}
- function renderMediaVersions(page, item) {
+ function renderMediaSources(page, item) {
- var html = item.MediaVersions.map(function (v) {
+ var html = item.MediaSources.map(function (v) {
- return getMediaVersionHtml(item, v);
+ return getMediaSourceHtml(item, v);
}).join('
');
- if (item.MediaVersions.length > 1) {
+ if (item.MediaSources.length > 1) {
html = '
' + html;
}
$('#mediaInfoContent', page).html(html).trigger('create');
}
- function getMediaVersionHtml(item, version) {
+ function getMediaSourceHtml(item, version) {
var html = '';
- if (version.Name && item.MediaVersions.length > 1) {
+ if (version.Name && item.MediaSources.length > 1) {
html += '' + version.Name + '
';
}
@@ -1342,7 +1292,7 @@
var id = getParameterByName('id');
- Dashboard.confirm("Are you sure you wish to split the versions apart into separate items?", "Split Versions Apart", function (confirmResult) {
+ Dashboard.confirm("Are you sure you wish to split the media sources into separate items?", "Split Media Apart", function (confirmResult) {
if (confirmResult) {
@@ -1350,7 +1300,7 @@
$.ajax({
type: "DELETE",
- url: ApiClient.getUrl("Videos/" + id + "/AlternateVersions")
+ url: ApiClient.getUrl("Videos/" + id + "/AlternateSources")
}).done(function () {
diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js
index 722a954baf..407fbc525e 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);
@@ -665,11 +665,11 @@
cssClass += ' ' + options.shape + 'PosterItem';
- var mediaVersionCount = item.MediaVersionCount || 1;
+ var mediaSourceCount = item.MediaSourceCount || 1;
var href = options.linkItem === false ? '#' : LibraryBrowser.getHref(item, options.context);
- html += '';
+ html += '';
var style = "";
@@ -700,8 +700,8 @@
html += LibraryBrowser.getPlayedIndicatorHtml(item);
}
- if (mediaVersionCount > 1) {
- html += '' + mediaVersionCount + '
';
+ if (mediaSourceCount > 1) {
+ html += '' + mediaSourceCount + '
';
}
if (item.IsUnidentified) {
html += '';
diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js
index 14d49af957..23488ac7a2 100644
--- a/dashboard-ui/scripts/librarylist.js
+++ b/dashboard-ui/scripts/librarylist.js
@@ -175,7 +175,7 @@
function splitVersions(id, page) {
- Dashboard.confirm("Are you sure you wish to split the versions apart into separate items?", "Split Versions Apart", function (confirmResult) {
+ Dashboard.confirm("Are you sure you wish to split the media sources into separate items?", "Split Media Apart", function (confirmResult) {
if (confirmResult) {
@@ -183,7 +183,7 @@
$.ajax({
type: "DELETE",
- url: ApiClient.getUrl("Videos/" + id + "/AlternateVersions")
+ url: ApiClient.getUrl("Videos/" + id + "/AlternateSources")
}).done(function () {
@@ -208,8 +208,8 @@
items.push({ type: 'link', text: 'Images', url: 'edititemimages.html?id=' + id });
- var versionCount = parseInt(elem.getAttribute('data-mediaversioncount') || '0');
-
+ var versionCount = parseInt(elem.getAttribute('data-mediasourcecount') || '0');
+
if (versionCount > 1) {
items.push({ type: 'divider' });
diff --git a/dashboard-ui/scripts/libraryreport.js b/dashboard-ui/scripts/libraryreport.js
index bc894428a6..a66f43ff34 100644
--- a/dashboard-ui/scripts/libraryreport.js
+++ b/dashboard-ui/scripts/libraryreport.js
@@ -8,7 +8,7 @@
SortBy: defaultSortBy,
SortOrder: "Ascending",
Recursive: true,
- Fields: "MediaVersions,DateCreated,Settings,Studios",
+ Fields: "MediaSources,DateCreated,Settings,Studios",
StartIndex: 0,
IncludeItemTypes: "Movie",
IsMissing: false,
@@ -207,19 +207,27 @@
function getItemCellsHtml(item, headercells) {
+ var primaryVersion = (item.MediaSources || [])[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 +272,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..c9a36eb536 100644
--- a/dashboard-ui/scripts/mediaplayer-video.js
+++ b/dashboard-ui/scripts/mediaplayer-video.js
@@ -1,5 +1,5 @@
(function () {
- videoPlayer = function (mediaPlayer, item, mediaVersion, startPosition, user) {
+ videoPlayer = function (mediaPlayer, item, mediaSource, startPosition, user) {
if (mediaPlayer == null) {
throw new Error("mediaPlayer cannot be null");
}
@@ -15,7 +15,7 @@
var self = mediaPlayer;
var currentItem;
- var currentMediaVersion;
+ var currentMediaSource;
var timeout;
var video;
var initialVolume;
@@ -24,7 +24,7 @@
var remoteFullscreen = false;
self.initVideoPlayer = function () {
- video = playVideo(item, mediaVersion, startPosition, user);
+ video = playVideo(item, mediaSource, startPosition, user);
return video;
};
@@ -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",
@@ -374,7 +374,7 @@
function getAudioTracksHtml() {
- var streams = currentMediaVersion.MediaStreams.filter(function (currentStream) {
+ var streams = currentMediaSource.MediaStreams.filter(function (currentStream) {
return currentStream.Type == "Audio";
});
@@ -444,7 +444,7 @@
function getSubtitleTracksHtml() {
- var streams = currentMediaVersion.MediaStreams.filter(function (currentStream) {
+ var streams = currentMediaSource.MediaStreams.filter(function (currentStream) {
return currentStream.Type == "Subtitle";
});
@@ -528,7 +528,7 @@
var currentAudioStreamIndex = getParameterByName('AudioStreamIndex', video.currentSrc);
- var options = getVideoQualityOptions(currentMediaVersion.MediaStreams, currentAudioStreamIndex, transcodingExtension);
+ var options = getVideoQualityOptions(currentMediaSource.MediaStreams, currentAudioStreamIndex, transcodingExtension);
if (isStatic) {
options[0].name = "Direct";
@@ -696,9 +696,9 @@
return options;
};
- function playVideo(item, mediaVersion, startPosition, user) {
+ function playVideo(item, mediaSource, startPosition, user) {
- var mediaStreams = mediaVersion.MediaStreams || [];
+ var mediaStreams = mediaSource.MediaStreams || [];
var baseParams = {
audioChannels: 2,
@@ -706,23 +706,24 @@
SubtitleStreamIndex: getInitialSubtitleStreamIndex(mediaStreams, user),
AudioStreamIndex: getInitialAudioStreamIndex(mediaStreams, user),
deviceId: ApiClient.deviceId(),
- Static: false
+ Static: false,
+ mediaSourceId: mediaSource.Id
};
var mp4Quality = getVideoQualityOptions(mediaStreams).filter(function (opt) {
return opt.selected;
})[0];
- mp4Quality = $.extend(mp4Quality, self.getFinalVideoParams(mediaVersion, mp4Quality.maxWidth, mp4Quality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.mp4'));
+ mp4Quality = $.extend(mp4Quality, self.getFinalVideoParams(mediaSource, mp4Quality.maxWidth, mp4Quality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.mp4'));
var webmQuality = getVideoQualityOptions(mediaStreams).filter(function (opt) {
return opt.selected;
})[0];
- webmQuality = $.extend(webmQuality, self.getFinalVideoParams(mediaVersion, webmQuality.maxWidth, webmQuality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.webm'));
+ webmQuality = $.extend(webmQuality, self.getFinalVideoParams(mediaSource, webmQuality.maxWidth, webmQuality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.webm'));
var m3U8Quality = getVideoQualityOptions(mediaStreams).filter(function (opt) {
return opt.selected;
})[0];
- m3U8Quality = $.extend(m3U8Quality, self.getFinalVideoParams(mediaVersion, mp4Quality.maxWidth, mp4Quality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.mp4'));
+ m3U8Quality = $.extend(m3U8Quality, self.getFinalVideoParams(mediaSource, mp4Quality.maxWidth, mp4Quality.bitrate, baseParams.AudioStreamIndex, baseParams.SubtitleStreamIndex, '.mp4'));
// Webm must be ahead of mp4 due to the issue of mp4 playing too fast in chrome
var prioritizeWebmOverH264 = $.browser.chrome || $.browser.msie;
@@ -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, mediaSource.Id, true, item.MediaType);
- self.startProgressInterval(mediaVersion.ItemId);
+ self.startProgressInterval(item.Id, mediaSource.Id);
}).on("pause", function (e) {
@@ -1000,7 +1001,7 @@
fullscreenExited = false;
currentItem = item;
- currentMediaVersion = mediaVersion;
+ currentMediaSource = mediaSource;
return videoElement[0];
};
diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js
index 4aaf83d412..26be435159 100644
--- a/dashboard-ui/scripts/mediaplayer.js
+++ b/dashboard-ui/scripts/mediaplayer.js
@@ -8,7 +8,7 @@
var currentMediaElement;
var currentProgressInterval;
var currentItem;
- var currentMediaVersion;
+ var currentMediaSource;
var curentDurationTicks;
var canClientSeek;
var currentPlaylistIndex = 0;
@@ -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, currentMediaSource.Id, position);
if (currentItem.MediaType == "Video") {
ApiClient.stopActiveEncodings();
@@ -72,7 +72,7 @@
self.nextTrack();
};
- self.startProgressInterval = function (itemId) {
+ self.startProgressInterval = function (itemId, mediaSourceId) {
clearProgressInterval();
@@ -81,7 +81,7 @@
currentProgressInterval = setInterval(function () {
if (currentMediaElement) {
- sendProgressUpdate(itemId);
+ sendProgressUpdate(itemId, mediaSourceId);
}
}, intervalTime);
@@ -136,7 +136,7 @@
var transcodingExtension = self.getTranscodingExtension();
- var finalParams = self.getFinalVideoParams(currentMediaVersion, maxWidth, bitrate, audioStreamIndex, subtitleStreamIndex, transcodingExtension);
+ var finalParams = self.getFinalVideoParams(currentMediaSource, maxWidth, bitrate, audioStreamIndex, subtitleStreamIndex, transcodingExtension);
currentSrc = replaceQueryString(currentSrc, 'MaxWidth', finalParams.maxWidth);
currentSrc = replaceQueryString(currentSrc, 'VideoBitrate', finalParams.videoBitrate);
currentSrc = replaceQueryString(currentSrc, 'AudioBitrate', finalParams.audioBitrate);
@@ -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, currentMediaSource.Id);
+ sendProgressUpdate(currentItem.Id, currentMediaSource.Id);
});
@@ -194,9 +194,9 @@
self.currentTimeElement.html(timeText);
};
- self.canPlayVideoDirect = function (mediaVersion, videoStream, audioStream, subtitleStream, maxWidth, bitrate) {
+ self.canPlayVideoDirect = function (mediaSource, videoStream, audioStream, subtitleStream, maxWidth, bitrate) {
- if (mediaVersion.VideoType != "VideoFile" || mediaVersion.LocationType != "FileSystem") {
+ if (mediaSource.VideoType != "VideoFile" || mediaSource.LocationType != "FileSystem") {
console.log('Transcoding because the content is not a video file');
return false;
}
@@ -229,7 +229,7 @@
return false;
}
- var extension = mediaVersion.Path.substring(mediaVersion.Path.lastIndexOf('.') + 1).toLowerCase();
+ var extension = mediaSource.Path.substring(mediaSource.Path.lastIndexOf('.') + 1).toLowerCase();
if (extension == 'm4v') {
return $.browser.chrome;
@@ -238,9 +238,9 @@
return extension.toLowerCase() == 'mp4';
};
- self.getFinalVideoParams = function (mediaVersion, maxWidth, bitrate, audioStreamIndex, subtitleStreamIndex, transcodingExtension) {
+ self.getFinalVideoParams = function (mediaSource, maxWidth, bitrate, audioStreamIndex, subtitleStreamIndex, transcodingExtension) {
- var mediaStreams = mediaVersion.MediaStreams;
+ var mediaStreams = mediaSource.MediaStreams;
var videoStream = mediaStreams.filter(function (stream) {
return stream.Type === "Video";
@@ -254,7 +254,7 @@
return stream.Index === subtitleStreamIndex;
})[0];
- var canPlayDirect = self.canPlayVideoDirect(mediaVersion, videoStream, audioStream, subtitleStream, maxWidth, bitrate);
+ var canPlayDirect = self.canPlayVideoDirect(mediaSource, videoStream, audioStream, subtitleStream, maxWidth, bitrate);
var audioBitrate = bitrate >= 700000 ? 128000 : 64000;
@@ -404,7 +404,7 @@
return parseInt(localStorage.getItem('preferredVideoBitrate') || '') || 1500000;
};
- function getOptimalMediaVersion(mediaType, versions) {
+ function getOptimalMediaSource(mediaType, versions) {
var optimalVersion;
@@ -449,23 +449,23 @@
if (item.MediaType === "Video") {
currentItem = item;
- currentMediaVersion = getOptimalMediaVersion(item.MediaType, item.MediaVersions);
+ currentMediaSource = getOptimalMediaSource(item.MediaType, item.MediaSources);
- videoPlayer(self, item, currentMediaVersion, startPosition, user);
+ videoPlayer(self, item, currentMediaSource, startPosition, user);
mediaElement = self.initVideoPlayer();
- curentDurationTicks = currentMediaVersion.RunTimeTicks;
+ curentDurationTicks = currentMediaSource.RunTimeTicks;
mediaControls = $("#videoControls");
} else if (item.MediaType === "Audio") {
currentItem = item;
- currentMediaVersion = getOptimalMediaVersion(item.MediaType, item.MediaVersions);
+ currentMediaSource = getOptimalMediaSource(item.MediaType, item.MediaSources);
- mediaElement = playAudio(item, currentMediaVersion, startPosition);
+ mediaElement = playAudio(item, currentMediaSource, startPosition);
mediaControls.show();
- curentDurationTicks = currentMediaVersion.RunTimeTicks;
+ curentDurationTicks = currentMediaSource.RunTimeTicks;
} else {
throw new Error("Unrecognized media type");
@@ -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, currentMediaSource.Id, position);
}
});
@@ -984,9 +984,9 @@
return url + '&' + param + "=" + value;
};
- function sendProgressUpdate(itemId) {
+ function sendProgressUpdate(itemId, mediaSourceId) {
- ApiClient.reportPlaybackProgress(Dashboard.getCurrentUserId(), itemId, self.getCurrentTicks(), currentMediaElement.paused, currentMediaElement.volume == 0);
+ ApiClient.reportPlaybackProgress(Dashboard.getCurrentUserId(), itemId, mediaSourceId, self.getCurrentTicks(), currentMediaElement.paused, currentMediaElement.volume == 0);
};
function clearProgressInterval() {
@@ -1008,7 +1008,7 @@
var newPercent = parseInt(this.value);
- var newPositionTicks = (newPercent / 100) * currentMediaVersion.RunTimeTicks;
+ var newPositionTicks = (newPercent / 100) * currentMediaSource.RunTimeTicks;
self.changeStream(Math.floor(newPositionTicks));
};
@@ -1022,29 +1022,30 @@
return d >= 0 && text.lastIndexOf(pattern) === d;
};
- function playAudio(item, mediaVersion, startPositionTicks) {
+ function playAudio(item, mediaSource, startPositionTicks) {
startPositionTicks = startPositionTicks || 0;
var baseParams = {
audioChannels: 2,
audioBitrate: 128000,
- StartTimeTicks: startPositionTicks
+ StartTimeTicks: startPositionTicks,
+ mediaSourceId: mediaSource.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'
}));
- var mediaStreams = mediaVersion.MediaStreams;
+ var mediaStreams = mediaSource.MediaStreams;
var isStatic = false;
var seekParam = isStatic && startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
@@ -1056,11 +1057,11 @@
if (stream.Type == "Audio") {
// Stream statically when possible
- if (endsWith(mediaVersion.Path, ".aac") && stream.BitRate <= 256000) {
+ if (endsWith(mediaSource.Path, ".aac") && stream.BitRate <= 256000) {
aacUrl += "&static=true" + seekParam;
isStatic = true;
}
- else if (endsWith(mediaVersion.Path, ".mp3") && stream.BitRate <= 256000) {
+ else if (endsWith(mediaSource.Path, ".mp3") && stream.BitRate <= 256000) {
mp3Url += "&static=true" + seekParam;
isStatic = true;
}
@@ -1131,9 +1132,9 @@
audioElement.off("play.once");
- ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), mediaVersion.ItemId, true, item.MediaType);
+ ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), item.Id, mediaSource.Id, true, item.MediaType);
- self.startProgressInterval(mediaVersion.ItemId);
+ self.startProgressInterval(item.Id, mediaSource.Id);
}).on("pause", function () {
@@ -1200,7 +1201,7 @@
return (trunc(titles[0], 30) + " " + trunc(titles[1], 30)).replace("---", " ");
};
- var getItemFields = "MediaVersions";
+ var getItemFields = "MediaSources,Chapters";
}
window.MediaPlayer = new mediaPlayer();
diff --git a/packages.config b/packages.config
index 0bdea523e3..7396527bb3 100644
--- a/packages.config
+++ b/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
|