mirror of
https://github.com/TeamPiped/Piped.git
synced 2026-06-02 04:44:30 +00:00
Add the upstream Mozilla tracker bug for the slow decodingInfo path. Refs: https://bugzilla.mozilla.org/show_bug.cgi?id=2043895 https://github.com/TeamPiped/Piped/issues/4238
57 lines
2.5 KiB
JavaScript
57 lines
2.5 KiB
JavaScript
/**
|
|
* HACK: Firefox-only fast path for navigator.mediaCapabilities.decodingInfo().
|
|
*
|
|
* Rough comparison: Chromium ~0.1 ms/call vs Firefox ~20 ms/call.
|
|
* Shaka calls decodingInfo once per Variant while filtering the manifest, so on
|
|
* a YouTube-shape manifest with many Variants Firefox stalls several seconds at
|
|
* player init before any SourceBuffer is added.
|
|
*
|
|
* This module delegates "supported" to MediaSource.isTypeSupported (sub-ms on
|
|
* Firefox) and synthesizes smooth = powerEfficient = supported.
|
|
*
|
|
* KNOWN DOWNSIDE: by forcing smooth and powerEfficient to true we discard the
|
|
* native signals Shaka would otherwise see. If anything in the player chain
|
|
* reads those fields (e.g. preferredDecodingAttributes is set, a downstream
|
|
* consumer ranks variants on power efficiency, or a Shaka upgrade changes
|
|
* filtering), this shim will cause Shaka to pick streams the device cannot
|
|
* decode in real time — frame drops, software-decode CPU spikes, battery
|
|
* drain. Today (Shaka 5.1, Piped default config) those fields are not read
|
|
* and the shim is harmless; revisit on every Shaka upgrade.
|
|
*
|
|
* Active only on Gecko engines, so Chromium / Safari / Edge / iOS Firefox
|
|
* (WebKit) are unaffected. DRM probes (keySystemConfiguration) and non-
|
|
* media-source query types fall through to the native API unchanged.
|
|
*
|
|
* Refs:
|
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=2043895
|
|
* https://github.com/TeamPiped/Piped/issues/4238
|
|
*/
|
|
if (
|
|
typeof navigator !== "undefined" &&
|
|
/Gecko\/[0-9]/.test(navigator.userAgent) &&
|
|
navigator.mediaCapabilities &&
|
|
typeof navigator.mediaCapabilities.decodingInfo === "function"
|
|
) {
|
|
const orig = navigator.mediaCapabilities.decodingInfo.bind(navigator.mediaCapabilities);
|
|
const cache = new Map();
|
|
const mimeOk = mime => {
|
|
if (!cache.has(mime)) cache.set(mime, MediaSource.isTypeSupported(mime));
|
|
return cache.get(mime);
|
|
};
|
|
navigator.mediaCapabilities.decodingInfo = function (config) {
|
|
if (config && config.type === "media-source" && !config.keySystemConfiguration) {
|
|
const v = config.video;
|
|
const a = config.audio;
|
|
const supported = (!v || mimeOk(v.contentType)) && (!a || mimeOk(a.contentType));
|
|
return Promise.resolve({
|
|
supported,
|
|
smooth: supported,
|
|
powerEfficient: supported,
|
|
keySystemAccess: null,
|
|
configuration: config,
|
|
});
|
|
}
|
|
return orig(config);
|
|
};
|
|
}
|