webcodecs-node 0.7.1 → 0.7.5

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 (105) hide show
  1. package/README.md +94 -12
  2. package/dist/config/ffmpeg-quality.d.ts +10 -1
  3. package/dist/config/ffmpeg-quality.d.ts.map +1 -1
  4. package/dist/config/ffmpeg-quality.js +12 -38
  5. package/dist/config/ffmpeg-quality.js.map +1 -1
  6. package/dist/config/webcodecs-config.d.ts +58 -0
  7. package/dist/config/webcodecs-config.d.ts.map +1 -0
  8. package/dist/config/webcodecs-config.js +187 -0
  9. package/dist/config/webcodecs-config.js.map +1 -0
  10. package/dist/containers/Demuxer.d.ts +3 -1
  11. package/dist/containers/Demuxer.d.ts.map +1 -1
  12. package/dist/containers/Demuxer.js +26 -19
  13. package/dist/containers/Demuxer.js.map +1 -1
  14. package/dist/containers/FFmpegMuxer.d.ts +42 -0
  15. package/dist/containers/FFmpegMuxer.d.ts.map +1 -0
  16. package/dist/containers/FFmpegMuxer.js +311 -0
  17. package/dist/containers/FFmpegMuxer.js.map +1 -0
  18. package/dist/containers/FFmpegSpawnMuxer.d.ts +42 -0
  19. package/dist/containers/FFmpegSpawnMuxer.d.ts.map +1 -0
  20. package/dist/containers/FFmpegSpawnMuxer.js +311 -0
  21. package/dist/containers/FFmpegSpawnMuxer.js.map +1 -0
  22. package/dist/containers/FallbackMuxer.d.ts +42 -0
  23. package/dist/containers/FallbackMuxer.d.ts.map +1 -0
  24. package/dist/containers/FallbackMuxer.js +311 -0
  25. package/dist/containers/FallbackMuxer.js.map +1 -0
  26. package/dist/containers/Muxer.d.ts +75 -107
  27. package/dist/containers/Muxer.d.ts.map +1 -1
  28. package/dist/containers/Muxer.js +184 -243
  29. package/dist/containers/Muxer.js.map +1 -1
  30. package/dist/containers/MuxerWithFallback.d.ts +110 -0
  31. package/dist/containers/MuxerWithFallback.d.ts.map +1 -0
  32. package/dist/containers/MuxerWithFallback.js +239 -0
  33. package/dist/containers/MuxerWithFallback.js.map +1 -0
  34. package/dist/containers/NodeAvMuxer.d.ts +118 -0
  35. package/dist/containers/NodeAvMuxer.d.ts.map +1 -0
  36. package/dist/containers/NodeAvMuxer.js +338 -0
  37. package/dist/containers/NodeAvMuxer.js.map +1 -0
  38. package/dist/containers/extract.d.ts.map +1 -1
  39. package/dist/containers/extract.js +3 -1
  40. package/dist/containers/extract.js.map +1 -1
  41. package/dist/containers/index.d.ts +20 -14
  42. package/dist/containers/index.d.ts.map +1 -1
  43. package/dist/containers/index.js +21 -14
  44. package/dist/containers/index.js.map +1 -1
  45. package/dist/containers/muxer-types.d.ts +117 -0
  46. package/dist/containers/muxer-types.d.ts.map +1 -0
  47. package/dist/containers/muxer-types.js +45 -0
  48. package/dist/containers/muxer-types.js.map +1 -0
  49. package/dist/containers/transcode.d.ts.map +1 -1
  50. package/dist/containers/transcode.js +171 -150
  51. package/dist/containers/transcode.js.map +1 -1
  52. package/dist/core/VideoFrame.d.ts +19 -0
  53. package/dist/core/VideoFrame.d.ts.map +1 -1
  54. package/dist/core/VideoFrame.js +11 -0
  55. package/dist/core/VideoFrame.js.map +1 -1
  56. package/dist/decoders/VideoDecoder.d.ts +1 -0
  57. package/dist/decoders/VideoDecoder.d.ts.map +1 -1
  58. package/dist/decoders/VideoDecoder.js +6 -4
  59. package/dist/decoders/VideoDecoder.js.map +1 -1
  60. package/dist/demos/demo-audio-visualizer-mediabunny.d.ts +10 -0
  61. package/dist/demos/demo-audio-visualizer-mediabunny.d.ts.map +1 -0
  62. package/dist/demos/demo-audio-visualizer-mediabunny.js +357 -0
  63. package/dist/demos/demo-audio-visualizer-mediabunny.js.map +1 -0
  64. package/dist/demos/demo-audio-visualizer-nodeav.d.ts +10 -0
  65. package/dist/demos/demo-audio-visualizer-nodeav.d.ts.map +1 -0
  66. package/dist/demos/demo-audio-visualizer-nodeav.js +318 -0
  67. package/dist/demos/demo-audio-visualizer-nodeav.js.map +1 -0
  68. package/dist/demos/demo-muxer-fallback.d.ts +8 -0
  69. package/dist/demos/demo-muxer-fallback.d.ts.map +1 -0
  70. package/dist/demos/demo-muxer-fallback.js +165 -0
  71. package/dist/demos/demo-muxer-fallback.js.map +1 -0
  72. package/dist/encoders/AudioEncoder.d.ts +2 -0
  73. package/dist/encoders/AudioEncoder.d.ts.map +1 -1
  74. package/dist/encoders/AudioEncoder.js +7 -4
  75. package/dist/encoders/AudioEncoder.js.map +1 -1
  76. package/dist/hardware/decoder-args.d.ts.map +1 -1
  77. package/dist/hardware/decoder-args.js +35 -14
  78. package/dist/hardware/decoder-args.js.map +1 -1
  79. package/dist/hardware/detection.d.ts.map +1 -1
  80. package/dist/hardware/detection.js +39 -0
  81. package/dist/hardware/detection.js.map +1 -1
  82. package/dist/hardware/encoder-args.d.ts.map +1 -1
  83. package/dist/hardware/encoder-args.js +43 -5
  84. package/dist/hardware/encoder-args.js.map +1 -1
  85. package/dist/hardware/types.d.ts.map +1 -1
  86. package/dist/hardware/types.js +30 -28
  87. package/dist/hardware/types.js.map +1 -1
  88. package/dist/node-av/NodeAvVideoEncoder.d.ts +5 -0
  89. package/dist/node-av/NodeAvVideoEncoder.d.ts.map +1 -1
  90. package/dist/node-av/NodeAvVideoEncoder.js +76 -23
  91. package/dist/node-av/NodeAvVideoEncoder.js.map +1 -1
  92. package/dist/utils/avc.d.ts +2 -0
  93. package/dist/utils/avc.d.ts.map +1 -1
  94. package/dist/utils/avc.js +36 -8
  95. package/dist/utils/avc.js.map +1 -1
  96. package/dist/utils/codec-validation.d.ts.map +1 -1
  97. package/dist/utils/codec-validation.js +12 -6
  98. package/dist/utils/codec-validation.js.map +1 -1
  99. package/dist/utils/hevc.d.ts +2 -0
  100. package/dist/utils/hevc.d.ts.map +1 -1
  101. package/dist/utils/hevc.js +42 -8
  102. package/dist/utils/hevc.js.map +1 -1
  103. package/docs/api.md +52 -2
  104. package/docs/configuration.md +10 -7
  105. package/package.json +1 -1
