mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
rework text subtitles
This commit is contained in:
parent
1447aafd24
commit
8ef09d054d
11 changed files with 300 additions and 146 deletions
25
ApiClient.js
25
ApiClient.js
|
@ -436,13 +436,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
|
|
||||||
self.getLiveTvPrograms = function (options) {
|
self.getLiveTvPrograms = function (options) {
|
||||||
|
|
||||||
var url = self.getUrl("LiveTv/Programs", options || {});
|
options = options || {};
|
||||||
|
|
||||||
|
if (options.channelIds) {
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "GET",
|
type: "POST",
|
||||||
url: url,
|
url: self.getUrl("LiveTv/Programs"),
|
||||||
dataType: "json"
|
data: JSON.stringify(options),
|
||||||
});
|
contentType: "application/json",
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: self.getUrl("LiveTv/Programs", options),
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getLiveTvRecordings = function (options) {
|
self.getLiveTvRecordings = function (options) {
|
||||||
|
|
|
@ -133,12 +133,12 @@
|
||||||
|
|
||||||
.channelTimeslotHeader {
|
.channelTimeslotHeader {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeslotHeaders {
|
.timeslotHeaders {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 13px;
|
right: 28px;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -205,14 +205,14 @@
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 15px;
|
||||||
bottom: 16px;
|
bottom: 46px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.programGrid {
|
.programGrid {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 30px;
|
||||||
right: 0;
|
right: 15px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
}
|
}
|
||||||
|
@ -242,15 +242,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeslotHeaders, .programGrid {
|
.timeslotHeaders, .programGrid {
|
||||||
left: 191px;
|
left: 206px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channelTimeslotHeader, .timeslotHeaders {
|
.channelTimeslotHeader, .timeslotHeaders {
|
||||||
top: 135px;
|
top: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channelList, .programGrid {
|
.channelList, .programGrid {
|
||||||
top: 165px;
|
top: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channelHeaderCell, .timeslotCell {
|
.channelHeaderCell, .timeslotCell {
|
||||||
|
@ -305,10 +305,10 @@
|
||||||
@media (max-width: 750px) {
|
@media (max-width: 750px) {
|
||||||
|
|
||||||
.channelTimeslotHeader, .timeslotHeaders {
|
.channelTimeslotHeader, .timeslotHeaders {
|
||||||
top: 100px;
|
top: 115px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.channelList, .programGrid {
|
.channelList, .programGrid {
|
||||||
top: 130px;
|
top: 145px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,15 @@
|
||||||
<form class="encodingSettingsForm">
|
<form class="encodingSettingsForm">
|
||||||
|
|
||||||
<fieldset data-role="controlgroup">
|
<fieldset data-role="controlgroup">
|
||||||
<legend>Transcoding Quality:</legend>
|
<legend>Transcoding Quality Preference:</legend>
|
||||||
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioAuto" value="Auto">
|
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioAuto" value="Auto">
|
||||||
<label for="radioAuto">Auto<br /><span style="font-weight:normal;">The server will decide quality and speed</span></label>
|
<label for="radioAuto">Auto<br /><span style="font-weight:normal;">The server will decide quality and speed</span></label>
|
||||||
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioHighSpeed" value="HighSpeed">
|
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioHighSpeed" value="HighSpeed">
|
||||||
<label for="radioHighSpeed">Prefer higher speed<br /><span style="font-weight:normal;">Lower quality, but faster encoding</span></label>
|
<label for="radioHighSpeed">Higher speed<br /><span style="font-weight:normal;">Lower quality, but faster encoding</span></label>
|
||||||
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioHighQuality" value="HighQuality">
|
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioHighQuality" value="HighQuality">
|
||||||
<label for="radioHighQuality">Prefer higher quality<br /><span style="font-weight:normal;">Higher quality, but slower encoding</span></label>
|
<label for="radioHighQuality">Higher quality<br /><span style="font-weight:normal;">Higher quality, but slower encoding</span></label>
|
||||||
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioMaxQuality" value="MaxQuality">
|
<input type="radio" name="radioEncodingQuality" class="radioEncodingQuality" id="radioMaxQuality" value="MaxQuality">
|
||||||
<label for="radioMaxQuality">Perfer max quality<br /><span style="font-weight:normal;">Best quality with slower encoding and high CPU usage</span></label>
|
<label for="radioMaxQuality">Max quality<br /><span style="font-weight:normal;">Best quality with slower encoding and high CPU usage</span></label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -141,6 +141,9 @@
|
||||||
<span id="playButtonContainer" style="display: none;">
|
<span id="playButtonContainer" style="display: none;">
|
||||||
<button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button>
|
<button id="btnPlay" type="button" data-icon="play" data-inline="true" data-mini="true">Play</button>
|
||||||
</span>
|
</span>
|
||||||
|
<span id="trailerButtonContainer">
|
||||||
|
<button id="btnPlayTrailer" type="button" data-icon="play" data-inline="true" data-mini="true">Trailer</button>
|
||||||
|
</span>
|
||||||
<span id="playExternalButtonContainer" style="display: none;">
|
<span id="playExternalButtonContainer" style="display: none;">
|
||||||
<a id="btnPlayExternal" data-role="button" data-icon="play" data-inline="true" data-mini="true" href="#" target="_blank">Play</a>
|
<a id="btnPlayExternal" data-role="button" data-icon="play" data-inline="true" data-mini="true" href="#" target="_blank">Play</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -16,10 +16,15 @@
|
||||||
<div data-role="content" style="padding-top: 5px;">
|
<div data-role="content" style="padding-top: 5px;">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div style="text-align: center;">
|
||||||
<select id="selectDate" data-mini="true" data-icon="calendar" data-inline="true">
|
<select id="selectDate" data-mini="true" data-icon="calendar" data-inline="true">
|
||||||
<option>Today</option>
|
<option>Today</option>
|
||||||
</select>
|
</select>
|
||||||
|
<div style="display: inline-block; vertical-align: middle;">
|
||||||
|
Channels
|
||||||
|
</div>
|
||||||
|
<div style="display: inline-block; vertical-align: middle;" class="channelPaging">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -83,6 +83,12 @@
|
||||||
$('#playButtonContainer', page).hide();
|
$('#playButtonContainer', page).hide();
|
||||||
$('#playExternalButtonContainer', page).hide();
|
$('#playExternalButtonContainer', page).hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.LocalTrailerCount && item.LocationType !== "Offline") {
|
||||||
|
$('#trailerButtonContainer', page).show();
|
||||||
|
} else {
|
||||||
|
$('#trailerButtonContainer', page).hide();
|
||||||
|
}
|
||||||
|
|
||||||
$(".autoNumeric").autoNumeric('init');
|
$(".autoNumeric").autoNumeric('init');
|
||||||
|
|
||||||
|
@ -189,7 +195,7 @@
|
||||||
$('#scenesCollapsible', page).show();
|
$('#scenesCollapsible', page).show();
|
||||||
renderScenes(page, item, 4);
|
renderScenes(page, item, 4);
|
||||||
}
|
}
|
||||||
if (!item.LocalTrailerCount && !item.RemoteTrailers.length) {
|
if (item.LocalTrailerCount || !item.RemoteTrailers.length) {
|
||||||
$('#trailersCollapsible', page).addClass('hide');
|
$('#trailersCollapsible', page).addClass('hide');
|
||||||
} else {
|
} else {
|
||||||
$('#trailersCollapsible', page).removeClass('hide');
|
$('#trailersCollapsible', page).removeClass('hide');
|
||||||
|
@ -1120,6 +1126,24 @@
|
||||||
LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, mediaType, userdata.PlaybackPositionTicks);
|
LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, mediaType, userdata.PlaybackPositionTicks);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#btnPlayTrailer', page).on('click', function () {
|
||||||
|
|
||||||
|
ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), currentItem.Id).done(function (trailers) {
|
||||||
|
|
||||||
|
var trailer = trailers[0];
|
||||||
|
var userdata = trailer.UserData || {};
|
||||||
|
|
||||||
|
var mediaType = trailer.MediaType;
|
||||||
|
|
||||||
|
if (trailer.Type == "MusicArtist" || trailer.Type == "MusicAlbum") {
|
||||||
|
mediaType = "Audio";
|
||||||
|
}
|
||||||
|
|
||||||
|
LibraryBrowser.showPlayMenu(this, trailer.Id, trailer.Type, mediaType, userdata.PlaybackPositionTicks);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$('#btnPlayExternal', page).on('click', function () {
|
$('#btnPlayExternal', page).on('click', function () {
|
||||||
|
|
||||||
ApiClient.markPlayed(Dashboard.getCurrentUserId(), currentItem.Id, new Date());
|
ApiClient.markPlayed(Dashboard.getCurrentUserId(), currentItem.Id, new Date());
|
||||||
|
|
|
@ -1417,7 +1417,7 @@
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
||||||
getPagingHtml: function (query, totalRecordCount, updatePageSizeSetting) {
|
getPagingHtml: function (query, totalRecordCount, updatePageSizeSetting, pageSizes) {
|
||||||
|
|
||||||
if (query.Limit && updatePageSizeSetting !== false) {
|
if (query.Limit && updatePageSizeSetting !== false) {
|
||||||
localStorage.setItem('pagesize', query.Limit);
|
localStorage.setItem('pagesize', query.Limit);
|
||||||
|
@ -1477,13 +1477,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
options += getOption(20);
|
pageSizes = pageSizes || [20, 50, 100, 200, 300, 400, 500];
|
||||||
options += getOption(50);
|
|
||||||
options += getOption(100);
|
for (var j = 0, length = pageSizes.length; j < length; j++) {
|
||||||
options += getOption(200);
|
options += getOption(pageSizes[j]);
|
||||||
options += getOption(300);
|
}
|
||||||
options += getOption(400);
|
|
||||||
options += getOption(500);
|
|
||||||
|
|
||||||
// Add styles to defeat jquery mobile
|
// Add styles to defeat jquery mobile
|
||||||
html += '<label style="display:inline;font-size:inherit;" class="labelPageSize" for="' + id + '">Limit: </label><select class="selectPageSize" id="' + id + '" data-enhance="false" data-role="none">' + options + '</select>';
|
html += '<label style="display:inline;font-size:inherit;" class="labelPageSize" for="' + id + '">Limit: </label><select class="selectPageSize" id="' + id + '" data-enhance="false" data-role="none">' + options + '</select>';
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
(function ($, document, apiClient) {
|
(function ($, document, apiClient) {
|
||||||
|
|
||||||
|
var query = {
|
||||||
|
|
||||||
|
StartIndex: 0
|
||||||
|
};
|
||||||
|
|
||||||
function getChannelsHtml(channels) {
|
function getChannelsHtml(channels) {
|
||||||
|
|
||||||
return LibraryBrowser.getPosterViewHtml({
|
return LibraryBrowser.getPosterViewHtml({
|
||||||
|
@ -10,23 +15,64 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderChannels(page, channels) {
|
function renderChannels(page, result) {
|
||||||
|
|
||||||
$('#items', page).html(getChannelsHtml(channels)).trigger('create');
|
$('.listTopPaging', page).html(LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, true)).trigger('create');
|
||||||
|
|
||||||
|
var html = getChannelsHtml(result.Items);
|
||||||
|
|
||||||
|
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount);
|
||||||
|
|
||||||
|
$('#items', page).html(html).trigger('create');
|
||||||
|
|
||||||
|
$('.selectPage', page).on('change', function () {
|
||||||
|
query.StartIndex = (parseInt(this.value) - 1) * query.Limit;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnNextPage', page).on('click', function () {
|
||||||
|
query.StartIndex += query.Limit;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnPreviousPage', page).on('click', function () {
|
||||||
|
query.StartIndex -= query.Limit;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.selectPageSize', page).on('change', function () {
|
||||||
|
query.Limit = parseInt(this.value);
|
||||||
|
query.StartIndex = 0;
|
||||||
|
reloadItems(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
LibraryBrowser.saveQueryValues('movies', query);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadItems(page) {
|
||||||
|
apiClient.getLiveTvChannels(query).done(function (result) {
|
||||||
|
|
||||||
|
renderChannels(page, result);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).on('pagebeforeshow', "#liveTvChannelsPage", function () {
|
$(document).on('pagebeforeshow', "#liveTvChannelsPage", function () {
|
||||||
|
|
||||||
var page = this;
|
var page = this;
|
||||||
|
|
||||||
apiClient.getLiveTvChannels({
|
var limit = LibraryBrowser.getDefaultPageSize();
|
||||||
|
|
||||||
userId: Dashboard.getCurrentUserId()
|
|
||||||
|
|
||||||
}).done(function (result) {
|
// If the default page size has changed, the start index will have to be reset
|
||||||
|
if (limit != query.Limit) {
|
||||||
|
query.Limit = limit;
|
||||||
|
query.StartIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
renderChannels(page, result.Items);
|
query.UserId = Dashboard.getCurrentUserId();
|
||||||
});
|
|
||||||
|
LibraryBrowser.loadSavedQueryValues('movies', query);
|
||||||
|
|
||||||
|
reloadItems(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
})(jQuery, document, ApiClient);
|
})(jQuery, document, ApiClient);
|
|
@ -8,6 +8,12 @@
|
||||||
var gridLocalEndDateMs;
|
var gridLocalEndDateMs;
|
||||||
|
|
||||||
var currentDate;
|
var currentDate;
|
||||||
|
|
||||||
|
var channelQuery = {
|
||||||
|
|
||||||
|
StartIndex: 0,
|
||||||
|
Limit: 20
|
||||||
|
};
|
||||||
var channelsPromise;
|
var channelsPromise;
|
||||||
|
|
||||||
function normalizeDateToTimeslot(date) {
|
function normalizeDateToTimeslot(date) {
|
||||||
|
@ -25,16 +31,19 @@
|
||||||
|
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reloadChannels(page) {
|
||||||
|
channelsPromise = null;
|
||||||
|
reloadGuide(page);
|
||||||
|
}
|
||||||
|
|
||||||
function reloadGuide(page) {
|
function reloadGuide(page) {
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
channelsPromise = channelsPromise || apiClient.getLiveTvChannels({
|
|
||||||
|
|
||||||
userId: Dashboard.getCurrentUserId()
|
channelQuery.userId = Dashboard.getCurrentUserId();
|
||||||
|
|
||||||
});;
|
channelsPromise = channelsPromise || apiClient.getLiveTvChannels(channelQuery);
|
||||||
|
|
||||||
var date = currentDate;
|
var date = currentDate;
|
||||||
|
|
||||||
|
@ -42,23 +51,45 @@
|
||||||
nextDay.setHours(0, 0, 0, 0);
|
nextDay.setHours(0, 0, 0, 0);
|
||||||
nextDay.setDate(nextDay.getDate() + 1);
|
nextDay.setDate(nextDay.getDate() + 1);
|
||||||
|
|
||||||
var promise1 = channelsPromise;
|
channelsPromise.done(function(channelsResult) {
|
||||||
var promise2 = apiClient.getLiveTvPrograms({
|
|
||||||
|
|
||||||
UserId: Dashboard.getCurrentUserId(),
|
apiClient.getLiveTvPrograms({
|
||||||
MaxStartDate: nextDay.toISOString(),
|
UserId: Dashboard.getCurrentUserId(),
|
||||||
MinEndDate: date.toISOString()
|
MaxStartDate: nextDay.toISOString(),
|
||||||
|
MinEndDate: date.toISOString(),
|
||||||
});
|
channelIds: channelsResult.Items.map(function(c) {
|
||||||
|
return c.Id;
|
||||||
$.when(promise1, promise2).done(function (response1, response2) {
|
}).join(',')
|
||||||
|
|
||||||
var channels = response1[0].Items;
|
}).done(function(programsResult) {
|
||||||
var programs = response2[0].Items;
|
|
||||||
|
renderGuide(page, date, channelsResult.Items, programsResult.Items);
|
||||||
renderGuide(page, date, channels, programs);
|
Dashboard.hideLoadingMsg();
|
||||||
|
});
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
var channelPagingHtml = LibraryBrowser.getPagingHtml(channelQuery, channelsResult.TotalRecordCount, false, [10, 20, 30, 50, 100]);
|
||||||
|
$('.channelPaging', page).html(channelPagingHtml).trigger('create');
|
||||||
|
|
||||||
|
$('.selectPage', page).on('change', function () {
|
||||||
|
channelQuery.StartIndex = (parseInt(this.value) - 1) * channelQuery.Limit;
|
||||||
|
reloadChannels(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnNextPage', page).on('click', function () {
|
||||||
|
channelQuery.StartIndex += channelQuery.Limit;
|
||||||
|
reloadChannels(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnPreviousPage', page).on('click', function () {
|
||||||
|
channelQuery.StartIndex -= channelQuery.Limit;
|
||||||
|
reloadChannels(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.selectPageSize', page).on('change', function () {
|
||||||
|
channelQuery.Limit = parseInt(this.value);
|
||||||
|
channelQuery.StartIndex = 0;
|
||||||
|
reloadChannels(page);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +253,7 @@
|
||||||
|
|
||||||
html += '<div class="guideProgramName">';
|
html += '<div class="guideProgramName">';
|
||||||
html += program.Name;
|
html += program.Name;
|
||||||
|
|
||||||
if (program.IsRepeat) {
|
if (program.IsRepeat) {
|
||||||
html += ' (R)';
|
html += ' (R)';
|
||||||
}
|
}
|
||||||
|
@ -373,7 +404,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var elem = $('#selectDate', page).html(html).selectmenu('refresh');
|
var elem = $('#selectDate', page).html(html).selectmenu('refresh');
|
||||||
|
|
||||||
if (currentDate) {
|
if (currentDate) {
|
||||||
elem.val(currentDate.getTime()).selectmenu('refresh');
|
elem.val(currentDate.getTime()).selectmenu('refresh');
|
||||||
}
|
}
|
||||||
|
@ -394,8 +425,8 @@
|
||||||
onProgramGridScroll(page, this);
|
onProgramGridScroll(page, this);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#selectDate', page).on('change', function() {
|
$('#selectDate', page).on('change', function () {
|
||||||
|
|
||||||
var date = new Date();
|
var date = new Date();
|
||||||
date.setTime(parseInt(this.value));
|
date.setTime(parseInt(this.value));
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
var unmuteButton;
|
var unmuteButton;
|
||||||
var startTimeTicksOffset;
|
var startTimeTicksOffset;
|
||||||
var curentDurationTicks;
|
var curentDurationTicks;
|
||||||
var isStaticStream;
|
var canClientSeek;
|
||||||
var culturesPromise;
|
var culturesPromise;
|
||||||
var timeout;
|
var timeout;
|
||||||
var idleState = true;
|
var idleState = true;
|
||||||
|
@ -28,6 +28,11 @@
|
||||||
var channelsListPromise;
|
var channelsListPromise;
|
||||||
var channelsListPromiseTime;
|
var channelsListPromiseTime;
|
||||||
|
|
||||||
|
function updateCanClientSeek(elem) {
|
||||||
|
var duration = elem.duration;
|
||||||
|
canClientSeek = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY;
|
||||||
|
}
|
||||||
|
|
||||||
function getChannelsListPromise() {
|
function getChannelsListPromise() {
|
||||||
|
|
||||||
var lastUpdateTime = channelsListPromiseTime || 0;
|
var lastUpdateTime = channelsListPromiseTime || 0;
|
||||||
|
@ -176,13 +181,14 @@
|
||||||
currentProgressInterval = null;
|
currentProgressInterval = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTranscodingExtension() {
|
function getTranscodingExtension() {
|
||||||
|
|
||||||
var media = testableVideoElement;
|
var media = testableVideoElement;
|
||||||
|
|
||||||
// safari
|
// safari
|
||||||
if (media.canPlayType('application/x-mpegURL').replace(/no/, '')) {
|
if (media.canPlayType('application/x-mpegURL').replace(/no/, '') ||
|
||||||
|
media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')) {
|
||||||
return '.m3u8';
|
return '.m3u8';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +196,7 @@
|
||||||
if (media.canPlayType('video/webm').replace(/no/, '')) {
|
if (media.canPlayType('video/webm').replace(/no/, '')) {
|
||||||
return '.webm';
|
return '.webm';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '.mp4';
|
return '.mp4';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +204,7 @@
|
||||||
|
|
||||||
var element = currentMediaElement;
|
var element = currentMediaElement;
|
||||||
|
|
||||||
if (isStaticStream && params == null) {
|
if (canClientSeek && params == null) {
|
||||||
|
|
||||||
element.currentTime = ticks / (1000 * 10000);
|
element.currentTime = ticks / (1000 * 10000);
|
||||||
|
|
||||||
|
@ -207,7 +213,6 @@
|
||||||
params = params || {};
|
params = params || {};
|
||||||
|
|
||||||
var currentSrc = element.currentSrc;
|
var currentSrc = element.currentSrc;
|
||||||
console.log(currentSrc);
|
|
||||||
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks);
|
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks);
|
||||||
|
|
||||||
if (params.AudioStreamIndex != null) {
|
if (params.AudioStreamIndex != null) {
|
||||||
|
@ -232,7 +237,7 @@
|
||||||
currentSrc = replaceQueryString(currentSrc, 'VideoCodec', params.VideoCodec);
|
currentSrc = replaceQueryString(currentSrc, 'VideoCodec', params.VideoCodec);
|
||||||
}
|
}
|
||||||
if (params.Static != null) {
|
if (params.Static != null) {
|
||||||
|
|
||||||
currentSrc = replaceQueryString(currentSrc, 'Static', params.Static);
|
currentSrc = replaceQueryString(currentSrc, 'Static', params.Static);
|
||||||
|
|
||||||
if (params.Static == 'true') {
|
if (params.Static == 'true') {
|
||||||
|
@ -246,6 +251,8 @@
|
||||||
|
|
||||||
$(element).off('ended.playbackstopped').off('ended.playnext').on("play.onceafterseek", function () {
|
$(element).off('ended.playbackstopped').off('ended.playnext').on("play.onceafterseek", function () {
|
||||||
|
|
||||||
|
updateCanClientSeek(this);
|
||||||
|
|
||||||
$(this).off('play.onceafterseek').on('ended.playbackstopped', onPlaybackStopped).on('ended.playnext', playNextAfterEnded);
|
$(this).off('play.onceafterseek').on('ended.playbackstopped', onPlaybackStopped).on('ended.playnext', playNextAfterEnded);
|
||||||
|
|
||||||
startProgressInterval(currentItem.Id);
|
startProgressInterval(currentItem.Id);
|
||||||
|
@ -256,7 +263,6 @@
|
||||||
ApiClient.stopActiveEncodings().done(function () {
|
ApiClient.stopActiveEncodings().done(function () {
|
||||||
|
|
||||||
startTimeTicksOffset = ticks;
|
startTimeTicksOffset = ticks;
|
||||||
|
|
||||||
element.src = currentSrc;
|
element.src = currentSrc;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -333,22 +339,20 @@
|
||||||
var videoBitrate = parseInt(this.getAttribute('data-videobitrate'));
|
var videoBitrate = parseInt(this.getAttribute('data-videobitrate'));
|
||||||
var audioBitrate = parseInt(this.getAttribute('data-audiobitrate'));
|
var audioBitrate = parseInt(this.getAttribute('data-audiobitrate'));
|
||||||
|
|
||||||
var mp4AudioCodec = this.getAttribute('data-mp4audio');
|
var audioCodec = this.getAttribute('data-audiocodec');
|
||||||
var mp4VideoCodec = this.getAttribute('data-mp4video');
|
var videoCodec = this.getAttribute('data-videocodec');
|
||||||
var isStatic = this.getAttribute('data-static');
|
var isStatic = this.getAttribute('data-static');
|
||||||
|
|
||||||
localStorage.setItem('preferredVideoBitrate', videoBitrate + audioBitrate);
|
localStorage.setItem('preferredVideoBitrate', videoBitrate + audioBitrate);
|
||||||
|
|
||||||
var isMp4 = currentMediaElement.currentSrc.toLowerCase().indexOf('.mp4') != -1;
|
|
||||||
|
|
||||||
changeStream(getCurrentTicks(), {
|
changeStream(getCurrentTicks(), {
|
||||||
|
|
||||||
MaxWidth: maxWidth,
|
MaxWidth: maxWidth,
|
||||||
VideoBitrate: videoBitrate,
|
VideoBitrate: videoBitrate,
|
||||||
AudioBitrate: audioBitrate,
|
AudioBitrate: audioBitrate,
|
||||||
Static: isStatic,
|
Static: isStatic,
|
||||||
AudioCodec: isMp4 ? mp4AudioCodec : null,
|
AudioCodec: audioCodec,
|
||||||
VideoCodec: isMp4 ? mp4VideoCodec : null
|
VideoCodec: videoCodec
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,15 +403,16 @@
|
||||||
currentTimeElement.html(timeText);
|
currentTimeElement.html(timeText);
|
||||||
}
|
}
|
||||||
|
|
||||||
function playAudio(item, params) {
|
function playAudio(item, startPositionTicks) {
|
||||||
|
|
||||||
|
startPositionTicks = startPositionTicks || 0;
|
||||||
|
|
||||||
var baseParams = {
|
var baseParams = {
|
||||||
audioChannels: 2,
|
audioChannels: 2,
|
||||||
audioBitrate: 128000
|
audioBitrate: 128000,
|
||||||
|
StartTimeTicks: startPositionTicks
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend(baseParams, params);
|
|
||||||
|
|
||||||
var mp3Url = ApiClient.getUrl('Audio/' + item.Id + '/stream.mp3', $.extend({}, baseParams, {
|
var mp3Url = ApiClient.getUrl('Audio/' + item.Id + '/stream.mp3', $.extend({}, baseParams, {
|
||||||
audioCodec: 'mp3'
|
audioCodec: 'mp3'
|
||||||
}));
|
}));
|
||||||
|
@ -422,6 +427,9 @@
|
||||||
|
|
||||||
var mediaStreams = item.MediaStreams || [];
|
var mediaStreams = item.MediaStreams || [];
|
||||||
|
|
||||||
|
var isStatic = false;
|
||||||
|
var seekParam = isStatic && startPositionTicks ? '#t=' + (startPositionTicks / 10000000) : '';
|
||||||
|
|
||||||
for (var i = 0, length = mediaStreams.length; i < length; i++) {
|
for (var i = 0, length = mediaStreams.length; i < length; i++) {
|
||||||
|
|
||||||
var stream = mediaStreams[i];
|
var stream = mediaStreams[i];
|
||||||
|
@ -430,16 +438,19 @@
|
||||||
|
|
||||||
// Stream statically when possible
|
// Stream statically when possible
|
||||||
if (endsWith(item.Path, ".aac") && stream.BitRate <= 256000) {
|
if (endsWith(item.Path, ".aac") && stream.BitRate <= 256000) {
|
||||||
aacUrl += "&static=true";
|
aacUrl += "&static=true" + seekParam;
|
||||||
|
isStatic = true;
|
||||||
}
|
}
|
||||||
else if (endsWith(item.Path, ".mp3") && stream.BitRate <= 256000) {
|
else if (endsWith(item.Path, ".mp3") && stream.BitRate <= 256000) {
|
||||||
mp3Url += "&static=true";
|
mp3Url += "&static=true" + seekParam;
|
||||||
|
isStatic = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startTimeTicksOffset = isStatic ? 0 : startPositionTicks;
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
var requiresControls = $.browser.android || ($.browser.webkit && !$.browser.chrome);
|
var requiresControls = $.browser.android || ($.browser.webkit && !$.browser.chrome);
|
||||||
|
@ -498,8 +509,7 @@
|
||||||
audioElement.hide();
|
audioElement.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
var duration = this.duration;
|
updateCanClientSeek(this);
|
||||||
isStaticStream = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY;
|
|
||||||
|
|
||||||
audioElement.off("play.once");
|
audioElement.off("play.once");
|
||||||
|
|
||||||
|
@ -549,7 +559,11 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var extension = item.Path.substring(item.Path.lastIndexOf('.') + 1);
|
var extension = item.Path.substring(item.Path.lastIndexOf('.') + 1).toLowerCase();
|
||||||
|
|
||||||
|
if (extension == 'm4v') {
|
||||||
|
return $.browser.chrome;
|
||||||
|
}
|
||||||
|
|
||||||
return extension.toLowerCase() == 'mp4';
|
return extension.toLowerCase() == 'mp4';
|
||||||
}
|
}
|
||||||
|
@ -575,7 +589,7 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVideoQualityOptions(item, audioStreamIndex) {
|
function getVideoQualityOptions(item, audioStreamIndex, transcodeExtension) {
|
||||||
|
|
||||||
var videoStream = (item.MediaStreams || []).filter(function (stream) {
|
var videoStream = (item.MediaStreams || []).filter(function (stream) {
|
||||||
return stream.Type == "Video";
|
return stream.Type == "Video";
|
||||||
|
@ -600,6 +614,13 @@
|
||||||
maxAllowedWidth = videoStream.Width;
|
maxAllowedWidth = videoStream.Width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var canPlayVideoCodecDirect = (videoStream ? videoStream.Codec : '').toLowerCase().indexOf('h264') != -1;
|
||||||
|
var canPlayAudioDirect = audioStream ? canPlayAudioStreamDirect(audioStream) : false;
|
||||||
|
|
||||||
|
var videoBitrate = videoStream ? videoStream.BitRate : null;
|
||||||
|
var audioBitrate = audioStream ? audioStream.BitRate : null;
|
||||||
|
var totalBitrate = (videoBitrate || 0) + (audioBitrate || 0);
|
||||||
|
|
||||||
// Some 1080- videos are reported as 1912?
|
// Some 1080- videos are reported as 1912?
|
||||||
if (maxAllowedWidth >= 1910) {
|
if (maxAllowedWidth >= 1910) {
|
||||||
options.push({ name: '1080p - 10Mbps', maxWidth: 1920, bitrate: 10000000 });
|
options.push({ name: '1080p - 10Mbps', maxWidth: 1920, bitrate: 10000000 });
|
||||||
|
@ -630,13 +651,6 @@
|
||||||
options.push({ name: '360p', maxWidth: 640, bitrate: 400000 });
|
options.push({ name: '360p', maxWidth: 640, bitrate: 400000 });
|
||||||
options.push({ name: '240p', maxWidth: 426, bitrate: 320000 });
|
options.push({ name: '240p', maxWidth: 426, bitrate: 320000 });
|
||||||
|
|
||||||
var canPlayVideoCodecDirect = (videoStream ? videoStream.Codec : '').toLowerCase().indexOf('h264') != -1;
|
|
||||||
var canPlayAudioDirect = audioStream ? canPlayAudioStreamDirect(audioStream) : false;
|
|
||||||
|
|
||||||
var videoBitrate = videoStream ? videoStream.BitRate : null;
|
|
||||||
var audioBitrate = audioStream ? audioStream.BitRate : null;
|
|
||||||
var totalBitrate = (videoBitrate || 0) + (audioBitrate || 0);
|
|
||||||
|
|
||||||
var videoWidth = videoStream ? videoStream.Width : null;
|
var videoWidth = videoStream ? videoStream.Width : null;
|
||||||
|
|
||||||
var i, length, option;
|
var i, length, option;
|
||||||
|
@ -660,15 +674,18 @@
|
||||||
if (canPlayDirect) {
|
if (canPlayDirect) {
|
||||||
|
|
||||||
option.isStatic = true;
|
option.isStatic = true;
|
||||||
option.mp4VideoCodec = 'copy';
|
option.videoCodec = 'copy';
|
||||||
option.mp4AudioCodec = 'copy';
|
option.audioCodec = 'copy';
|
||||||
}
|
}
|
||||||
|
//else if (canPlayVideoCodecDirect && transcodeExtension == '.m3u8') {
|
||||||
|
// option.videoCodec = 'copy';
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
option.isStatic = option.isStatic || false;
|
option.isStatic = option.isStatic || false;
|
||||||
option.mp4VideoCodec = option.mp4VideoCodec || 'h264';
|
|
||||||
|
|
||||||
option.mp4AudioCodec = option.mp4AudioCodec || 'aac';
|
option.videoCodec = option.videoCodec || (transcodeExtension == '.webm' ? 'vpx' : 'h264');
|
||||||
|
option.audioCodec = option.audioCodec || (transcodeExtension == '.webm' ? 'Vorbis' : 'aac');
|
||||||
|
|
||||||
option.videoBitrate = option.bitrate - option.audioBitrate;
|
option.videoBitrate = option.bitrate - option.audioBitrate;
|
||||||
}
|
}
|
||||||
|
@ -681,7 +698,7 @@
|
||||||
options[selectedIndex].selected = true;
|
options[selectedIndex].selected = true;
|
||||||
|
|
||||||
var firstOption = options[0];
|
var firstOption = options[0];
|
||||||
|
|
||||||
if (firstOption.isStatic) {
|
if (firstOption.isStatic) {
|
||||||
firstOption.name = 'Direct';
|
firstOption.name = 'Direct';
|
||||||
}
|
}
|
||||||
|
@ -703,39 +720,60 @@
|
||||||
Static: false
|
Static: false
|
||||||
};
|
};
|
||||||
|
|
||||||
var qualityOption = getVideoQualityOptions(item, baseParams.AudioStreamIndex).filter(function (opt) {
|
var mp4Quality = getVideoQualityOptions(item, baseParams.AudioStreamIndex, '.mp4').filter(function (opt) {
|
||||||
return opt.selected;
|
return opt.selected;
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
baseParams.maxWidth = qualityOption.maxWidth;
|
var webmQuality = getVideoQualityOptions(item, baseParams.AudioStreamIndex, '.webm').filter(function (opt) {
|
||||||
baseParams.videoBitrate = qualityOption.videoBitrate;
|
return opt.selected;
|
||||||
baseParams.audioBitrate = qualityOption.audioBitrate;
|
})[0];
|
||||||
|
|
||||||
|
var m3U8Quality = getVideoQualityOptions(item, baseParams.AudioStreamIndex, '.m3u8').filter(function (opt) {
|
||||||
|
return opt.selected;
|
||||||
|
})[0];
|
||||||
|
|
||||||
// Webm must be ahead of mp4 due to the issue of mp4 playing too fast in chrome
|
// Webm must be ahead of mp4 due to the issue of mp4 playing too fast in chrome
|
||||||
var prioritizeWebmOverH264 = $.browser.chrome || $.browser.msie;
|
var prioritizeWebmOverH264 = $.browser.chrome || $.browser.msie;
|
||||||
|
|
||||||
var staticMp4 = qualityOption.isStatic;
|
var isStatic = mp4Quality.isStatic;
|
||||||
|
|
||||||
|
startTimeTicksOffset = isStatic ? 0 : startPosition || 0;
|
||||||
|
|
||||||
|
var seekParam = isStatic && startPosition ? '#t=' + (startPosition / 10000000) : '';
|
||||||
|
|
||||||
var mp4VideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.mp4', $.extend({}, baseParams, {
|
var mp4VideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.mp4', $.extend({}, baseParams, {
|
||||||
VideoCodec: qualityOption.mp4VideoCodec,
|
|
||||||
AudioCodec: qualityOption.mp4AudioCodec,
|
|
||||||
profile: 'baseline',
|
profile: 'baseline',
|
||||||
level: 3,
|
level: 3,
|
||||||
Static: staticMp4
|
Static: isStatic,
|
||||||
}));
|
maxWidth: mp4Quality.maxWidth,
|
||||||
|
videoBitrate: mp4Quality.videoBitrate,
|
||||||
|
audioBitrate: mp4Quality.audioBitrate,
|
||||||
|
VideoCodec: mp4Quality.videoCodec,
|
||||||
|
AudioCodec: mp4Quality.audioCodec
|
||||||
|
|
||||||
|
})) + seekParam;
|
||||||
|
|
||||||
var webmVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.webm', $.extend({}, baseParams, {
|
var webmVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.webm', $.extend({}, baseParams, {
|
||||||
|
|
||||||
VideoCodec: 'vpx',
|
VideoCodec: 'vpx',
|
||||||
AudioCodec: 'Vorbis'
|
AudioCodec: 'Vorbis',
|
||||||
}));
|
maxWidth: webmQuality.maxWidth,
|
||||||
|
videoBitrate: webmQuality.videoBitrate,
|
||||||
|
audioBitrate: webmQuality.audioBitrate
|
||||||
|
|
||||||
|
})) + seekParam;
|
||||||
|
|
||||||
var hlsVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.m3u8', $.extend({}, baseParams, {
|
var hlsVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.m3u8', $.extend({}, baseParams, {
|
||||||
VideoCodec: qualityOption.mp4VideoCodec,
|
|
||||||
AudioCodec: qualityOption.mp4AudioCodec,
|
|
||||||
profile: 'baseline',
|
profile: 'baseline',
|
||||||
level: 3,
|
level: 3,
|
||||||
timeStampOffsetMs: 0
|
timeStampOffsetMs: 0,
|
||||||
}));
|
maxWidth: m3U8Quality.maxWidth,
|
||||||
|
videoBitrate: m3U8Quality.videoBitrate,
|
||||||
|
audioBitrate: m3U8Quality.audioBitrate,
|
||||||
|
VideoCodec: m3U8Quality.videoCodec,
|
||||||
|
AudioCodec: m3U8Quality.audioCodec
|
||||||
|
|
||||||
|
})) + seekParam;
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
|
@ -748,19 +786,19 @@
|
||||||
html += '<video class="itemVideo" autoplay preload="none">';
|
html += '<video class="itemVideo" autoplay preload="none">';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!staticMp4) {
|
if (!isStatic) {
|
||||||
// HLS must be at the top for safari
|
// HLS must be at the top for safari
|
||||||
html += '<source type="application/x-mpegURL" src="' + hlsVideoUrl + '" />';
|
html += '<source type="application/x-mpegURL" src="' + hlsVideoUrl + '" />';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prioritizeWebmOverH264 && !staticMp4) {
|
if (prioritizeWebmOverH264 && !isStatic) {
|
||||||
|
|
||||||
html += '<source type="video/webm" src="' + webmVideoUrl + '" />';
|
html += '<source type="video/webm" src="' + webmVideoUrl + '" />';
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '<source type="video/mp4" src="' + mp4VideoUrl + '" />';
|
html += '<source type="video/mp4" src="' + mp4VideoUrl + '" />';
|
||||||
|
|
||||||
if (!prioritizeWebmOverH264 && !staticMp4) {
|
if (!prioritizeWebmOverH264 && !isStatic) {
|
||||||
|
|
||||||
html += '<source type="video/webm" src="' + webmVideoUrl + '" />';
|
html += '<source type="video/webm" src="' + webmVideoUrl + '" />';
|
||||||
}
|
}
|
||||||
|
@ -830,15 +868,10 @@
|
||||||
|
|
||||||
}).on("play.once", function () {
|
}).on("play.once", function () {
|
||||||
|
|
||||||
var duration = this.duration;
|
updateCanClientSeek(this);
|
||||||
isStaticStream = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY;
|
|
||||||
|
|
||||||
videoElement.off("play.once");
|
videoElement.off("play.once");
|
||||||
|
|
||||||
if (startPosition && staticMp4) {
|
|
||||||
self.seek(startPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), item.Id, true, item.MediaType);
|
ApiClient.reportPlaybackStart(Dashboard.getCurrentUserId(), item.Id, true, item.MediaType);
|
||||||
|
|
||||||
startProgressInterval(item.Id);
|
startProgressInterval(item.Id);
|
||||||
|
@ -993,26 +1026,12 @@
|
||||||
|
|
||||||
self.canPlayMediaType = function (mediaType) {
|
self.canPlayMediaType = function (mediaType) {
|
||||||
|
|
||||||
var media;
|
|
||||||
|
|
||||||
if (mediaType === "Video") {
|
if (mediaType === "Video") {
|
||||||
media = testableVideoElement;
|
return true;
|
||||||
if (media.canPlayType) {
|
|
||||||
|
|
||||||
return media.canPlayType('video/mp4').replace(/no/, '') || media.canPlayType('video/mp2t').replace(/no/, '') || media.canPlayType('video/webm').replace(/no/, '') || media.canPlayType('application/x-mpegURL').replace(/no/, '') || media.canPlayType('video/ogv').replace(/no/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaType === "Audio") {
|
if (mediaType === "Audio") {
|
||||||
media = testableAudioElement;
|
return true;
|
||||||
if (media.canPlayType) {
|
|
||||||
|
|
||||||
return media.canPlayType('audio/mpeg').replace(/no/, '') || media.canPlayType('audio/webm').replace(/no/, '') || media.canPlayType('audio/aac').replace(/no/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1116,13 +1135,11 @@
|
||||||
mediaElement = playVideo(item, startPosition, user);
|
mediaElement = playVideo(item, startPosition, user);
|
||||||
} else if (item.MediaType === "Audio") {
|
} else if (item.MediaType === "Audio") {
|
||||||
|
|
||||||
mediaElement = playAudio(item);
|
mediaElement = playAudio(item, startPosition);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unrecognized media type");
|
throw new Error("Unrecognized media type");
|
||||||
}
|
}
|
||||||
|
|
||||||
startTimeTicksOffset = startPosition || 0;
|
|
||||||
|
|
||||||
currentMediaElement = mediaElement;
|
currentMediaElement = mediaElement;
|
||||||
|
|
||||||
var nowPlayingBar = $('#nowPlayingBar').show();
|
var nowPlayingBar = $('#nowPlayingBar').show();
|
||||||
|
@ -1834,9 +1851,26 @@
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
|
var currentSrc = currentMediaElement.currentSrc.toLowerCase();
|
||||||
|
var isStatic = currentSrc.indexOf('static=true') != -1;
|
||||||
|
|
||||||
|
var transcodingExtension = isStatic ? getTranscodingExtension() : null;
|
||||||
|
|
||||||
|
if (!transcodingExtension) {
|
||||||
|
if (currentSrc.indexOf('.m3u8') != -1) {
|
||||||
|
transcodingExtension = '.m3u8';
|
||||||
|
}
|
||||||
|
else if (currentSrc.indexOf('.webm') != -1) {
|
||||||
|
transcodingExtension = '.webm';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
transcodingExtension = '.mp4';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var currentAudioStreamIndex = getParameterByName('AudioStreamIndex', currentMediaElement.currentSrc);
|
var currentAudioStreamIndex = getParameterByName('AudioStreamIndex', currentMediaElement.currentSrc);
|
||||||
|
|
||||||
var options = getVideoQualityOptions(item, currentAudioStreamIndex);
|
var options = getVideoQualityOptions(item, currentAudioStreamIndex, transcodingExtension);
|
||||||
|
|
||||||
for (var i = 0, length = options.length; i < length; i++) {
|
for (var i = 0, length = options.length; i < length; i++) {
|
||||||
|
|
||||||
|
@ -1848,7 +1882,7 @@
|
||||||
cssClass += " selectedMediaFlyoutOption";
|
cssClass += " selectedMediaFlyoutOption";
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '<div data-static="' + option.isStatic + '" data-mp4video="' + option.mp4VideoCodec + '" data-mp4audio="' + option.mp4AudioCodec + '" data-maxwidth="' + option.maxWidth + '" data-videobitrate="' + option.videoBitrate + '" data-audiobitrate="' + option.audioBitrate + '" class="' + cssClass + '">';
|
html += '<div data-static="' + option.isStatic + '" data-videocodec="' + option.videoCodec + '" data-audiocodec="' + option.audioCodec + '" data-maxwidth="' + option.maxWidth + '" data-videobitrate="' + option.videoBitrate + '" data-audiobitrate="' + option.audioBitrate + '" class="' + cssClass + '">';
|
||||||
|
|
||||||
html += '<div class="mediaFlyoutOptionContent">';
|
html += '<div class="mediaFlyoutOptionContent">';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.219" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.223" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Add table
Add a link
Reference in a new issue