Skip to content

Commit 00c9df3

Browse files
romot-coclaude
andcommitted
Release v0.3.1: Enhanced configuration validation and error handling
- Add comprehensive config parser validation with detailed error messages - Improve encoder factory with better browser compatibility checks - Enhance worker communication with structured message handling - Add frame drop detection and recovery in encoder worker - Improve stream encoding with robust error handling - Add config-parser test suite for validation coverage - Update dependencies and improve type definitions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b6b835c commit 00c9df3

21 files changed

Lines changed: 1454 additions & 780 deletions

CHANGELOG.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.3.1] - 2025-09-22
9+
10+
### 🎧 Added
11+
- Expanded audio codec coverage to include FLAC, MP3, Vorbis, linear PCM, and μ-law/A-law, with capability probing via `AudioEncoder.isConfigSupported()` and worker fallbacks when a codec is unavailable.
12+
13+
### 🛠️ Improved
14+
- The configuration parser now infers codec-specific defaults (bitrate, sample rate, channels) without forcing inappropriate values onto PCM or telephony codecs.
15+
- `canEncode` and the MP4/WebM muxers share stricter compatibility checks so unsupported codec/container combinations are rejected before encoding begins.
16+
- VideoFile sources read metadata up front, align the encoder resolution, and scale frames when necessary to avoid width/height mismatches.
17+
- Worker creation prefers external worker scripts; the inline mock worker is now opt-in for development and tests only.
18+
19+
### 🐛 Fixed
20+
- Preserved `video: false` and `audio: false` flags when merging options, restoring audio-only workflows.
21+
- Delayed muxer construction until after codec fallbacks complete, ensuring muxers match the actual encoder configuration.
22+
- MediaStream tracks are no longer stopped automatically during cleanup, leaving ownership with the caller.
23+
24+
### 🧪 Tests
25+
- Extended coverage across async iterable safety, audio codec probing, worker initialization paths, and configuration merging edge cases.
26+
27+
---
28+
829
## [0.3.0] - 2025-08-07
930

1031
### 💥 BREAKING CHANGES
@@ -141,4 +162,4 @@ Key areas improved:
141162
- Support for AAC, Opus audio codecs
142163
- MP4 and WebM container formats
143164
- WebCodecs API integration
144-
- TypeScript support
165+
- TypeScript support