package/docs/api.md CHANGED
@@ -57,15 +57,19 @@ Configure the encoder. Must be called before encoding.
57
57
  **VideoEncoderConfig:**
58
58
  | Property | Type | Required | Description |
59
59
  |----------|------|----------|-------------|
60
- | `codec` | string | Yes | Codec string (e.g., 'avc1.42001E', 'vp9') |
60
+ | `codec` | string | Yes | Codec string (e.g., 'avc1.42001E', 'vp9', 'av1') |
61
61
  | `width` | number | Yes | Frame width in pixels |
62
62
  | `height` | number | Yes | Frame height in pixels |
63
+ | `displayWidth` | number | No | Display width (for non-square pixels) |
64
+ | `displayHeight` | number | No | Display height (for non-square pixels) |
63
65
  | `bitrate` | number | No | Target bitrate in bits/second |
64
66
  | `framerate` | number | No | Target framerate |
65
67
  | `bitrateMode` | 'constant' \| 'variable' \| 'quantizer' | No | Bitrate control mode |
66
68
  | `alpha` | 'discard' \| 'keep' | No | Alpha channel handling |
67
69
  | `latencyMode` | 'quality' \| 'realtime' | No | Latency vs quality tradeoff |
68
70
  | `hardwareAcceleration` | 'no-preference' \| 'prefer-hardware' \| 'prefer-software' | No | Hardware acceleration preference |
