mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-12 20:16:15 -08:00
fix(playback): preserve explicit extension overrides
Entire-Checkpoint: f957cd9849e0
This commit is contained in:
1 parent
cd331c796c
commit
a0850c1505
2 files changed
+42
-12
No files matched your search
@@ -293,7 +293,7 @@ describe('playback diagnostics', () => {
|
||||
it('keeps trusted media path extensions ahead of generic query metadata', () => {
|
||||
expect(
|
||||
getPlaybackMediaExtensionFromUrl(
|
||||
'http://cdn.example/archive/movie.mp4?type=hls'
|
||||
'http://cdn.example/archive/movie.mp4?container=m3u8'
|
||||
)
|
||||
).toBe('mp4');
|
||||
expect(
|
||||
@@ -303,6 +303,19 @@ describe('playback diagnostics', () => {
|
||||
).toBe('m3u8');
|
||||
});
|
||||
|
||||
it('keeps explicit extension query metadata ahead of trusted media path extensions', () => {
|
||||
expect(
|
||||
getPlaybackMediaExtensionFromUrl(
|
||||
'http://cdn.example/live/channel.ts?extension=m3u8'
|
||||
)
|
||||
).toBe('m3u8');
|
||||
expect(
|
||||
getPlaybackMediaExtensionFromUrl(
|
||||
'http://cdn.example/live/channel.m3u8?ext=ts'
|
||||
)
|
||||
).toBe('ts');
|
||||
});
|
||||
|
||||
it('does not infer media extensions from generic type/output query metadata', () => {
|
||||
expect(
|
||||
getPlaybackMediaExtensionFromUrl(
|
||||
@@ -319,6 +332,11 @@ describe('playback diagnostics', () => {
|
||||
'http://portal.example/play/live.php?format=mpv&stream=123'
|
||||
)
|
||||
).toBe('');
|
||||
expect(
|
||||
getPlaybackMediaExtensionFromUrl(
|
||||
'http://portal.example/play/live.mpv?stream=123'
|
||||
)
|
||||
).toBe('');
|
||||
});
|
||||
|
||||
it('detects codecs with limited Chromium browser-player support', () => {
|
||||
|
||||
@@ -124,12 +124,9 @@ const UNSUPPORTED_CONTAINER_NAMES = new Set([
|
||||
'x-msvideo',
|
||||
]);
|
||||
|
||||
const DECLARED_MEDIA_EXTENSION_QUERY_KEYS = [
|
||||
'extension',
|
||||
'ext',
|
||||
'format',
|
||||
'container',
|
||||
];
|
||||
const EXPLICIT_MEDIA_EXTENSION_QUERY_KEYS = ['extension', 'ext'];
|
||||
|
||||
const DECLARED_MEDIA_FORMAT_QUERY_KEYS = ['format', 'container'];
|
||||
|
||||
const DECLARED_MEDIA_EXTENSION_ALIASES = new Map([
|
||||
['hls', 'm3u8'],
|
||||
@@ -158,6 +155,7 @@ const NON_MEDIA_URL_EXTENSIONS = new Set([
|
||||
'aspx',
|
||||
'cgi',
|
||||
'jsp',
|
||||
'mpv',
|
||||
'php',
|
||||
'pl',
|
||||
]);
|
||||
@@ -195,14 +193,25 @@ export function createPlaybackSourceMetadata(
|
||||
}
|
||||
|
||||
export function getPlaybackMediaExtensionFromUrl(url: string): string {
|
||||
const explicitQueryExtension = getMediaExtensionFromQuery(
|
||||
url,
|
||||
EXPLICIT_MEDIA_EXTENSION_QUERY_KEYS
|
||||
);
|
||||
if (explicitQueryExtension) {
|
||||
return explicitQueryExtension;
|
||||
}
|
||||
|
||||
const pathExtension = normalizeExtensionToken(getExtensionFromUrl(url));
|
||||
if (DECLARED_MEDIA_EXTENSIONS.has(pathExtension)) {
|
||||
return pathExtension;
|
||||
}
|
||||
|
||||
const queryExtension = getMediaExtensionFromQuery(url);
|
||||
if (queryExtension) {
|
||||
return queryExtension;
|
||||
const formatQueryExtension = getMediaExtensionFromQuery(
|
||||
url,
|
||||
DECLARED_MEDIA_FORMAT_QUERY_KEYS
|
||||
);
|
||||
if (formatQueryExtension) {
|
||||
return formatQueryExtension;
|
||||
}
|
||||
|
||||
if (NON_MEDIA_URL_EXTENSIONS.has(pathExtension)) {
|
||||
@@ -493,10 +502,13 @@ function normalizeExtensionToken(value: string | undefined): string {
|
||||
return normalizeToken(value).replace(/^\.+/, '');
|
||||
}
|
||||
|
||||
function getMediaExtensionFromQuery(url: string): string {
|
||||
function getMediaExtensionFromQuery(
|
||||
url: string,
|
||||
queryKeys: readonly string[]
|
||||
): string {
|
||||
try {
|
||||
const parsedUrl = new URL(url, 'http://iptvnator.local');
|
||||
for (const key of DECLARED_MEDIA_EXTENSION_QUERY_KEYS) {
|
||||
for (const key of queryKeys) {
|
||||
const declaredExtension = normalizeDeclaredMediaExtension(
|
||||
parsedUrl.searchParams.get(key) ?? undefined
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user