README.md

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Function-First API to encode video and audio using WebCodecs API.
55
[![CI](https://github.com/romot-co/webcodecs-encoder/actions/workflows/ci.yml/badge.svg)](https://github.com/romot-co/webcodecs-encoder/actions/workflows/ci.yml)
66
[![bundle size](https://img.shields.io/bundlephobia/minzip/webcodecs-encoder)](https://bundlephobia.com/result?p=webcodecs-encoder)
77

8-
A TypeScript library to encode video (H.264/AVC, VP9, VP8) and audio (AAC, Opus) using the WebCodecs API and mux them into MP4 or WebM containers with a simple.
8+
A TypeScript library to encode video (H.264/AVC, HEVC, VP9, VP8, AV1) and audio (AAC, MP3, Opus, Vorbis, FLAC) using the WebCodecs API and mux them into MP4 or WebM containers with a simple, function-first API.
99

1010
## Features
1111

@@ -17,7 +17,7 @@ A TypeScript library to encode video (H.264/AVC, VP9, VP8) and audio (AAC, Opus)
1717
- **🎨 Progressive Enhancement**: Start simple, add complexity as needed
1818
- **📦 Optimized Bundle Size**: Tree-shakable with ES Modules and `sideEffects: false` for efficient bundling.
1919
- **🛡️ Type Safety**: Full TypeScript support with comprehensive types
20-
- **🎵 Audio Support**: AAC and Opus encoding with automatic configuration
20+
- **🎵 Audio Support**: Automatic AAC↔MP3 fallback for MP4 and Opus/Vorbis/FLAC support for WebM
2121
- **🎤 Audio-Only Encoding**: Support for `video: false` option (v0.2.2)
2222
- **📹 VideoFile Audio**: Extract and encode audio from video files (v0.2.2)
2323
- **⚡ Performance Optimized**: Transferable objects for faster data transfer (v0.2.2)
@@ -32,15 +32,59 @@ yarn add webcodecs-encoder
3232

3333
### Worker Setup
3434

35-
A dedicated Web Worker (**webcodecs-worker.js**) must be reachable at the site root (default: `/webcodecs-worker.js`). The library falls back to an inline worker only in test environments; in production, the external file **is mandatory for security reasons**.
35+
The encoder runs inside a dedicated Web Worker (`/webcodecs-worker.js`). Ship that file with your app and ensure it is publicly reachable at the site root.
3636

37-
You need to copy the worker file from `node_modules` to your public directory.
37+
By default the library:
38+
39+
- **Prefers the external worker** in browsers and production builds.
40+
- **Falls back to an inline mock** only when running under known test runners (Vitest, Jest, `NODE_ENV=test`) or when you explicitly opt in.
41+
- **Never uses the inline mock in production** unless you override the safety check.
42+
43+
Inline worker controls:
44+
45+
| Flag | Effect |
46+
| --- | --- |
47+
| `WEBCODECS_USE_INLINE_WORKER=true` or `window.__WEBCODECS_USE_INLINE_WORKER__ = true` | Force the inline mock (useful for Storybook, unit tests, etc.). |
48+
| `WEBCODECS_DISABLE_INLINE_WORKER=true` or `window.__WEBCODECS_DISABLE_INLINE_WORKER__ = true` | Always require the external worker. |
49+
| `WEBCODECS_ALLOW_INLINE_IN_PROD=true` or `window.__WEBCODECS_ALLOW_INLINE_IN_PROD__ = true` | Explicitly permit the inline mock on production builds (not recommended). |
50+
51+
> ⚠️ The inline worker is a **test stub** that returns placeholder bytes. Use it only for wiring/UI development. Real MP4/WebM output requires the external worker bundle.
52+
53+
Copy the worker file from `node_modules` into your public assets directory during build/deploy:
3854

3955
```bash
4056
# Example for a Next.js/Vite project with a 'public' directory
4157
cp node_modules/webcodecs-encoder/dist/webcodecs-worker.js public/
4258
```
4359

60+
#### Example: Vite + TypeScript
61+
62+
```ts
63+
// vite.config.ts
64+
import { defineConfig } from 'vite';
65+
import copy from 'rollup-plugin-copy';
66+
67+
export default defineConfig({
68+
plugins: [
69+
copy({
70+
targets: [
71+
{
72+
src: 'node_modules/webcodecs-encoder/dist/webcodecs-worker.js',
73+
dest: 'public'
74+
}
75+
]
76+
})
77+
]
78+
});
79+
```
80+
81+
```ts
82+
// main.ts (development helper)
83+
if (import.meta.env.DEV) {
84+
window.__WEBCODECS_USE_INLINE_WORKER__ = true;
85+
}
86+
```
87+
4488
## Quick Start
4589

4690
### Basic Encoding
@@ -176,7 +220,7 @@ interface EncodeOptions {
176220
177221
/** Set to `false` to disable audio. */
178222
audio?: {
179-
codec?: 'aac' | 'opus';
223+
codec?: 'aac' | 'mp3' | 'opus' | 'vorbis' | 'flac';
180224
bitrate?: number;
181225
sampleRate?: number;
182226
channels?: number;
@@ -225,17 +269,25 @@ interface EncodeOptions {
225269
interface ProgressInfo {
226270
/** Percentage of completion (0-100) */
227271
percent: number;
272+
/** Total number of frames processed */
273+
processedFrames: number;
274+
/** Total number of frames to encode (if known) */
275+
totalFrames?: number;
228276
/** Current encoding speed in frames per second */
229277
fps: number;
230-
/** Total number of frames processed */
231-
frameCount: number;
232-
/** Total number of frames to encode */
233-
totalFrameCount: number;
278+
/** Current stage label ("streaming", "finalizing", etc.) */
279+
stage: string;
234280
/** Estimated remaining time in milliseconds */
235281
estimatedRemainingMs?: number;
236282
}
237283
```
238284

285+
> **Audio codec compatibility**
286+
>
287+
> - `container: 'mp4'` supports `aac` (default) and automatically falls back to `mp3` if AAC isnt available.
288+
> - `container: 'webm'` supports `opus` (default) with `vorbis` and `flac` as fallbacks.
289+
> - Other codec hints are treated as best-effort; if they cant be muxed into the requested container the encoder switches to the first compatible alternative.
290+
239291
### Real-time MediaStream Recording
240292

241293
Use `encodeStream()` for real-time recording from camera, microphone, or screen sharing. This provides progressive encoding with streaming output:
@@ -546,7 +598,6 @@ for (const chunk of chunks) {
546598
- **Better tree-shaking**: Smaller bundle sizes with function imports
547599
- **Streaming support**: Real-time chunk processing
548600
- **Memory efficiency**: Progressive encoding without buffering entire video
549-
- **Cancellation**: Built-in AbortController support
550601
- **Error handling**: Standard async/await error handling
551602

552603
#### Common Migration Patterns
@@ -572,12 +623,16 @@ encodeStream(stream, { onProgress })
572623
**Cancellation**:
573624
```typescript
574625
// Before: recorder.cancel()
575-
// After: AbortController
576-
const controller = new AbortController();
577-
encodeStream(stream, { signal: controller.signal });
578-
controller.abort(); // Cancel encoding
626+
// After: Stop MediaStream tracks or break out of the loop
627+
const stopRecording = () => {
628+
stream.getTracks().forEach(track => track.stop());
629+
};
630+
631+
setTimeout(stopRecording, 5000);
579632
```
580633

634+
> The current implementation does not accept an `AbortSignal`. To cancel `encode` / `encodeStream`, stop the MediaStream tracks or end the async generator manually.
635+
581636
See [`examples/realtime-mediastream.ts`](examples/realtime-mediastream.ts) for complete examples.
582637

583638
## Changelog

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webcodecs-encoder",
3-
"version": "0.3.0",
3+
"version": "0.3.1",
44
"description": "A TypeScript library for browser environments to encode video (H.264/AVC, VP9, VP8) and audio (AAC, Opus) using the WebCodecs API and mux them into MP4 or WebM containers with real-time streaming support. New function-first API design.",
55
"homepage": "https://github.com/romot-co/webcodecs-encoder",
66
"repository": {

0 commit comments

Comments
 (0)