71
+ | `scalabilityMode` | string | No | SVC scalability mode (e.g., 'L1T2') |
72
+ | `format` | 'mp4' \| 'annexb' | No | Output format: 'mp4' (default) for length-prefixed, 'annexb' for raw bitstreams |
69
73
  | `maxQueueSize` | number | No | Max pending frames before QuotaExceededError. Auto-calculated from resolution if not set (~300MB target memory). |
70
74
 
71
75
  #### `encode(frame: VideoFrame, options?: VideoEncoderEncodeOptions): void`
@@ -124,7 +128,13 @@ Check if a configuration is supported.
124
128
  | `codec` | string | Yes | Codec string |
125
129
  | `codedWidth` | number | No | Coded frame width |
126
130
  | `codedHeight` | number | No | Coded frame height |
131
+ | `displayAspectWidth` | number | No | Display aspect ratio width |
132
+ | `displayAspectHeight` | number | No | Display aspect ratio height |
127
133
  | `description` | BufferSource | No | Codec-specific data (e.g., SPS/PPS for H.264) |
134
+ | `colorSpace` | VideoColorSpaceInit | No | Color space configuration |
135
+ | `hardwareAcceleration` | 'no-preference' \| 'prefer-hardware' \| 'prefer-software' | No | Hardware acceleration preference |
136
+ | `optimizeForLatency` | boolean | No | Optimize for low latency decoding |
137
+ | `outputFormat` | VideoPixelFormat | No | Preferred output pixel format |
128
138
  | `maxQueueSize` | number | No | Max pending chunks before QuotaExceededError. Auto-calculated from resolution if dimensions provided (~300MB target memory). |
129
139
 
130
140
  #### `decode(chunk: EncodedVideoChunk): void`
@@ -174,7 +184,10 @@ new AudioEncoder(init: AudioEncoderInit)
174
184
  | `codec` | string | Yes | Codec string (e.g., 'opus', 'mp4a.40.2') |
175
185
  | `sampleRate` | number | Yes | Sample rate in Hz |
176
186
  | `numberOfChannels` | number | Yes | Number of audio channels |
177
- | `bitrate` | number | No | Target bitrate |
187
+ | `bitrate` | number | No | Target bitrate in bits/second |
188
+ | `bitrateMode` | 'constant' \| 'variable' | No | Bitrate control mode |
189
+ | `latencyMode` | 'quality' \| 'realtime' | No | Latency vs quality tradeoff |
190
+ | `format` | 'adts' \| 'aac' | No | Output format: 'adts' (default) for ADTS headers, 'aac' for raw AAC frames |
178
191
 
179
192
  #### `encode(data: AudioData): void`
180
193
 
@@ -209,6 +222,7 @@ new AudioDecoder(init: AudioDecoderInit)
209
222
  | `sampleRate` | number | Yes | Sample rate in Hz |
210
223
  | `numberOfChannels` | number | Yes | Number of channels |
211
224
  | `description` | BufferSource | No | Codec-specific data |
225
+ | `outputFormat` | AudioSampleFormat | No | Preferred output sample format (default: 'f32') |
212
226
 
213
227
  #### `decode(chunk: EncodedAudioChunk): void`
214
228
 
@@ -396,6 +410,10 @@ new VideoFrame(data: BufferSource, init: VideoFrameBufferInit)
396
410
 
397
411
  Get buffer size needed for copyTo.
398
412
 
413
+ #### `metadata(): VideoFrameMetadata`
414
+
415
+ Returns metadata associated with this VideoFrame. Currently returns an empty object as metadata fields (like `rtpTimestamp` for WebRTC) will be added as needed per W3C spec.
416
+
399
417
  #### `copyTo(destination: BufferSource, options?: VideoFrameCopyToOptions): Promise<PlaneLayout[]>`
400
418
 
401
419
  Copy frame data to a buffer.
