alyssaxuu/screenity · error

WebCodecsRecorder: No supported H.264 encoder

Error message

WebCodecsRecorder: No supported H.264 encoder

What it means

WebCodecsRecorder probes candidate H.264 VideoEncoder configurations (codec strings/hardware-software preferences) and throws when none report successful configuration/support, meaning the encoder cannot be created at all.

Source

Thrown at src/pages/Recorder/webcodecs/WebCodecsRecorder.js:2766

            },
          });
        } catch {}
        return {
          config: resolvedConfig,
          codec: c.codec,
          containerCodec: c.containerCodec,
        };
      } catch (e) {
        this._videoCodecConfigsTried.push({
          codec: c.codec,
          hw: c.hw,
          succeeded: false,
        });
      } finally {
        try { test.close(); } catch {}
      }
    }
    throw new Error("WebCodecsRecorder: No supported H.264 encoder");
  }

  // Geometry lives in letterbox.js; this just paints it.
  drawFrameToResizeCanvas(frame) {
    const tw = this.targetWidth;
    const th = this.targetHeight;
    const rect = computeLetterboxRect({
      sw: frame.codedWidth,
      sh: frame.codedHeight,
      tw,
      th,
    });

    if (rect.fills) {
      this.resizeCtx.drawImage(frame, 0, 0, tw, th);
      return;
    }

View on GitHub (pinned to 512606387b)

Solutions

  1. Detect H.264 support up front (VideoEncoder.isConfigSupported) and fall back to VP9/VP8 or MediaRecorder
  2. Add software H.264 encoder configs to the candidate probe list (containing 'avc1.42E01E' style levels, hardwareAcceleration: 'prefer-software')
  3. Install/use a browser build with proprietary codecs enabled
  4. Surface a clear user message recommending Chrome/Edge with H.264 support

Example fix

// before
throw new Error("WebCodecsRecorder: No supported H.264 encoder");
// after
const h264 = await probeH264();
if (!h264 && (await probeVp9())) { this.codec = "vp9"; return; }
throw new Error("WebCodecsRecorder: no supported video encoder (tried h264, vp9)");
Defensive patterns

Strategy: fallback

Validate before calling

const cfg = { codec: "avc1.42E01E", width: 1280, height: 720, bitrate: 2_000_000 };
const { supported } = await VideoEncoder.isConfigSupported(cfg);
if (!supported) useVp9OrMediaRecorderFallback();

Type guard

async function hasH264Encoder(w, h, bitrate) {
  if (typeof VideoEncoder === "undefined") return false;
  const r = await VideoEncoder.isConfigSupported({ codec: "avc1.42E01E", width: w, height: h, bitrate });
  return r.supported === true;
}

Try / catch

try {
  recorder = new WebCodecsRecorder(stream, opts);
  await recorder.init(); // probes H.264 here
} catch (e) {
  if (String(e.message).includes("No supported H.264 encoder")) {
    recorder = new MediaRecorderFallback(stream, opts);
  }
}

Prevention

When it happens

Trigger: Every probed H.264 codec string fails VideoEncoder.isConfigSupported or the test encode throws — e.g. the browser lacks H.264 encoding (no proprietary codecs build), hardware encoder unavailable and software fallback disabled/missing.

Common situations: Chromium builds without proprietary codecs (H.264), Firefox without H.264 encode support in some versions, locked-down hardware/VMs with no H.264 encoder, user agents where hardware accel is off and no software encoder exists.

Related errors


AI-assisted analysis of alyssaxuu/screenity@512606387b (2026-09-02). Data as JSON: /api/errors/3083b92484299f3b. Report an issue: GitHub.