Add subtitle/audio auto-set feature.
This commit is contained in:
parent
1794ab53fe
commit
d8e7e14da0
5 changed files with 118 additions and 6 deletions
|
@ -2106,7 +2106,7 @@ class PlaybackManager {
|
|||
}
|
||||
}
|
||||
|
||||
function playInternal(item, playOptions, onPlaybackStartedFn) {
|
||||
function playInternal(item, playOptions, onPlaybackStartedFn, prevSource) {
|
||||
if (item.IsPlaceHolder) {
|
||||
loading.hide();
|
||||
showPlaybackInfoErrorMessage(self, 'PlaybackErrorPlaceHolder');
|
||||
|
@ -2131,7 +2131,7 @@ class PlaybackManager {
|
|||
const mediaType = item.MediaType;
|
||||
|
||||
const onBitrateDetectionFailure = function () {
|
||||
return playAfterBitrateDetect(getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType), item, playOptions, onPlaybackStartedFn);
|
||||
return playAfterBitrateDetect(getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType), item, playOptions, onPlaybackStartedFn, prevSource);
|
||||
};
|
||||
|
||||
if (!isServerItem(item) || itemHelper.isLocalItem(item)) {
|
||||
|
@ -2144,7 +2144,7 @@ class PlaybackManager {
|
|||
return apiClient.detectBitrate().then(function (bitrate) {
|
||||
appSettings.maxStreamingBitrate(endpointInfo.IsInNetwork, mediaType, bitrate);
|
||||
|
||||
return playAfterBitrateDetect(bitrate, item, playOptions, onPlaybackStartedFn);
|
||||
return playAfterBitrateDetect(bitrate, item, playOptions, onPlaybackStartedFn, prevSource);
|
||||
}, onBitrateDetectionFailure);
|
||||
} else {
|
||||
onBitrateDetectionFailure();
|
||||
|
@ -2222,7 +2222,80 @@ class PlaybackManager {
|
|||
});
|
||||
}
|
||||
|
||||
function playAfterBitrateDetect(maxBitrate, item, playOptions, onPlaybackStartedFn) {
|
||||
function rankStreamType(prevIndex, prevSource, mediaSource, streamType) {
|
||||
if (prevIndex == -1) {
|
||||
console.debug(`AutoSet ${streamType} - No Stream Set`);
|
||||
if (streamType == 'Subtitle')
|
||||
mediaSource.DefaultSubtitleStreamIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
let bestStreamIndex = null;
|
||||
let bestStreamScore = 0;
|
||||
const prevStream = prevSource.MediaStreams[prevIndex];
|
||||
|
||||
console.debug(`AutoSet ${streamType} - Previous was ${prevStream.Index} - ${prevStream.DisplayTitle}`);
|
||||
|
||||
let prevRelIndex = 0;
|
||||
for (const stream of prevSource.MediaStreams) {
|
||||
if (stream.Type != streamType)
|
||||
continue;
|
||||
|
||||
if (stream.Index == prevIndex)
|
||||
break;
|
||||
|
||||
prevRelIndex += 1;
|
||||
}
|
||||
|
||||
let newRelIndex = 0;
|
||||
for (const stream of mediaSource.MediaStreams) {
|
||||
if (stream.Type != streamType)
|
||||
continue;
|
||||
|
||||
let score = 0;
|
||||
|
||||
if (prevStream.Codec == stream.Codec)
|
||||
score += 1;
|
||||
if (prevRelIndex == newRelIndex)
|
||||
score += 1;
|
||||
if (prevStream.Title && prevStream.Title == stream.Title)
|
||||
score += 2;
|
||||
if (prevStream.Language && prevStream.Language != 'und' && prevStream.Language == stream.Language)
|
||||
score += 2;
|
||||
|
||||
console.debug(`AutoSet ${streamType} - Score ${score} for ${stream.Index} - ${stream.DisplayTitle}`);
|
||||
if (score > bestStreamScore && score >= 3) {
|
||||
bestStreamScore = score;
|
||||
bestStreamIndex = stream.Index;
|
||||
}
|
||||
|
||||
newRelIndex += 1;
|
||||
}
|
||||
|
||||
if (bestStreamIndex != null) {
|
||||
console.debug(`AutoSet ${streamType} - Using ${bestStreamIndex} score ${bestStreamScore}.`);
|
||||
if (streamType == 'Subtitle')
|
||||
mediaSource.DefaultSubtitleStreamIndex = bestStreamIndex;
|
||||
if (streamType == 'Audio')
|
||||
mediaSource.DefaultAudioStreamIndex = bestStreamIndex;
|
||||
} else {
|
||||
console.debug(`AutoSet ${streamType} - Threshold not met. Using default.`);
|
||||
}
|
||||
}
|
||||
|
||||
function autoSetNextTracks(prevSource, mediaSource) {
|
||||
if (!prevSource
|
||||
|| typeof prevSource.DefaultAudioStreamIndex != 'number'
|
||||
|| typeof mediaSource.DefaultAudioStreamIndex != 'number'
|
||||
|| typeof prevSource.DefaultSubtitleStreamIndex != 'number'
|
||||
|| typeof mediaSource.DefaultSubtitleStreamIndex != 'number')
|
||||
return;
|
||||
|
||||
rankStreamType(prevSource.DefaultAudioStreamIndex, prevSource, mediaSource, 'Audio');
|
||||
rankStreamType(prevSource.DefaultSubtitleStreamIndex, prevSource, mediaSource, 'Subtitle');
|
||||
}
|
||||
|
||||
function playAfterBitrateDetect(maxBitrate, item, playOptions, onPlaybackStartedFn, prevSource) {
|
||||
const startPosition = playOptions.startPositionTicks;
|
||||
|
||||
const player = getPlayer(item, playOptions);
|
||||
|
@ -2272,6 +2345,9 @@ class PlaybackManager {
|
|||
playOptions.items = null;
|
||||
|
||||
return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex).then(function (mediaSource) {
|
||||
if (userSettings.enableSetUsingLastTracks())
|
||||
autoSetNextTracks(prevSource, mediaSource);
|
||||
|
||||
const streamInfo = createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition);
|
||||
|
||||
streamInfo.fullscreen = playOptions.fullscreen;
|
||||
|
@ -2622,6 +2698,16 @@ class PlaybackManager {
|
|||
return self.previousTrack(player);
|
||||
};
|
||||
|
||||
function getPreviousSource(player) {
|
||||
const prevSource = self.currentMediaSource(player);
|
||||
const prevPlayerData = getPlayerData(player);
|
||||
return {
|
||||
...prevSource,
|
||||
DefaultAudioStreamIndex: prevPlayerData.audioStreamIndex,
|
||||
DefaultSubtitleStreamIndex: prevPlayerData.subtitleStreamIndex
|
||||
};
|
||||
}
|
||||
|
||||
self.nextTrack = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (player && !enableLocalPlaylistManagement(player)) {
|
||||
|
@ -2637,7 +2723,7 @@ class PlaybackManager {
|
|||
|
||||
playInternal(newItemInfo.item, newItemPlayOptions, function () {
|
||||
setPlaylistState(newItemInfo.item.PlaylistItemId, newItemInfo.index);
|
||||
});
|
||||
}, getPreviousSource(player));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2658,7 +2744,7 @@ class PlaybackManager {
|
|||
|
||||
playInternal(newItem, newItemPlayOptions, function () {
|
||||
setPlaylistState(newItem.PlaylistItemId, newIndex);
|
||||
});
|
||||
}, getPreviousSource(player));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue