From dc956eb48c48a8ab249ab5a736c0ce75746f73d3 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sun, 3 Apr 2022 13:10:50 +0200 Subject: [PATCH 1/2] Restore sort order after jellyfin/jellyfin#7529, allow subtitle selector display whithout video stream --- src/components/itemHelper.js | 14 +++++++++++- src/controllers/itemDetails/index.js | 32 ++++++++++++---------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/components/itemHelper.js b/src/components/itemHelper.js index decb77b3e3..030b6d7fcf 100644 --- a/src/components/itemHelper.js +++ b/src/components/itemHelper.js @@ -331,6 +331,17 @@ export function supportsMediaSourceSelection (item) { return true; } +export function sortTracks (trackA, trackB) { + let cmp = trackA.IsExternal - trackB.IsExternal; + if (cmp != 0) return cmp; + cmp = trackB.IsForced - trackA.IsForced; + if (cmp != 0) return cmp; + cmp = trackB.IsDefault - trackA.IsDefault; + if (cmp != 0) return cmp; + + return trackA.Index - trackB.Index; +} + export default { getDisplayName: getDisplayName, supportsAddingToCollection: supportsAddingToCollection, @@ -346,5 +357,6 @@ export default { canRate: canRate, canConvert: canConvert, canRefreshMetadata: canRefreshMetadata, - supportsMediaSourceSelection: supportsMediaSourceSelection + supportsMediaSourceSelection: supportsMediaSourceSelection, + sortTracks: sortTracks }; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 5272e51dfc..c51c018739 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -188,7 +188,7 @@ function renderTrackSelections(page, instance, item, forceReload) { }); resolutionNames.sort((a, b) => parseInt(b.Name, 10) - parseInt(a.Name, 10)); - sourceNames.sort(function(a, b) { + sourceNames.sort((a, b) => { const nameA = a.Name.toUpperCase(); const nameB = b.Name.toUpperCase(); if (nameA < nameB) { @@ -274,6 +274,7 @@ function renderAudioSelections(page, mediaSources) { const tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Audio'; }); + tracks.sort((a, b) => itemHelper.sortTracks(a, b)); const select = page.querySelector('.selectAudio'); select.setLabel(globalize.translate('Audio')); const selectedId = mediaSource.DefaultAudioStreamIndex; @@ -303,31 +304,26 @@ function renderSubtitleSelections(page, mediaSources) { const tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Subtitle'; }); + tracks.sort((a, b) => itemHelper.sortTracks(a, b)); const select = page.querySelector('.selectSubtitles'); select.setLabel(globalize.translate('Subtitles')); const selectedId = mediaSource.DefaultSubtitleStreamIndex == null ? -1 : mediaSource.DefaultSubtitleStreamIndex; - const videoTracks = mediaSource.MediaStreams.filter(function (m) { - return m.Type === 'Video'; - }); + let selected = selectedId === -1 ? ' selected' : ''; + select.innerHTML = '' + tracks.map(function (v) { + selected = v.Index === selectedId ? ' selected' : ''; + return ''; + }).join(''); - // This only makes sense on Video items - if (videoTracks.length) { - let selected = selectedId === -1 ? ' selected' : ''; - select.innerHTML = '' + tracks.map(function (v) { - selected = v.Index === selectedId ? ' selected' : ''; - return ''; - }).join(''); - - if (tracks.length > 0) { - select.removeAttribute('disabled'); - } else { - select.setAttribute('disabled', 'disabled'); - } + if (tracks.length > 0) { + select.removeAttribute('disabled'); + } else { + select.setAttribute('disabled', 'disabled'); + } + if (tracks.length) { page.querySelector('.selectSubtitlesContainer').classList.remove('hide'); } else { - select.innerHTML = ''; page.querySelector('.selectSubtitlesContainer').classList.add('hide'); } } From b69b9227c4cfc1fdd7dd81748780cfebd5bb2d99 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Wed, 6 Apr 2022 13:17:46 +0200 Subject: [PATCH 2/2] Add track sorting to mediainfo and player track selection --- src/components/itemMediaInfo/itemMediaInfo.js | 5 +++-- src/components/playback/playbackmanager.js | 8 ++++---- src/controllers/itemDetails/index.js | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index 08c290379c..bf3e4f0932 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -12,6 +12,7 @@ import toast from '../toast/toast'; import { copy } from '../../scripts/clipboard'; import dom from '../../scripts/dom'; import globalize from '../../scripts/globalize'; +import itemHelper from '../../components/itemHelper'; import loading from '../loading/loading'; import '../../elements/emby-select/emby-select'; import '../listview/listview.scss'; @@ -71,8 +72,8 @@ const attributeDelimiterHtml = layoutManager.tv ? '' : ': `; } - for (let i = 0, length = version.MediaStreams.length; i < length; i++) { - const stream = version.MediaStreams[i]; + version.MediaStreams.sort(itemHelper.sortTracks); + for (const stream of version.MediaStreams) { if (stream.Type === 'Data') { continue; } diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index cd634d71cf..9736d597db 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3657,7 +3657,7 @@ class PlaybackManager { if (player.audioTracks) { const result = player.audioTracks(); if (result) { - return result; + return result.sort(itemHelper.sortTracks); } } @@ -3666,14 +3666,14 @@ class PlaybackManager { const mediaStreams = (mediaSource || {}).MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Audio'; - }); + }).sort(itemHelper.sortTracks); } subtitleTracks(player = this._currentPlayer) { if (player.subtitleTracks) { const result = player.subtitleTracks(); if (result) { - return result; + return result.sort(itemHelper.sortTracks); } } @@ -3682,7 +3682,7 @@ class PlaybackManager { const mediaStreams = (mediaSource || {}).MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Subtitle'; - }); + }).sort(itemHelper.sortTracks); } getSupportedCommands(player) { diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index c51c018739..9004c6d288 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -274,7 +274,7 @@ function renderAudioSelections(page, mediaSources) { const tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Audio'; }); - tracks.sort((a, b) => itemHelper.sortTracks(a, b)); + tracks.sort(itemHelper.sortTracks); const select = page.querySelector('.selectAudio'); select.setLabel(globalize.translate('Audio')); const selectedId = mediaSource.DefaultAudioStreamIndex; @@ -304,7 +304,7 @@ function renderSubtitleSelections(page, mediaSources) { const tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Subtitle'; }); - tracks.sort((a, b) => itemHelper.sortTracks(a, b)); + tracks.sort(itemHelper.sortTracks); const select = page.querySelector('.selectSubtitles'); select.setLabel(globalize.translate('Subtitles')); const selectedId = mediaSource.DefaultSubtitleStreamIndex == null ? -1 : mediaSource.DefaultSubtitleStreamIndex;