diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 8aaaa12aea..9d38bb2712 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -11,6 +11,7 @@ import { appHost } from '../apphost'; import Screenfull from 'screenfull'; import ServerConnections from '../ServerConnections'; import alert from '../alert'; +import { includesAny } from '../../utils/container.ts'; const UNLIMITED_ITEMS = -1; @@ -1306,6 +1307,7 @@ class PlaybackManager { return false; } + const container = mediaSource.Container.toLowerCase(); const codec = (mediaStream.Codec || '').toLowerCase(); if (!codec) { @@ -1315,20 +1317,9 @@ class PlaybackManager { const profiles = deviceProfile.DirectPlayProfiles || []; return profiles.filter(function (p) { - if (p.Type === 'Video') { - if (!p.AudioCodec) { - return true; - } - - // This is an exclusion filter - if (p.AudioCodec.indexOf('-') === 0) { - return p.AudioCodec.toLowerCase().indexOf(codec) === -1; - } - - return p.AudioCodec.toLowerCase().indexOf(codec) !== -1; - } - - return false; + return p.Type === 'Video' + && includesAny((p.Container || '').toLowerCase(), container) + && includesAny((p.AudioCodec || '').toLowerCase(), codec); }).length > 0; } diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 123c550517..aaf6b53c76 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -30,6 +30,7 @@ import globalize from '../../scripts/globalize'; import ServerConnections from '../../components/ServerConnections'; import profileBuilder from '../../scripts/browserDeviceProfile'; import { getIncludeCorsCredentials } from '../../scripts/settings/webSettings'; +import { includesAny } from '../../utils/container.ts'; /** * Returns resolved URL. @@ -602,7 +603,7 @@ function tryRemoveElement(elem) { /** * @private */ - isAudioStreamSupported(stream, deviceProfile) { + isAudioStreamSupported(stream, deviceProfile, container) { const codec = (stream.Codec || '').toLowerCase(); if (!codec) { @@ -617,15 +618,9 @@ function tryRemoveElement(elem) { const profiles = deviceProfile.DirectPlayProfiles || []; return profiles.filter(function (p) { - if (p.Type === 'Video') { - if (!p.AudioCodec) { - return true; - } - - return p.AudioCodec.toLowerCase().includes(codec); - } - - return false; + return p.Type === 'Video' + && includesAny((p.Container || '').toLowerCase(), container) + && includesAny((p.AudioCodec || '').toLowerCase(), codec); }).length > 0; } @@ -635,8 +630,11 @@ function tryRemoveElement(elem) { getSupportedAudioStreams() { const profile = this.#lastProfile; - return getMediaStreamAudioTracks(this._currentPlayOptions.mediaSource).filter((stream) => { - return this.isAudioStreamSupported(stream, profile); + const mediaSource = this._currentPlayOptions.mediaSource; + const container = mediaSource.Container.toLowerCase(); + + return getMediaStreamAudioTracks(mediaSource).filter((stream) => { + return this.isAudioStreamSupported(stream, profile, container); }); } diff --git a/src/utils/container.ts b/src/utils/container.ts new file mode 100644 index 0000000000..170c357d65 --- /dev/null +++ b/src/utils/container.ts @@ -0,0 +1,42 @@ +/** + * Checks if the list includes any value from the search. + * @param list The list to search in. + * @param search The values to search. + * @returns _true_ if the list includes any value from the search. + * @remarks The list (string) can start with '-', in which case the logic is inverted. + */ +export function includesAny(list: string | string[] | null | undefined, search: string | string[]): boolean { + if (!list) { + return true; + } + + let inverseMatch = false; + + if (typeof list === 'string') { + if (list.startsWith('-')) { + inverseMatch = true; + list = list.substring(1); + } + + list = list.split(','); + } + + list = list.filter(i => i); + + if (!list.length) { + return true; + } + + if (typeof search === 'string') { + search = search.split(','); + } + + search = search.filter(i => i); + + /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */ + if (search.some(s => list!.includes(s))) { + return !inverseMatch; + } + + return inverseMatch; +}