From 6577a54418044891649e120678ec092704ad1ef0 Mon Sep 17 00:00:00 2001 From: FabLrc Date: Tue, 28 Apr 2026 13:59:10 +0200 Subject: [PATCH 1/3] fix(exporter): normalize bare VP8/VP9 codec strings from web-demuxer --- src/lib/exporter/streamingDecoder.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/exporter/streamingDecoder.ts b/src/lib/exporter/streamingDecoder.ts index 24b9844..c3bca3c 100644 --- a/src/lib/exporter/streamingDecoder.ts +++ b/src/lib/exporter/streamingDecoder.ts @@ -311,8 +311,16 @@ export class StreamingVideoDecoder { ); } + if (/^vp08$/i.test(decoderConfig.codec)) { + decoderConfig.codec = "vp8"; + } + if (/^vp09$/i.test(decoderConfig.codec)) { + decoderConfig.codec = "vp9"; + } + const codec = decoderConfig.codec.toLowerCase(); - const shouldPreferSoftwareDecode = codec.includes("av01") || codec.includes("av1"); + const shouldPreferSoftwareDecode = + codec.includes("av01") || codec.includes("av1") || codec.includes("vp09"); const segments = this.splitBySpeed( this.computeSegments(this.metadata.duration, trimRegions), speedRegions, From cae71ed49c56e9f0626ae17a2bae6f94fcec2a14 Mon Sep 17 00:00:00 2001 From: FabLrc Date: Tue, 28 Apr 2026 14:08:01 +0200 Subject: [PATCH 2/3] fix(exporter): add codec normalization for bare avc1/h264 and logging --- src/lib/exporter/streamingDecoder.ts | 36 ++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/lib/exporter/streamingDecoder.ts b/src/lib/exporter/streamingDecoder.ts index c3bca3c..8cf0257 100644 --- a/src/lib/exporter/streamingDecoder.ts +++ b/src/lib/exporter/streamingDecoder.ts @@ -302,9 +302,12 @@ export class StreamingVideoDecoder { const decoderConfig = await this.demuxer.getDecoderConfig("video"); - // web-demuxer may return a bare "av01" for AV1 in WebM containers when the - // extradata isn't in the expected ISOBMFF format. WebCodecs requires the - // full parametrized form (e.g. "av01.0.05M.08"). + console.log("[StreamingVideoDecoder] decoderConfig.codec:", decoderConfig.codec); + console.log("[StreamingVideoDecoder] decoderConfig.description:", decoderConfig.description); + + // web-demuxer may return bare four-character code strings ("av01", "vp08", + // "vp09", "avc1") that WebCodecs rejects. Normalize them to the short or + // full parametrized forms that VideoDecoder accepts. if (/^av01$/i.test(decoderConfig.codec)) { decoderConfig.codec = buildAV1CodecString( decoderConfig.description as BufferSource | undefined, @@ -318,9 +321,19 @@ export class StreamingVideoDecoder { decoderConfig.codec = "vp9"; } + if (/^avc1$/i.test(decoderConfig.codec)) { + decoderConfig.codec = "avc1.640033"; + } + if (/^h264$/i.test(decoderConfig.codec)) { + decoderConfig.codec = "avc1.640033"; + } + const codec = decoderConfig.codec.toLowerCase(); const shouldPreferSoftwareDecode = - codec.includes("av01") || codec.includes("av1") || codec.includes("vp09"); + codec.includes("av01") || + codec.includes("av1") || + codec.includes("vp09") || + codec.includes("vp9"); const segments = this.splitBySpeed( this.computeSegments(this.metadata.duration, trimRegions), speedRegions, @@ -351,6 +364,10 @@ export class StreamingVideoDecoder { } }, error: (e: DOMException) => { + console.warn( + `[StreamingVideoDecoder] decoder error for codec "${decoderConfig.codec}":`, + e.message, + ); decodeError = new Error(`VideoDecoder error: ${e.message}`); if (frameResolve) { const resolve = frameResolve; @@ -367,6 +384,17 @@ export class StreamingVideoDecoder { : decoderConfig; try { + const support = await VideoDecoder.isConfigSupported(preferredDecoderConfig); + console.log( + `[StreamingVideoDecoder] isConfigSupported for "${preferredDecoderConfig.codec}":`, + support.supported, + ); + if (!support.supported) { + throw new DOMException( + `Unsupported codec: ${preferredDecoderConfig.codec}`, + "NotSupportedError", + ); + } this.decoder.configure(preferredDecoderConfig); } catch (error) { if (!shouldPreferSoftwareDecode) { From f9401f051c68392fe7bc4483702d518272057347 Mon Sep 17 00:00:00 2001 From: FabLrc Date: Tue, 28 Apr 2026 14:13:34 +0200 Subject: [PATCH 3/3] fix(exporter): fall back to avc1.640033 for unsupported H.264 codec strings --- src/lib/exporter/streamingDecoder.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/lib/exporter/streamingDecoder.ts b/src/lib/exporter/streamingDecoder.ts index 8cf0257..dd4df7b 100644 --- a/src/lib/exporter/streamingDecoder.ts +++ b/src/lib/exporter/streamingDecoder.ts @@ -390,18 +390,22 @@ export class StreamingVideoDecoder { support.supported, ); if (!support.supported) { - throw new DOMException( - `Unsupported codec: ${preferredDecoderConfig.codec}`, - "NotSupportedError", - ); + throw new Error(`Unsupported codec: ${preferredDecoderConfig.codec}`); } this.decoder.configure(preferredDecoderConfig); } catch (error) { - if (!shouldPreferSoftwareDecode) { + if (shouldPreferSoftwareDecode) { + this.decoder.configure(decoderConfig); + } else if (/^avc1/i.test(codec)) { + const fallback = { ...decoderConfig, codec: "avc1.640033" }; + console.warn( + `[StreamingVideoDecoder] codec "${codec}" unsupported, ` + + `falling back to "${fallback.codec}"`, + ); + this.decoder.configure(fallback); + } else { throw error; } - // Fall back to default decoder config if software preference isn't supported. - this.decoder.configure(decoderConfig); } const getNextFrame = (): Promise => {