mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
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>
43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
import { getPlaybackMediaExtensionFromUrl } from '@iptvnator/playback/util';
|
|
|
|
/** Helpers for driving the native `<video>` element source list. */
|
|
|
|
const MP4_FAMILY_EXTENSIONS: ReadonlySet<string> = new Set(['mp4', 'm4v']);
|
|
|
|
export function clearNativeVideoSources(element: HTMLVideoElement): void {
|
|
element.removeAttribute('src');
|
|
element.replaceChildren();
|
|
}
|
|
|
|
/**
|
|
* MIME hint for a native `<source>`, given only to MP4-family files.
|
|
*
|
|
* The hint is a filter, not a description: the browser skips a `<source>`
|
|
* whose type its `canPlayType()` rejects, and a container it demuxes (mkv,
|
|
* webm, mov, avi) is not necessarily one it advertises there. Those sources
|
|
* stay unhinted so the browser sniffs the bytes instead.
|
|
*/
|
|
export function resolveNativeSourceMimeType(url: string): string | undefined {
|
|
return MP4_FAMILY_EXTENSIONS.has(getPlaybackMediaExtensionFromUrl(url))
|
|
? 'video/mp4'
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* Replaces the element's sources with a single `<source>` without loading it;
|
|
* callers bind their controls source first, then call `element.load()`.
|
|
*/
|
|
export function setNativeVideoSource(
|
|
element: HTMLVideoElement,
|
|
url: string,
|
|
type?: string
|
|
): void {
|
|
clearNativeVideoSources(element);
|
|
const source = document.createElement('source');
|
|
source.src = url;
|
|
if (type) {
|
|
source.type = type;
|
|
}
|
|
element.appendChild(source);
|
|
}
|