This commit is contained in:
Vanilagy
2026-08-21 20:06:29 +02:00
4 changed files with 32 additions and 11 deletions
+11 -2
View File
@@ -38,6 +38,7 @@ import {
isWebKit, isWebKit,
last, last,
mapAsyncGenerator, mapAsyncGenerator,
missingWebCodecsClassMessage,
promiseWithResolvers, promiseWithResolvers,
removeItem, removeItem,
Rotation, Rotation,
@@ -1691,8 +1692,12 @@ export class VideoSampleSink extends BaseMediaSampleSink<VideoSample> {
onError: (error: unknown) => unknown, onError: (error: unknown) => unknown,
) { ) {
if (!(await this._track.canDecode())) { if (!(await this._track.canDecode())) {
if (typeof VideoDecoder === 'undefined') {
throw new Error(missingWebCodecsClassMessage('VideoDecoder'));
}
throw new Error( throw new Error(
'This video track cannot be decoded by this browser. Make sure to check decodability before using' 'This video track cannot be decoded in this environment. Make sure to check decodability before using'
+ ' a track.', + ' a track.',
); );
} }
@@ -2426,8 +2431,12 @@ export class AudioSampleSink extends BaseMediaSampleSink<AudioSample> {
onError: (error: unknown) => unknown, onError: (error: unknown) => unknown,
) { ) {
if (!(await this._track.canDecode())) { if (!(await this._track.canDecode())) {
if (typeof AudioDecoder === 'undefined') {
throw new Error(missingWebCodecsClassMessage('AudioDecoder'));
}
throw new Error( throw new Error(
'This audio track cannot be decoded by this browser. Make sure to check decodability before using' 'This audio track cannot be decoded in this environment. Make sure to check decodability before using'
+ ' a track.', + ' a track.',
); );
} }
+8 -6
View File
@@ -29,6 +29,7 @@ import {
clearIntervalUnthrottled, clearIntervalUnthrottled,
floorToDivisor, floorToDivisor,
last, last,
missingWebCodecsClassMessage,
promiseWithResolvers, promiseWithResolvers,
roundToDivisor, roundToDivisor,
setInt24, setInt24,
@@ -718,7 +719,7 @@ class VideoEncoderWrapper {
if (!selected) { if (!selected) {
if (typeof VideoEncoder === 'undefined') { if (typeof VideoEncoder === 'undefined') {
throw new Error('VideoEncoder is not supported by this browser.'); throw new Error(missingWebCodecsClassMessage('VideoEncoder'));
} }
// The candidates only differ in their rate control, so we describe them as one config with a // The candidates only differ in their rate control, so we describe them as one config with a
@@ -731,7 +732,7 @@ class VideoEncoderWrapper {
throw new Error( throw new Error(
`This specific encoder configuration (${firstConfig.codec}, ${rateControls.join(' / ')},` `This specific encoder configuration (${firstConfig.codec}, ${rateControls.join(' / ')},`
+ ` ${firstConfig.width}x${firstConfig.height}, hardware acceleration:` + ` ${firstConfig.width}x${firstConfig.height}, hardware acceleration:`
+ ` ${firstConfig.hardwareAcceleration ?? 'no-preference'}) is not supported by this browser.` + ` ${firstConfig.hardwareAcceleration ?? 'no-preference'}) is not supported in this environment.`
+ ` Consider using another codec or changing your video parameters.`, + ` Consider using another codec or changing your video parameters.`,
); );
} }
@@ -1694,8 +1695,8 @@ export class MediaStreamVideoTrackSource extends VideoSource {
}); });
} else { } else {
throw new Error( throw new Error(
'When no explicit frame rate is set, MediaStreamTrackProcessor is required; but it\'s not supported' 'When no explicit frame rate is set, MediaStreamTrackProcessor is required; but it\'s not available'
+ ' by this browser.', + ' in this environment.',
); );
} }
} }
@@ -2210,7 +2211,7 @@ class AudioEncoderWrapper {
this.initPcmEncoder(); this.initPcmEncoder();
} else { } else {
if (typeof AudioEncoder === 'undefined') { if (typeof AudioEncoder === 'undefined') {
throw new Error('AudioEncoder is not supported by this browser.'); throw new Error(missingWebCodecsClassMessage('AudioEncoder'));
} }
let supported: boolean; let supported: boolean;
@@ -2226,7 +2227,8 @@ class AudioEncoderWrapper {
throw new Error( throw new Error(
`This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps,` `This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps,`
+ ` ${encoderConfig.numberOfChannels} channels, ${encoderConfig.sampleRate} Hz) is not` + ` ${encoderConfig.numberOfChannels} channels, ${encoderConfig.sampleRate} Hz) is not`
+ ` supported by this browser. Consider using another codec or changing your audio parameters.`, + ` supported in this environment. Consider using another codec or changing your`
+ ` audio parameters.`,
); );
} }
+10
View File
@@ -721,6 +721,16 @@ export const getChromiumVersion = () => {
return chromiumVersionCache = Number(match[1]!); return chromiumVersionCache = Number(match[1]!);
}; };
export const missingWebCodecsClassMessage = (className: string) => {
if (typeof globalThis.isSecureContext !== 'undefined' && !globalThis.isSecureContext) {
// WebCodecs is not exposed in insecure contexts
return `${className} is not available in this environment; this may be because this page is running in an`
+ ` insecure context. Try serving your page over HTTPS or use localhost.`;
}
return `${className} is not available in this environment.`;
};
/** /**
* T or a promise that resolves to T. * T or a promise that resolves to T.
* @group Miscellaneous * @group Miscellaneous
+3 -3
View File
@@ -155,7 +155,7 @@ export class EncodedPacket {
throw new TypeError('Metadata-only packets cannot be converted to a video chunk.'); throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
} }
if (typeof EncodedVideoChunk === 'undefined') { if (typeof EncodedVideoChunk === 'undefined') {
throw new Error('Your browser does not support EncodedVideoChunk.'); throw new Error('EncodedVideoChunk is not available in this environment.');
} }
return new EncodedVideoChunk({ return new EncodedVideoChunk({
@@ -179,7 +179,7 @@ export class EncodedPacket {
throw new TypeError('Metadata-only packets cannot be converted to a video chunk.'); throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
} }
if (typeof EncodedVideoChunk === 'undefined') { if (typeof EncodedVideoChunk === 'undefined') {
throw new Error('Your browser does not support EncodedVideoChunk.'); throw new Error('EncodedVideoChunk is not available in this environment.');
} }
return new EncodedVideoChunk({ return new EncodedVideoChunk({
@@ -198,7 +198,7 @@ export class EncodedPacket {
throw new TypeError('Metadata-only packets cannot be converted to an audio chunk.'); throw new TypeError('Metadata-only packets cannot be converted to an audio chunk.');
} }
if (typeof EncodedAudioChunk === 'undefined') { if (typeof EncodedAudioChunk === 'undefined') {
throw new Error('Your browser does not support EncodedAudioChunk.'); throw new Error('EncodedAudioChunk is not available in this environment.');
} }
return new EncodedAudioChunk({ return new EncodedAudioChunk({