@napi-rs/webcodecs 0.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,7 @@ WebCodecs API implementation for Node.js using FFmpeg, built with [NAPI-RS](http
10
10
  - **Video encoding/decoding** - H.264, H.265, VP8, VP9, AV1
11
11
  - **Audio encoding/decoding** - AAC, Opus, MP3, FLAC, Vorbis, PCM variants
12
12
  - **Image decoding** - JPEG, PNG, WebP, GIF, BMP, AVIF
13
+ - **Canvas integration** - Create VideoFrames from `@napi-rs/canvas` for graphics and text rendering
13
14
  - **Hardware acceleration** - Zero-copy GPU encoding with VideoToolbox (macOS), NVENC (NVIDIA), VAAPI (Linux), QSV (Intel)
14
15
  - **Cross-platform** - macOS, Windows, Linux (glibc/musl, x64/arm64/armv7)
15
16
  - **Structured logging** - FFmpeg logs redirected to Rust `tracing` crate for easy integration
@@ -17,13 +18,21 @@ WebCodecs API implementation for Node.js using FFmpeg, built with [NAPI-RS](http
17
18
  ## Installation
18
19
 
19
20
  ```bash
20
- npm install @napi-rs/webcodecs
21
+ bun add @napi-rs/webcodecs
21
22
  # or
22
23
  pnpm add @napi-rs/webcodecs
23
24
  # or
24
25
  yarn add @napi-rs/webcodecs
25
26
  ```
26
27
 
28
+ ### Optional: Canvas Integration
29
+
30
+ For creating VideoFrames from canvas content, install `@napi-rs/canvas`:
31
+
32
+ ```bash
33
+ npm install @napi-rs/canvas
34
+ ```
35
+
27
36
  ## Quick Start
28
37
 
29
38
  ### Video Encoding
@@ -157,6 +166,39 @@ result.image.close()
157
166
  decoder.close()
158
167
  ```
159
168
 
169
+ ### VideoFrame from Canvas
170
+
171
+ Create VideoFrames from `@napi-rs/canvas` for graphics, text rendering, or image compositing:
172
+
173
+ ```typescript
174
+ import { VideoFrame } from '@napi-rs/webcodecs'
175
+ import { createCanvas } from '@napi-rs/canvas'
176
+
177
+ const canvas = createCanvas(1920, 1080)
178
+ const ctx = canvas.getContext('2d')
179
+
180
+ // Draw graphics
181
+ ctx.fillStyle = '#FF0000'
182
+ ctx.fillRect(0, 0, 1920, 1080)
183
+ ctx.fillStyle = '#FFFFFF'
184
+ ctx.font = '48px sans-serif'
185
+ ctx.fillText('Hello WebCodecs!', 100, 100)
186
+
187
+ // Create VideoFrame from canvas (timestamp required per W3C spec)
188
+ const frame = new VideoFrame(canvas, {
189
+ timestamp: 0,
190
+ duration: 33333, // optional: frame duration in microseconds
191
+ })
192
+
193
+ console.log(frame.format) // 'RGBA'
194
+ console.log(frame.codedWidth, frame.codedHeight) // 1920, 1080
195
+
196
+ // Use with VideoEncoder (see Video Encoding section)
197
+ frame.close()
198
+ ```
199
+
200
+ **Note:** Canvas pixel data is copied as RGBA format with sRGB color space.
201
+
160
202
  ## Supported Codecs
161
203
 
162
204
  ### Video
@@ -213,7 +255,7 @@ This implementation is validated against the [W3C Web Platform Tests](https://gi
213
255
 
214
256
  | Status | Count | Percentage |
215
257
  | ----------- | ----- | ---------- |
216
- | **Passing** | 522 | 99.1% |
258
+ | **Passing** | 573 | 99.1% |
217
259
  | **Skipped** | 5 | 0.9% |
218
260
  | **Failing** | 0 | 0% |
219
261
 
@@ -296,6 +338,40 @@ const encoder = new VideoEncoder({
296
338
  })
297
339
  ```
298
340
 
341
+ ### VideoFrame Format Conversion
342
+
343
+ `VideoFrame.copyTo()` and `VideoFrame.allocationSize()` support format conversion per W3C WebCodecs spec:
344
+
345
+ ```typescript
346
+ const frame = new VideoFrame(i420Data, {
347
+ format: 'I420',
348
+ codedWidth: 1920,
349
+ codedHeight: 1080,
350
+ timestamp: 0,
351
+ })
352
+
353
+ // Get allocation size for RGBA output
354
+ const rgbaSize = frame.allocationSize({ format: 'RGBA' })
355
+
356
+ // Copy with format conversion (I420 → RGBA)
357
+ const rgbaBuffer = new Uint8Array(rgbaSize)
358
+ const layout = await frame.copyTo(rgbaBuffer, { format: 'RGBA' })
359
+
360
+ frame.close()
361
+ ```
362
+
363
+ **Supported conversions:**
364
+
365
+ | Source Format | Target Format | Status |
366
+ | ---------------------------- | ---------------------- | -------------------- |
367
+ | I420, I422, I444, NV12, NV21 | RGBA, RGBX, BGRA, BGRX | ✅ |
368
+ | RGBA, RGBX, BGRA, BGRX | RGBA, RGBX, BGRA, BGRX | ✅ |
369
+ | RGBA, RGBX, BGRA, BGRX | I420, I422, I444, NV12 | ❌ NotSupportedError |
370
+
371
+ Per WPT `videoFrame-copyTo-rgb.any.js`, RGB-to-YUV conversion throws `NotSupportedError`.
372
+
373
+ Custom layouts with overflow-inducing values (e.g., `offset: 2³²-2`) throw `TypeError` via checked arithmetic. Rect alignment is validated against the source format during conversion.
374
+
299
375
  ### ImageDecoder Options
300
376
 
301
377
  ImageDecoder supports all W3C spec options:
@@ -355,7 +431,7 @@ This package implements the [W3C WebCodecs API](https://w3c.github.io/webcodecs/
355
431
 
356
432
  - `VideoEncoder` / `VideoDecoder` - Video encoding and decoding with EventTarget support
357
433
  - `AudioEncoder` / `AudioDecoder` - Audio encoding and decoding with EventTarget support
358
- - `VideoFrame` - Raw video frame data (RGBA formats default to sRGB colorSpace)
434
+ - `VideoFrame` - Raw video frame data (supports buffer data, existing VideoFrame, or `@napi-rs/canvas` Canvas)
359
435
  - `AudioData` - Raw audio sample data
360
436
  - `EncodedVideoChunk` / `EncodedAudioChunk` - Encoded media data
361
437
  - `ImageDecoder` - Static image decoding