@@ -659,3 +677,35 @@ export WEBCODECS_CAPABILITIES_PROFILE=$(pwd)/webcodecs-capabilities.json
659
677
  ```
660
678
 
661
679
  The JSON follows the `CapabilityProfile` schema (see `src/capabilities/types.ts`). If no profile is provided, `mediaCapabilities` falls back to built-in heuristics based on resolution, bitrate, and detected hardware acceleration.
680
+
681
+ ---
682
+
683
+ ## Known Limitations
684
+
685
+ ### Encoder Frame Batching
686
+
687
+ When using `latencyMode: 'quality'` (the default), FFmpeg encoders may buffer frames for better compression. This means:
688
+
689
+ - Multiple `encode()` calls may produce fewer output chunks than input frames
690
+ - All frames are output after `flush()`, but may be batched
691
+
692
+ **Workaround:** Use `latencyMode: 'realtime'` for 1:1 frame-to-chunk output:
693
+
694
+ ```typescript
695
+ encoder.configure({
696
+ codec: 'vp8',
697
+ width: 640,
698
+ height: 480,
699
+ latencyMode: 'realtime', // Disables frame buffering
700
+ });
701
+ ```
702
+
703
+ ### Codec String Validation
704
+
705
+ The `isConfigSupported()` method performs strict codec string validation per the WebCodecs specification:
706
+
707
+ - **Case-sensitive:** `vP8` or `VP8` returns `supported: false` (use `vp8`)
708
+ - **Fully qualified VP9/AV1:** Ambiguous `vp9` returns `supported: false` (use `vp09.00.10.08`)
709
+ - **Valid parameters:** Unknown profiles/levels return `supported: false`
710
+
711
+ Note: `configure()` is more lenient and accepts simple codec strings like `vp9` for FFmpeg compatibility.
@@ -100,10 +100,10 @@ encoder.configure({
100
100
 
101
101
  `crf` and `preset` are **extensions** (not part of the WebCodecs spec). They are loaded globally from a JS file and passed to FFmpeg when supported.
102
102
 
103
- Edit `ffmpeg-quality.js` in the project root:
103
+ Edit `webcodecs-config.js` in the project root:
104
104
 
105
105
  ```javascript
106
- export default {
106
+ module.exports = {
107
107
  // Global overrides:
108
108
  // crf: 28,
109
109
  // preset: 'veryfast',
@@ -113,12 +113,15 @@ export default {
113
113
  // h264: { crf: 30, preset: 'veryfast' },
114
114
  // hevc: { crf: 28, preset: 'medium' },
115
115
  // },
116
+
117
+ // Hardware acceleration priority (optional):
118
+ // hwaccel: ['nvenc', 'qsv', 'vaapi'],
116
119
  };
117
120
  ```
118
121
 
119
122
  **Notes:**
120
123
  - If the file is missing, no overrides are applied.
121
- - The file is loaded from `process.cwd()` or from `WEB_CODECS_FFMPEG_QUALITY`.
124
+ - The file is loaded from `process.cwd()` or from `WEBCODECS_CONFIG` env var.
122
125
 
123
126
  ---
124
127
 
@@ -147,16 +150,16 @@ The `alpha` option controls how transparent pixels are handled during encoding.
147
150
 
148
151
  ## Output Bitstream Format
149
152
 
150
- By default the encoders emit Annex B (video) and ADTS/OGG (audio) bitstreams. If you need MP4-style payloads (length-prefixed NAL units, raw AAC frames) you can opt-in via the `format` config field.
153
+ By default the video encoder emits MP4-style payloads (length-prefixed NAL units) with `decoderConfig.description`. Audio encoders default to ADTS/OGG bitstreams, with an option for raw AAC frames.
151
154
 
152
155
  ### VideoEncoder `format`
153
156
 
154
157
  | Value | Description |
155
158
  |-------|-------------|
156
- | `'annexb'` (default) | Emit Annex B/IVF bitstreams (same as before). |
157
- | `'mp4'` | Convert AnnexB output into length-prefixed avcC/hvcc samples and include `decoderConfig.description`. |
159
+ | `'mp4'` (default) | Emit length-prefixed avcC/hvcc samples with `decoderConfig.description` for MP4 muxing. |
160
+ | `'annexb'` | Emit raw Annex B bitstreams with start codes (for raw streaming or ffmpeg piping). |
158
161
 
159
- When `format: 'mp4'` is set the encoder automatically extracts SPS/PPS/VPS from keyframes and exposes them in metadata so an MP4 muxer can use them.
162
+ With the default `format: 'mp4'`, the encoder automatically extracts SPS/PPS/VPS from keyframes and exposes them in metadata so an MP4 muxer can use them.
160
163
 
161
164
  ### AudioEncoder `format`
162
165
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webcodecs-node",
3
- "version": "0.7.1",
3
+ "version": "0.7.5",
4
4
  "description": "WebCodecs API implementation for Node.js using node-av",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",