@napi-rs/webcodecs 1.0.0 → 1.1.1

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.
Files changed (4) hide show
  1. package/README.md +147 -1
  2. package/index.d.ts +620 -24
  3. package/index.js +58 -52
  4. package/package.json +12 -11
package/README.md CHANGED
@@ -9,6 +9,7 @@ WebCodecs API implementation for Node.js using FFmpeg, built with [NAPI-RS](http
9
9
  - **W3C WebCodecs API compliant** - Full implementation of the WebCodecs specification with native `DOMException` errors
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
+ - **Container muxing/demuxing** - MP4, WebM, MKV containers with seeking support
12
13
  - **Image decoding** - JPEG, PNG, WebP, GIF, BMP, AVIF
13
14
  - **Canvas integration** - Create VideoFrames from `@napi-rs/canvas` for graphics and text rendering
14
15
  - **Hardware acceleration** - Zero-copy GPU encoding with VideoToolbox (macOS), NVENC (NVIDIA), VAAPI (Linux), QSV (Intel)
@@ -18,7 +19,7 @@ WebCodecs API implementation for Node.js using FFmpeg, built with [NAPI-RS](http
18
19
  ## Installation
19
20
 
20
21
  ```bash
21
- npm install @napi-rs/webcodecs
22
+ bun add @napi-rs/webcodecs
22
23
  # or
23
24
  pnpm add @napi-rs/webcodecs
24
25
  # or
@@ -166,6 +167,141 @@ result.image.close()
166
167
  decoder.close()
167
168
  ```
168
169
 
170
+ ### Container Demuxing
171
+
172
+ Read encoded video/audio from MP4, WebM, or MKV containers:
173
+
174
+ ```typescript
175
+ import { Mp4Demuxer, VideoDecoder, AudioDecoder } from '@napi-rs/webcodecs'
176
+
177
+ // Create decoder instances
178
+ const videoDecoder = new VideoDecoder({
179
+ output: (frame) => {
180
+ console.log(`Decoded frame: ${frame.timestamp}`)
181
+ frame.close()
182
+ },
183
+ error: (e) => console.error(e),
184
+ })
185
+
186
+ const audioDecoder = new AudioDecoder({
187
+ output: (data) => {
188
+ console.log(`Decoded audio: ${data.timestamp}`)
189
+ data.close()
190
+ },
191
+ error: (e) => console.error(e),
192
+ })
193
+
194
+ // Create demuxer with callbacks
195
+ const demuxer = new Mp4Demuxer({
196
+ videoOutput: (chunk) => videoDecoder.decode(chunk),
197
+ audioOutput: (chunk) => audioDecoder.decode(chunk),
198
+ error: (e) => console.error(e),
199
+ })
200
+
201
+ // Load from file or buffer
202
+ await demuxer.load('./video.mp4')
203
+ // or: await demuxer.loadBuffer(uint8Array)
204
+
205
+ // Configure decoders with extracted configs
206
+ videoDecoder.configure(demuxer.videoDecoderConfig)
207
+ audioDecoder.configure(demuxer.audioDecoderConfig)
208
+
209
+ // Get track info
210
+ console.log(demuxer.tracks) // Array of track info
211
+ console.log(demuxer.duration) // Duration in microseconds
212
+
213
+ // Demux all packets (calls callbacks)
214
+ demuxer.demux()
215
+
216
+ // Or demux in batches
217
+ demuxer.demux(100) // Demux up to 100 packets
218
+
219
+ // Seek to timestamp (microseconds)
220
+ demuxer.seek(5_000_000) // Seek to 5 seconds
221
+
222
+ demuxer.close()
223
+ ```
224
+
225
+ ### Container Muxing
226
+
227
+ Write encoded video/audio to MP4, WebM, or MKV containers:
228
+
229
+ ```typescript
230
+ import { Mp4Muxer, VideoEncoder, AudioEncoder } from '@napi-rs/webcodecs'
231
+ import { writeFileSync } from 'fs'
232
+
233
+ // Create muxer
234
+ const muxer = new Mp4Muxer({ fastStart: true })
235
+
236
+ // Track description will be set from encoder metadata
237
+ let videoDescription: Uint8Array | undefined
238
+
239
+ // Create encoder that feeds into muxer
240
+ const videoEncoder = new VideoEncoder({
241
+ output: (chunk, metadata) => {
242
+ // Capture codec description from first keyframe
243
+ if (metadata?.decoderConfig?.description) {
244
+ videoDescription = metadata.decoderConfig.description
245
+ }
246
+ muxer.addVideoChunk(chunk, metadata)
247
+ },
248
+ error: (e) => console.error(e),
249
+ })
250
+
251
+ videoEncoder.configure({
252
+ codec: 'avc1.42001E',
253
+ width: 1920,
254
+ height: 1080,
255
+ bitrate: 5_000_000,
256
+ })
257
+
258
+ // Add tracks before adding chunks
259
+ muxer.addVideoTrack({
260
+ codec: 'avc1.42001E',
261
+ width: 1920,
262
+ height: 1080,
263
+ })
264
+
265
+ // Encode frames...
266
+ // videoEncoder.encode(frame)
267
+
268
+ await videoEncoder.flush()
269
+
270
+ // Finalize and write output
271
+ const mp4Data = muxer.finalize()
272
+ writeFileSync('output.mp4', mp4Data)
273
+ muxer.close()
274
+ ```
275
+
276
+ #### Streaming Muxer Mode
277
+
278
+ For live streaming or large files, use streaming mode:
279
+
280
+ ```typescript
281
+ import { Mp4Muxer } from '@napi-rs/webcodecs'
282
+
283
+ const muxer = new Mp4Muxer({
284
+ fragmented: true, // Required for MP4 streaming
285
+ streaming: { bufferCapacity: 256 * 1024 },
286
+ })
287
+
288
+ muxer.addVideoTrack({ codec: 'avc1.42001E', width: 1920, height: 1080 })
289
+
290
+ // Add chunks as they arrive
291
+ muxer.addVideoChunk(chunk, metadata)
292
+
293
+ // Read available data incrementally
294
+ const data = muxer.read()
295
+ if (data) {
296
+ stream.write(data)
297
+ }
298
+
299
+ // Check when finished
300
+ if (muxer.isFinished) {
301
+ stream.end()
302
+ }
303
+ ```
304
+
169
305
  ### VideoFrame from Canvas
170
306
 
171
307
  Create VideoFrames from `@napi-rs/canvas` for graphics, text rendering, or image compositing:
@@ -235,6 +371,14 @@ frame.close()
235
371
  | BMP | `image/bmp` | ✅ |
236
372
  | AVIF | `image/avif` | ✅ |
237
373
 
374
+ ### Containers
375
+
376
+ | Container | Video Codecs | Audio Codecs | Demuxer | Muxer |
377
+ | --------- | --------------------------- | ---------------------------- | ------------- | ----------- |
378
+ | MP4 | H.264, H.265, AV1 | AAC, Opus, MP3, FLAC | `Mp4Demuxer` | `Mp4Muxer` |
379
+ | WebM | VP8, VP9, AV1 | Opus, Vorbis | `WebMDemuxer` | `WebMMuxer` |
380
+ | MKV | H.264, H.265, VP8, VP9, AV1 | AAC, Opus, Vorbis, FLAC, MP3 | `MkvDemuxer` | `MkvMuxer` |
381
+
238
382
  ## Platform Support
239
383
 
240
384
  Pre-built binaries are available for:
@@ -436,6 +580,8 @@ This package implements the [W3C WebCodecs API](https://w3c.github.io/webcodecs/
436
580
  - `EncodedVideoChunk` / `EncodedAudioChunk` - Encoded media data
437
581
  - `ImageDecoder` - Static image decoding
438
582
  - `VideoColorSpace` - Color space information
583
+ - `Mp4Demuxer` / `WebMDemuxer` / `MkvDemuxer` - Container demuxing with seeking
584
+ - `Mp4Muxer` / `WebMMuxer` / `MkvMuxer` - Container muxing with streaming support
439
585
 
440
586
  All encoders and decoders implement the `EventTarget` interface with `addEventListener()`, `removeEventListener()`, and `dispatchEvent()`.
441
587