import { SourceTrack, SourceTrackKind } from "./jhls.d.ts"; const cache = new Map() // TODO this testing method makes the assumption, that if the codec is supported on its own, it can be // TODO arbitrarly combined with others that are supported. in reality this is true but the spec does not gurantee it. export async function test_media_capability(track: SourceTrack): Promise { const cache_key = `${get_track_kind(track.kind)};${track.codec}` const cached = cache.get(cache_key); if (cached !== undefined) return cached const r = await test_media_capability_inner(track) console.log(`${r ? "positive" : "negative"} media capability test finished for codec=${track.codec}`); cache.set(cache_key, r) return r } async function test_media_capability_inner(track: SourceTrack) { if (track.kind.subtitles) { return track.codec == "V_TEXT/WEBVTT" // TODO: actually implement it } let res; const codec = MASTROSKA_CODEC_MAP[track.codec] if (!codec) return console.warn(`unknown codec: ${track.codec}`), false if (track.kind.audio) { res = await navigator.mediaCapabilities.decodingInfo({ type: "media-source", audio: { contentType: `audio/webm; codecs=${codec}`, samplerate: track.kind.audio.sample_rate, channels: "" + track.kind.audio.channels, bitrate: 128 * 1000, } }) } if (track.kind.video) { res = await navigator.mediaCapabilities.decodingInfo({ type: "media-source", video: { contentType: `video/webm; codecs=${codec}`, framerate: track.kind.video.fps || 30, width: track.kind.video.width, height: track.kind.video.height, bitrate: 5 * 1000 * 1000 // TODO we dont know this but we should in the future } }) } return res?.supported ?? false } const MASTROSKA_CODEC_MAP: { [key: string]: string } = { "V_VP9": "vp9", "V_VP8": "vp8", "V_AV1": "av1", "V_MPEG4/ISO/AVC": "h264", "V_MPEGH/ISO/HEVC": "h265", "A_OPUS": "opus", "A_VORBIS": "vorbis", "S_TEXT/WEBVTT": "webvtt", } export function get_track_kind(track: SourceTrackKind): "audio" | "video" | "subtitles" { if (track.audio) return "audio" if (track.video) return "video" if (track.subtitles) return "subtitles" throw new Error("invalid track"); }