Files
iptvnator/libs/playback/util/src/lib/playback-source-routing.spec.ts
T
4grayandClaude Fable 5.1 5e51c1ea5d fix(playback): route non-HLS containers to the native source path (#1510)
The HTML5 player chose its engine by exclusion: anything that was not
mpd/ts/mp4 went to hls.js, so .mkv (the default Xtream series/VOD
container), .webm, .avi, .mov and .m4v were fed to hls.js as manifests.
hls.js raised a manifest error and the player showed the network/provider
diagnostic over media Chromium plays natively.

Add resolvePlaybackUrlSourceKind() to @iptvnator/playback/util as the one
URL-to-engine rule (mpd -> dash, m3u8/m3u -> hls, ts/m2ts/extension-less
-> mpegts, everything else -> native) and read it from both the HTML5
player and ArtPlayer's getArtPlayerVideoType(), so the two engines agree.
ArtPlayer serves every native container through a single
ART_PLAYER_NATIVE_SOURCE_TYPE custom type, keeping the source session the
owner of teardown and controls binding. The HTML5 native <source> carries
the video/mp4 hint only for MP4-family files: a hint the browser's
canPlayType() rejects makes it skip the source, and Chromium demuxes
containers it does not advertise there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 09:43:33 +02:00

44 lines
1.9 KiB
TypeScript

import { PlaybackSourceKind } from './playback-recommendation.model';
import { resolvePlaybackUrlSourceKind } from './playback-source-routing';
describe('resolvePlaybackUrlSourceKind', () => {
it.each([
['https://example.test/live/playlist.m3u8', PlaybackSourceKind.Hls],
[
'https://example.test/live/playlist.M3U8?token=signed',
PlaybackSourceKind.Hls,
],
['https://example.test/live/list.m3u', PlaybackSourceKind.Hls],
['https://example.test/play?format=hls', PlaybackSourceKind.Hls],
['https://example.test/live.mpd', PlaybackSourceKind.Dash],
[
'https://example.test/stream.MPD?token=signed#frag',
PlaybackSourceKind.Dash,
],
['https://example.test/raw.ts', PlaybackSourceKind.MpegTs],
['https://example.test/disc.m2ts', PlaybackSourceKind.MpegTs],
['https://example.test/live/user/pass/1', PlaybackSourceKind.MpegTs],
['https://example.test/live.php?id=7', PlaybackSourceKind.MpegTs],
['https://example.test/play?ext=mpegts', PlaybackSourceKind.MpegTs],
])('routes %s to the %s engine', (url, kind) => {
expect(resolvePlaybackUrlSourceKind(url)).toBe(kind);
});
it.each([
'https://example.test/movie/user/pass/2000000.mp4',
'https://example.test/series/user/pass/80000.mkv',
'https://example.test/movie.MKV?token=signed',
'https://example.test/play?extension=mkv',
'https://example.test/movie.webm',
'https://example.test/movie.avi',
'https://example.test/movie.mov',
'https://example.test/movie.m4v',
'https://example.test/track.mp3',
'https://example.test/movie.bin',
])('hands the non-HLS container %s to the native element', (url) => {
expect(resolvePlaybackUrlSourceKind(url)).toBe(
PlaybackSourceKind.Native
);
});
});