mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'jellyfin:master' into audio-normalization
This commit is contained in:
commit
993d6d81a9
71 changed files with 4475 additions and 1428 deletions
|
@ -366,6 +366,10 @@ import template from './libraryoptionseditor.template.html';
|
|||
parent.querySelector('.subtitleFetchers').addEventListener('click', onSortableContainerClick);
|
||||
parent.querySelector('.metadataFetchers').addEventListener('click', onSortableContainerClick);
|
||||
parent.querySelector('.imageFetchers').addEventListener('click', onImageFetchersContainerClick);
|
||||
|
||||
parent.querySelector('#chkEnableEmbeddedTitles').addEventListener('change', (e) => {
|
||||
parent.querySelector('.chkEnableEmbeddedExtrasTitlesContainer').classList.toggle('hide', !e.currentTarget.checked);
|
||||
});
|
||||
}
|
||||
|
||||
export async function embed(parent, contentType, libraryOptions) {
|
||||
|
@ -412,8 +416,12 @@ import template from './libraryoptionseditor.template.html';
|
|||
|
||||
if (contentType === 'books' || contentType === 'boxsets' || contentType === 'playlists' || contentType === 'music') {
|
||||
parent.querySelector('.chkEnableEmbeddedTitlesContainer').classList.add('hide');
|
||||
parent.querySelector('.chkEnableEmbeddedExtrasTitlesContainer').classList.add('hide');
|
||||
} else {
|
||||
parent.querySelector('.chkEnableEmbeddedTitlesContainer').classList.remove('hide');
|
||||
if (parent.querySelector('#chkEnableEmbeddedTitles').checked) {
|
||||
parent.querySelector('.chkEnableEmbeddedExtrasTitlesContainer').classList.remove('hide');
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType === 'tvshows') {
|
||||
|
@ -525,6 +533,7 @@ import template from './libraryoptionseditor.template.html';
|
|||
SeasonZeroDisplayName: parent.querySelector('#txtSeasonZeroName').value,
|
||||
AutomaticRefreshIntervalDays: parseInt(parent.querySelector('#selectAutoRefreshInterval').value),
|
||||
EnableEmbeddedTitles: parent.querySelector('#chkEnableEmbeddedTitles').checked,
|
||||
EnableEmbeddedExtrasTitles: parent.querySelector('#chkEnableEmbeddedExtrasTitles').checked,
|
||||
EnableEmbeddedEpisodeInfos: parent.querySelector('#chkEnableEmbeddedEpisodeInfos').checked,
|
||||
AllowEmbeddedSubtitles: parent.querySelector('#selectAllowEmbeddedSubtitles').value,
|
||||
SkipSubtitlesIfEmbeddedSubtitlesPresent: parent.querySelector('#chkSkipIfGraphicalSubsPresent').checked,
|
||||
|
@ -580,6 +589,8 @@ import template from './libraryoptionseditor.template.html';
|
|||
parent.querySelector('#chkSaveLocal').checked = options.SaveLocalMetadata;
|
||||
parent.querySelector('.chkAutomaticallyGroupSeries').checked = options.EnableAutomaticSeriesGrouping;
|
||||
parent.querySelector('#chkEnableEmbeddedTitles').checked = options.EnableEmbeddedTitles;
|
||||
parent.querySelector('.chkEnableEmbeddedExtrasTitlesContainer').classList.toggle('hide', !options.EnableEmbeddedTitles);
|
||||
parent.querySelector('#chkEnableEmbeddedExtrasTitles').checked = options.EnableEmbeddedExtrasTitles;
|
||||
parent.querySelector('#chkEnableEmbeddedEpisodeInfos').value = options.EnableEmbeddedEpisodeInfos;
|
||||
parent.querySelector('#selectAllowEmbeddedSubtitles').value = options.AllowEmbeddedSubtitles;
|
||||
parent.querySelector('#chkSkipIfGraphicalSubsPresent').checked = options.SkipSubtitlesIfEmbeddedSubtitlesPresent;
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${PreferEmbeddedTitlesOverFileNamesHelp}</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription chkEnableEmbeddedExtrasTitlesContainer hide advanced">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEnableEmbeddedExtrasTitles" />
|
||||
<span>${PreferEmbeddedExtrasTitlesOverFileNames}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${PreferEmbeddedExtrasTitlesOverFileNamesHelp}</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription chkEnableEmbeddedEpisodeInfosContainer hide advanced">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEnableEmbeddedEpisodeInfos" />
|
||||
|
|
|
@ -261,6 +261,10 @@ import ServerConnections from '../ServerConnections';
|
|||
const imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
|
||||
let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
|
||||
|
||||
if (options.imageSource === 'channel') {
|
||||
imageClass += ' listItemImage-channel';
|
||||
}
|
||||
|
||||
if (isLargeStyle && layoutManager.tv) {
|
||||
imageClass += ' listItemImage-large-tv';
|
||||
}
|
||||
|
@ -428,6 +432,7 @@ import ServerConnections from '../ServerConnections';
|
|||
container: false,
|
||||
episodeTitle: false,
|
||||
criticRating: false,
|
||||
officialRating: false,
|
||||
endsAt: false
|
||||
|
||||
});
|
||||
|
|
|
@ -153,6 +153,10 @@
|
|||
margin-right: 0.75em;
|
||||
}
|
||||
|
||||
.listItemImage-channel {
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.listItemImageButton {
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
|
@ -316,3 +320,13 @@
|
|||
.listItemCheckboxContainer {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.listItemMediaInfo + .timerIndicator {
|
||||
[dir="ltr"] & {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'material-design-icons-iconfont';
|
|||
import './mediainfo.scss';
|
||||
import '../guide/programs.scss';
|
||||
import '../../elements/emby-button/emby-button';
|
||||
import * as userSettings from '../../scripts/settings/userSettings';
|
||||
|
||||
/* eslint-disable indent */
|
||||
function getTimerIndicator(item) {
|
||||
|
@ -158,7 +159,7 @@ import '../../elements/emby-button/emby-button';
|
|||
}
|
||||
}
|
||||
|
||||
if (item.StartDate && item.Type !== 'Program' && item.Type !== 'SeriesTimer') {
|
||||
if (item.StartDate && item.Type !== 'Program' && item.Type !== 'SeriesTimer' && item.Type !== 'Timer') {
|
||||
try {
|
||||
date = datetime.parseISO8601Date(item.StartDate);
|
||||
|
||||
|
@ -196,47 +197,52 @@ import '../../elements/emby-button/emby-button';
|
|||
}
|
||||
}
|
||||
|
||||
if (item.Type === 'Program') {
|
||||
if (item.Type === 'Program' || item.Type === 'Timer') {
|
||||
let program = item;
|
||||
if (item.Type === 'Timer') {
|
||||
program = item.ProgramInfo;
|
||||
}
|
||||
|
||||
if (options.programIndicator !== false) {
|
||||
if (item.IsLive) {
|
||||
if (program.IsLive && userSettings.get('guide-indicator-live') === 'true') {
|
||||
miscInfo.push({
|
||||
html: `<div class="mediaInfoProgramAttribute mediaInfoItem liveTvProgram">${globalize.translate('Live')}</div>`
|
||||
});
|
||||
} else if (item.IsPremiere) {
|
||||
} else if (program.IsPremiere && userSettings.get('guide-indicator-premiere') === 'true') {
|
||||
miscInfo.push({
|
||||
html: `<div class="mediaInfoProgramAttribute mediaInfoItem premiereTvProgram">${globalize.translate('Premiere')}</div>`
|
||||
});
|
||||
} else if (item.IsSeries && !item.IsRepeat) {
|
||||
} else if (program.IsSeries && !program.IsRepeat && userSettings.get('guide-indicator-new') === 'true') {
|
||||
miscInfo.push({
|
||||
html: `<div class="mediaInfoProgramAttribute mediaInfoItem newTvProgram">${globalize.translate('New')}</div>`
|
||||
});
|
||||
} else if (item.IsSeries && item.IsRepeat) {
|
||||
} else if (program.IsSeries && program.IsRepeat && userSettings.get('guide-indicator-repeat') === 'true') {
|
||||
miscInfo.push({
|
||||
html: `<div class="mediaInfoProgramAttribute mediaInfoItem repeatTvProgram">${globalize.translate('Repeat')}</div>`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ((item.IsSeries || item.EpisodeTitle) && options.episodeTitle !== false) {
|
||||
text = itemHelper.getDisplayName(item, {
|
||||
if ((program.IsSeries || program.EpisodeTitle) && options.episodeTitle !== false) {
|
||||
text = itemHelper.getDisplayName(program, {
|
||||
includeIndexNumber: options.episodeTitleIndexNumber
|
||||
});
|
||||
|
||||
if (text) {
|
||||
miscInfo.push(escapeHtml(text));
|
||||
}
|
||||
} else if (item.IsMovie && item.ProductionYear && options.originalAirDate !== false) {
|
||||
miscInfo.push(item.ProductionYear);
|
||||
} else if (item.PremiereDate && options.originalAirDate !== false) {
|
||||
} else if (program.IsMovie && program.ProductionYear && options.originalAirDate !== false) {
|
||||
miscInfo.push(program.ProductionYear);
|
||||
} else if (program.PremiereDate && options.originalAirDate !== false) {
|
||||
try {
|
||||
date = datetime.parseISO8601Date(item.PremiereDate);
|
||||
date = datetime.parseISO8601Date(program.PremiereDate);
|
||||
text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date));
|
||||
miscInfo.push(text);
|
||||
} catch (e) {
|
||||
console.error('error parsing date:', item.PremiereDate);
|
||||
console.error('error parsing date:', program.PremiereDate);
|
||||
}
|
||||
} else if (item.ProductionYear) {
|
||||
miscInfo.push(item.ProductionYear);
|
||||
} else if (program.ProductionYear && options.year !== false ) {
|
||||
miscInfo.push(program.ProductionYear);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +261,7 @@ import '../../elements/emby-button/emby-button';
|
|||
}
|
||||
}
|
||||
|
||||
if (item.RunTimeTicks && item.Type !== 'Series' && item.Type !== 'Program' && item.Type !== 'Book' && !showFolderRuntime && options.runtime !== false) {
|
||||
if (item.RunTimeTicks && item.Type !== 'Series' && item.Type !== 'Program' && item.Type !== 'Timer' && item.Type !== 'Book' && !showFolderRuntime && options.runtime !== false) {
|
||||
if (item.Type === 'Audio') {
|
||||
miscInfo.push(datetime.getDisplayRunningTime(item.RunTimeTicks));
|
||||
} else {
|
||||
|
@ -263,7 +269,7 @@ import '../../elements/emby-button/emby-button';
|
|||
}
|
||||
}
|
||||
|
||||
if (item.OfficialRating && item.Type !== 'Season' && item.Type !== 'Episode') {
|
||||
if (options.officialRating !== false && item.OfficialRating && item.Type !== 'Season' && item.Type !== 'Episode') {
|
||||
miscInfo.push({
|
||||
text: item.OfficialRating,
|
||||
cssClass: 'mediaInfoOfficialRating'
|
||||
|
|
|
@ -422,7 +422,8 @@ function getPlaybackInfo(player,
|
|||
enableDirectPlay,
|
||||
enableDirectStream,
|
||||
allowVideoStreamCopy,
|
||||
allowAudioStreamCopy) {
|
||||
allowAudioStreamCopy,
|
||||
secondarySubtitleStreamIndex) {
|
||||
if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio' && !player.useServerPlaybackInfoForAudio) {
|
||||
return Promise.resolve({
|
||||
MediaSources: [
|
||||
|
@ -462,6 +463,9 @@ function getPlaybackInfo(player,
|
|||
if (subtitleStreamIndex != null) {
|
||||
query.SubtitleStreamIndex = subtitleStreamIndex;
|
||||
}
|
||||
if (secondarySubtitleStreamIndex != null) {
|
||||
query.SecondarySubtitleStreamIndex = secondarySubtitleStreamIndex;
|
||||
}
|
||||
if (enableDirectPlay != null) {
|
||||
query.EnableDirectPlay = enableDirectPlay;
|
||||
}
|
||||
|
@ -876,25 +880,49 @@ class PlaybackManager {
|
|||
});
|
||||
};
|
||||
|
||||
function getCurrentSubtitleStream(player) {
|
||||
self.playerHasSecondarySubtitleSupport = function (player = self._currentPlayer) {
|
||||
if (!player) return false;
|
||||
return Boolean(player.supports('SecondarySubtitles'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if:
|
||||
* - the track can be used directly as a secondary subtitle
|
||||
* - or if it can be paired with a secondary subtitle when used as a primary subtitle
|
||||
*/
|
||||
self.trackHasSecondarySubtitleSupport = function (track, player = self._currentPlayer) {
|
||||
if (!player || !track) return false;
|
||||
const format = (track.Codec || '').toLowerCase();
|
||||
// Currently, only non-SSA/non-ASS external subtitles are supported.
|
||||
// Showing secondary subtitles does not work with any SSA/ASS subtitle combinations because
|
||||
// of the complexity of how they are rendered and the risk of the subtitles overlapping
|
||||
return format !== 'ssa' && format !== 'ass' && getDeliveryMethod(track) === 'External';
|
||||
};
|
||||
|
||||
self.secondarySubtitleTracks = function (player = self._currentPlayer) {
|
||||
const streams = self.subtitleTracks(player);
|
||||
return streams.filter((stream) => self.trackHasSecondarySubtitleSupport(stream, player));
|
||||
};
|
||||
|
||||
function getCurrentSubtitleStream(player, isSecondaryStream = false) {
|
||||
if (!player) {
|
||||
throw new Error('player cannot be null');
|
||||
}
|
||||
|
||||
const index = getPlayerData(player).subtitleStreamIndex;
|
||||
const index = isSecondaryStream ? getPlayerData(player).secondarySubtitleStreamIndex : getPlayerData(player).subtitleStreamIndex;
|
||||
|
||||
if (index == null || index === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getSubtitleStream(player, index);
|
||||
return self.getSubtitleStream(player, index);
|
||||
}
|
||||
|
||||
function getSubtitleStream(player, index) {
|
||||
self.getSubtitleStream = function (player, index) {
|
||||
return self.subtitleTracks(player).filter(function (s) {
|
||||
return s.Type === 'Subtitle' && s.Index === index;
|
||||
})[0];
|
||||
}
|
||||
};
|
||||
|
||||
self.getPlaylist = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
|
@ -1463,6 +1491,24 @@ class PlaybackManager {
|
|||
return getPlayerData(player).subtitleStreamIndex;
|
||||
};
|
||||
|
||||
self.getSecondarySubtitleStreamIndex = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
|
||||
if (!player) {
|
||||
throw new Error('player cannot be null');
|
||||
}
|
||||
|
||||
try {
|
||||
if (!enableLocalPlaylistManagement(player)) {
|
||||
return player.getSecondarySubtitleStreamIndex();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[playbackmanager] Failed to get secondary stream index:', e);
|
||||
}
|
||||
|
||||
return getPlayerData(player).secondarySubtitleStreamIndex;
|
||||
};
|
||||
|
||||
function getDeliveryMethod(subtitleStream) {
|
||||
// This will be null for internal subs for local items
|
||||
if (subtitleStream.DeliveryMethod) {
|
||||
|
@ -1480,7 +1526,7 @@ class PlaybackManager {
|
|||
|
||||
const currentStream = getCurrentSubtitleStream(player);
|
||||
|
||||
const newStream = getSubtitleStream(player, index);
|
||||
const newStream = self.getSubtitleStream(player, index);
|
||||
|
||||
if (!currentStream && !newStream) {
|
||||
return;
|
||||
|
@ -1522,9 +1568,48 @@ class PlaybackManager {
|
|||
|
||||
player.setSubtitleStreamIndex(selectedTrackElementIndex);
|
||||
|
||||
// Also disable secondary subtitles when disabling the primary
|
||||
// subtitles, or if it doesn't support a secondary pair
|
||||
if (selectedTrackElementIndex === -1 || !self.trackHasSecondarySubtitleSupport(newStream)) {
|
||||
self.setSecondarySubtitleStreamIndex(-1);
|
||||
}
|
||||
|
||||
getPlayerData(player).subtitleStreamIndex = index;
|
||||
};
|
||||
|
||||
self.setSecondarySubtitleStreamIndex = function (index, player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (!self.playerHasSecondarySubtitleSupport(player)) return;
|
||||
if (player && !enableLocalPlaylistManagement(player)) {
|
||||
try {
|
||||
return player.setSecondarySubtitleStreamIndex(index);
|
||||
} catch (e) {
|
||||
console.error('[playbackmanager] AutoSet - Failed to set secondary track:', e);
|
||||
}
|
||||
}
|
||||
|
||||
const currentStream = getCurrentSubtitleStream(player, true);
|
||||
|
||||
const newStream = self.getSubtitleStream(player, index);
|
||||
|
||||
if (!currentStream && !newStream) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Secondary subtitles are currently only handled client side
|
||||
// Changes to the server code are required before we can handle other delivery methods
|
||||
if (newStream && !self.trackHasSecondarySubtitleSupport(newStream, player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
player.setSecondarySubtitleStreamIndex(index);
|
||||
getPlayerData(player).secondarySubtitleStreamIndex = index;
|
||||
} catch (e) {
|
||||
console.error('[playbackmanager] AutoSet - Failed to set secondary track:', e);
|
||||
}
|
||||
};
|
||||
|
||||
self.supportSubtitleOffset = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
return player && 'setSubtitleOffset' in player;
|
||||
|
@ -1548,7 +1633,7 @@ class PlaybackManager {
|
|||
};
|
||||
|
||||
self.isSubtitleStreamExternal = function (index, player) {
|
||||
const stream = getSubtitleStream(player, index);
|
||||
const stream = self.getSubtitleStream(player, index);
|
||||
return stream ? getDeliveryMethod(stream) === 'External' : false;
|
||||
};
|
||||
|
||||
|
@ -1639,6 +1724,7 @@ class PlaybackManager {
|
|||
}).then(function (deviceProfile) {
|
||||
const audioStreamIndex = params.AudioStreamIndex == null ? getPlayerData(player).audioStreamIndex : params.AudioStreamIndex;
|
||||
const subtitleStreamIndex = params.SubtitleStreamIndex == null ? getPlayerData(player).subtitleStreamIndex : params.SubtitleStreamIndex;
|
||||
const secondarySubtitleStreamIndex = params.SecondarySubtitleStreamIndex == null ? getPlayerData(player).secondarySubtitleStreamIndex : params.SecondarySubtitleStreamIndex;
|
||||
|
||||
let currentMediaSource = self.currentMediaSource(player);
|
||||
const apiClient = ServerConnections.getApiClient(currentItem.ServerId);
|
||||
|
@ -1665,6 +1751,7 @@ class PlaybackManager {
|
|||
}
|
||||
|
||||
getPlayerData(player).subtitleStreamIndex = subtitleStreamIndex;
|
||||
getPlayerData(player).secondarySubtitleStreamIndex = secondarySubtitleStreamIndex;
|
||||
getPlayerData(player).audioStreamIndex = audioStreamIndex;
|
||||
getPlayerData(player).maxStreamingBitrate = maxBitrate;
|
||||
|
||||
|
@ -1950,6 +2037,7 @@ class PlaybackManager {
|
|||
state.PlayState.PlaybackRate = self.getPlaybackRate(player);
|
||||
|
||||
state.PlayState.SubtitleStreamIndex = self.getSubtitleStreamIndex(player);
|
||||
state.PlayState.SecondarySubtitleStreamIndex = self.getSecondarySubtitleStreamIndex(player);
|
||||
state.PlayState.AudioStreamIndex = self.getAudioStreamIndex(player);
|
||||
state.PlayState.BufferedRanges = self.getBufferedRanges(player);
|
||||
|
||||
|
@ -2230,11 +2318,16 @@ class PlaybackManager {
|
|||
});
|
||||
}
|
||||
|
||||
function rankStreamType(prevIndex, prevSource, mediaSource, streamType) {
|
||||
function rankStreamType(prevIndex, prevSource, mediaSource, streamType, isSecondarySubtitle) {
|
||||
if (prevIndex == -1) {
|
||||
console.debug(`AutoSet ${streamType} - No Stream Set`);
|
||||
if (streamType == 'Subtitle')
|
||||
mediaSource.DefaultSubtitleStreamIndex = -1;
|
||||
if (streamType == 'Subtitle') {
|
||||
if (isSecondarySubtitle) {
|
||||
mediaSource.DefaultSecondarySubtitleStreamIndex = -1;
|
||||
} else {
|
||||
mediaSource.DefaultSubtitleStreamIndex = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2292,8 +2385,13 @@ class PlaybackManager {
|
|||
|
||||
if (bestStreamIndex != null) {
|
||||
console.debug(`AutoSet ${streamType} - Using ${bestStreamIndex} score ${bestStreamScore}.`);
|
||||
if (streamType == 'Subtitle')
|
||||
mediaSource.DefaultSubtitleStreamIndex = bestStreamIndex;
|
||||
if (streamType == 'Subtitle') {
|
||||
if (isSecondarySubtitle) {
|
||||
mediaSource.DefaultSecondarySubtitleStreamIndex = bestStreamIndex;
|
||||
} else {
|
||||
mediaSource.DefaultSubtitleStreamIndex = bestStreamIndex;
|
||||
}
|
||||
}
|
||||
if (streamType == 'Audio')
|
||||
mediaSource.DefaultAudioStreamIndex = bestStreamIndex;
|
||||
} else {
|
||||
|
@ -2317,6 +2415,10 @@ class PlaybackManager {
|
|||
if (subtitle && typeof prevSource.DefaultSubtitleStreamIndex == 'number') {
|
||||
rankStreamType(prevSource.DefaultSubtitleStreamIndex, prevSource, mediaSource, 'Subtitle');
|
||||
}
|
||||
|
||||
if (subtitle && typeof prevSource.DefaultSecondarySubtitleStreamIndex == 'number') {
|
||||
rankStreamType(prevSource.DefaultSecondarySubtitleStreamIndex, prevSource, mediaSource, 'Subtitle', true);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`AutoSet - Caught unexpected error: ${e}`);
|
||||
}
|
||||
|
@ -2384,6 +2486,19 @@ class PlaybackManager {
|
|||
const user = await apiClient.getCurrentUser();
|
||||
autoSetNextTracks(prevSource, mediaSource, user.Configuration.RememberAudioSelections, user.Configuration.RememberSubtitleSelections);
|
||||
|
||||
if (mediaSource.DefaultSubtitleStreamIndex == null || mediaSource.DefaultSubtitleStreamIndex < 0) {
|
||||
mediaSource.DefaultSubtitleStreamIndex = mediaSource.DefaultSecondarySubtitleStreamIndex;
|
||||
mediaSource.DefaultSecondarySubtitleStreamIndex = -1;
|
||||
}
|
||||
|
||||
const subtitleTrack1 = mediaSource.MediaStreams[mediaSource.DefaultSubtitleStreamIndex];
|
||||
const subtitleTrack2 = mediaSource.MediaStreams[mediaSource.DefaultSecondarySubtitleStreamIndex];
|
||||
|
||||
if (!self.trackHasSecondarySubtitleSupport(subtitleTrack1, player)
|
||||
|| !self.trackHasSecondarySubtitleSupport(subtitleTrack2, player)) {
|
||||
mediaSource.DefaultSecondarySubtitleStreamIndex = -1;
|
||||
}
|
||||
|
||||
const streamInfo = createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition, player);
|
||||
|
||||
streamInfo.fullscreen = playOptions.fullscreen;
|
||||
|
@ -2751,7 +2866,8 @@ class PlaybackManager {
|
|||
return {
|
||||
...prevSource,
|
||||
DefaultAudioStreamIndex: prevPlayerData.audioStreamIndex,
|
||||
DefaultSubtitleStreamIndex: prevPlayerData.subtitleStreamIndex
|
||||
DefaultSubtitleStreamIndex: prevPlayerData.subtitleStreamIndex,
|
||||
DefaultSecondarySubtitleStreamIndex: prevPlayerData.secondarySubtitleStreamIndex
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2910,9 +3026,11 @@ class PlaybackManager {
|
|||
if (mediaSource) {
|
||||
playerData.audioStreamIndex = mediaSource.DefaultAudioStreamIndex;
|
||||
playerData.subtitleStreamIndex = mediaSource.DefaultSubtitleStreamIndex;
|
||||
playerData.secondarySubtitleStreamIndex = mediaSource.DefaultSecondarySubtitleStreamIndex;
|
||||
} else {
|
||||
playerData.audioStreamIndex = null;
|
||||
playerData.subtitleStreamIndex = null;
|
||||
playerData.secondarySubtitleStreamIndex = null;
|
||||
}
|
||||
|
||||
self._playNextAfterEnded = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue