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
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Demo: Audio Visualizer (node-av Muxer version)
3
+ *
4
+ * Same as demo-audio-visualizer.ts but uses node-av Muxer directly
5
+ * instead of spawning FFmpeg for muxing. This should be faster.
6
+ *
7
+ * Outputs both video and audio encoded in-process, then muxes them together.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=demo-audio-visualizer-nodeav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo-audio-visualizer-nodeav.d.ts","sourceRoot":"","sources":["../../src/demos/demo-audio-visualizer-nodeav.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Demo: Audio Visualizer (node-av Muxer version)
3
+ *
4
+ * Same as demo-audio-visualizer.ts but uses node-av Muxer directly
5
+ * instead of spawning FFmpeg for muxing. This should be faster.
6
+ *
7
+ * Outputs both video and audio encoded in-process, then muxes them together.
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import { createCanvas, getRawPixels } from '../canvas/index.js';
12
+ import { VideoEncoder } from '../encoders/VideoEncoder.js';
13
+ import { AudioEncoder } from '../encoders/AudioEncoder.js';
14
+ import { VideoFrame } from '../core/VideoFrame.js';
15
+ import { AudioData } from '../core/AudioData.js';
16
+ import { NodeAvMuxer } from '../containers/NodeAvMuxer.js';
17
+ const WIDTH = 800;
18
+ const HEIGHT = 600;
19
+ const DURATION_SECONDS = 10;
20
+ const FRAME_RATE = 30;
21
+ const SAMPLE_RATE = 48000;
22
+ const AUDIO_CHANNELS = 2;
23
+ const FRAME_COUNT = DURATION_SECONDS * FRAME_RATE;
24
+ const FRAME_DURATION_US = Math.round(1_000_000 / FRAME_RATE);
25
+ const SAMPLES_PER_FRAME = Math.round(SAMPLE_RATE / FRAME_RATE);
26
+ const OUTPUT_DIR = path.resolve('media', 'visualizer-demo');
27
+ const OUTPUT_VIDEO = path.join(OUTPUT_DIR, 'visualizer-nodeav.mp4');
28
+ // Musical frequencies (A minor pentatonic scale)
29
+ const FREQUENCIES = [220, 261.63, 329.63, 392, 440, 523.25, 659.25, 783.99];
30
+ // Visualization colors
31
+ const COLORS = {
32
+ background: '#1a1a2e',
33
+ waveform: '#00ff88',
34
+ bars: ['#ff0080', '#ff4080', '#ff8080', '#ffaa00', '#ffff00', '#80ff00', '#00ff80', '#00ffff'],
35
+ text: '#ffffff',
36
+ grid: '#333355',
37
+ };
38
+ function generateAudioSamples(state, numSamples, sampleRate, startSample) {
39
+ const samples = new Float32Array(numSamples * AUDIO_CHANNELS);
40
+ for (let i = 0; i < numSamples; i++) {
41
+ const t = (startSample + i) / sampleRate;
42
+ let sample = 0;
43
+ // Mix multiple frequencies with their amplitudes
44
+ for (let f = 0; f < state.frequencies.length; f++) {
45
+ const freq = state.frequencies[f];
46
+ const amp = state.amplitudes[f];
47
+ const phase = state.phases[f];
48
+ sample += Math.sin(2 * Math.PI * freq * t + phase) * amp;
49
+ }
50
+ // Normalize
51
+ sample = sample / state.frequencies.length * 0.7;
52
+ // Stereo (same for both channels)
53
+ samples[i * AUDIO_CHANNELS] = sample;
54
+ samples[i * AUDIO_CHANNELS + 1] = sample;
55
+ }
56
+ return samples;
57
+ }
58
+ function drawWaveform(ctx, samples, x, y, width, height) {
59
+ const step = Math.ceil(samples.length / AUDIO_CHANNELS / width);
60
+ const centerY = y + height / 2;
61
+ ctx.beginPath();
62
+ ctx.strokeStyle = COLORS.waveform;
63
+ ctx.lineWidth = 2;
64
+ for (let i = 0; i < width; i++) {
65
+ const sampleIndex = Math.min(i * step, samples.length / AUDIO_CHANNELS - 1);
66
+ const sample = samples[sampleIndex * AUDIO_CHANNELS];
67
+ const py = centerY - sample * (height / 2) * 0.9;
68
+ if (i === 0) {
69
+ ctx.moveTo(x + i, py);
70
+ }
71
+ else {
72
+ ctx.lineTo(x + i, py);
73
+ }
74
+ }
75
+ ctx.stroke();
76
+ }
77
+ function drawSpectrumBars(ctx, amplitudes, x, y, width, height, time) {
78
+ const numBars = amplitudes.length;
79
+ const barWidth = (width / numBars) * 0.8;
80
+ const gap = (width / numBars) * 0.2;
81
+ for (let i = 0; i < numBars; i++) {
82
+ // Add some animation to the bars
83
+ const animatedAmp = amplitudes[i] * (0.8 + 0.2 * Math.sin(time * 5 + i));
84
+ const barHeight = animatedAmp * height * 0.9;
85
+ const bx = x + i * (barWidth + gap) + gap / 2;
86
+ const by = y + height - barHeight;
87
+ // Gradient effect
88
+ const gradient = ctx.createLinearGradient(bx, by, bx, y + height);
89
+ gradient.addColorStop(0, COLORS.bars[i % COLORS.bars.length]);
90
+ gradient.addColorStop(1, '#000033');
91
+ ctx.fillStyle = gradient;
92
+ // Rounded rectangle
93
+ const radius = barWidth / 4;
94
+ ctx.beginPath();
95
+ ctx.moveTo(bx + radius, by);
96
+ ctx.lineTo(bx + barWidth - radius, by);
97
+ ctx.quadraticCurveTo(bx + barWidth, by, bx + barWidth, by + radius);
98
+ ctx.lineTo(bx + barWidth, y + height);
99
+ ctx.lineTo(bx, y + height);
100
+ ctx.lineTo(bx, by + radius);
101
+ ctx.quadraticCurveTo(bx, by, bx + radius, by);
102
+ ctx.fill();
103
+ }
104
+ }
105
+ function drawGrid(ctx, width, height) {
106
+ ctx.strokeStyle = COLORS.grid;
107
+ ctx.lineWidth = 1;
108
+ // Horizontal lines
109
+ for (let y = 0; y < height; y += 50) {
110
+ ctx.beginPath();
111
+ ctx.moveTo(0, y);
112
+ ctx.lineTo(width, y);
113
+ ctx.stroke();
114
+ }
115
+ // Vertical lines
116
+ for (let x = 0; x < width; x += 50) {
117
+ ctx.beginPath();
118
+ ctx.moveTo(x, 0);
119
+ ctx.lineTo(x, height);
120
+ ctx.stroke();
121
+ }
122
+ }
123
+ function drawLabels(ctx, frequencies, time) {
124
+ ctx.fillStyle = COLORS.text;
125
+ ctx.font = '16px monospace';
126
+ ctx.textAlign = 'left';
127
+ // Title
128
+ ctx.font = 'bold 24px sans-serif';
129
+ ctx.fillText('Audio Visualizer (node-av)', 20, 35);
130
+ // Time
131
+ ctx.font = '16px monospace';
132
+ ctx.fillText(`Time: ${time.toFixed(2)}s`, WIDTH - 120, 35);
133
+ // Frequency labels
134
+ ctx.font = '12px monospace';
135
+ ctx.textAlign = 'center';
136
+ const barWidth = (WIDTH - 40) / frequencies.length;
137
+ for (let i = 0; i < frequencies.length; i++) {
138
+ const x = 20 + i * barWidth + barWidth / 2;
139
+ ctx.fillText(`${frequencies[i].toFixed(0)}Hz`, x, HEIGHT - 10);
140
+ }
141
+ }
142
+ async function main() {
143
+ console.log('╔═══════════════════════════════════════════════════════════════╗');
144
+ console.log('║ Audio Visualizer Demo (node-av Muxer) ║');
145
+ console.log('╚═══════════════════════════════════════════════════════════════╝\n');
146
+ fs.mkdirSync(OUTPUT_DIR, { recursive: true });
147
+ // Initialize audio state with varying amplitudes
148
+ const audioState = {
149
+ frequencies: FREQUENCIES.slice(0, 8),
150
+ amplitudes: [0.8, 0.6, 0.7, 0.5, 0.9, 0.4, 0.6, 0.7],
151
+ phases: FREQUENCIES.map((_, i) => (i * Math.PI) / 4),
152
+ };
153
+ // Create canvas
154
+ const canvas = createCanvas({ width: WIDTH, height: HEIGHT });
155
+ const ctx = canvas.getContext('2d');
156
+ // Collect encoded chunks
157
+ const videoChunks = [];
158
+ const audioChunks = [];
159
+ let videoDescription;
160
+ let audioDescription;
161
+ // Video encoder
162
+ const videoEncoder = new VideoEncoder({
163
+ output: (chunk, metadata) => {
164
+ videoChunks.push(chunk);
165
+ if (metadata?.decoderConfig?.description && !videoDescription) {
166
+ const desc = metadata.decoderConfig.description;
167
+ videoDescription = desc instanceof Uint8Array ? desc : new Uint8Array(desc);
168
+ }
169
+ },
170
+ error: (err) => console.error('Video encoder error:', err),
171
+ });
172
+ videoEncoder.configure({
173
+ codec: 'avc1.64001E',
174
+ width: WIDTH,
175
+ height: HEIGHT,
176
+ framerate: FRAME_RATE,
177
+ bitrate: 4_000_000,
178
+ latencyMode: 'quality',
179
+ hardwareAcceleration: 'prefer-hardware',
180
+ });
181
+ // Audio encoder
182
+ const audioEncoder = new AudioEncoder({
183
+ output: (chunk, metadata) => {
184
+ audioChunks.push(chunk);
185
+ if (metadata?.decoderConfig?.description && !audioDescription) {
186
+ const desc = metadata.decoderConfig.description;
187
+ audioDescription = desc instanceof Uint8Array ? desc : new Uint8Array(desc);
188
+ }
189
+ },
190
+ error: (err) => console.error('Audio encoder error:', err),
191
+ });
192
+ audioEncoder.configure({
193
+ codec: 'mp4a.40.2', // AAC-LC
194
+ sampleRate: SAMPLE_RATE,
195
+ numberOfChannels: AUDIO_CHANNELS,
196
+ bitrate: 128_000,
197
+ });
198
+ console.log(` Resolution: ${WIDTH}x${HEIGHT}`);
199
+ console.log(` Duration: ${DURATION_SECONDS}s`);
200
+ console.log(` Frequencies: ${audioState.frequencies.map(f => f.toFixed(0) + 'Hz').join(', ')}`);
201
+ console.log(` Encoding...\n`);
202
+ const startTime = Date.now();
203
+ let totalSamples = 0;
204
+ for (let i = 0; i < FRAME_COUNT; i++) {
205
+ // Backpressure: wait if encoder queues are getting full
206
+ while (videoEncoder.encodeQueueSize >= 50 || audioEncoder.encodeQueueSize >= 50) {
207
+ await new Promise((resolve) => setTimeout(resolve, 10));
208
+ }
209
+ const time = i / FRAME_RATE;
210
+ const timestamp = i * FRAME_DURATION_US;
211
+ // Animate amplitudes over time
212
+ for (let f = 0; f < audioState.amplitudes.length; f++) {
213
+ audioState.amplitudes[f] = 0.3 + 0.5 * Math.abs(Math.sin(time * 0.5 + f * 0.7));
214
+ }
215
+ // Generate audio samples for this frame
216
+ const samples = generateAudioSamples(audioState, SAMPLES_PER_FRAME, SAMPLE_RATE, totalSamples);
217
+ totalSamples += SAMPLES_PER_FRAME;
218
+ // Encode audio samples
219
+ const audioData = new AudioData({
220
+ format: 'f32-planar',
221
+ sampleRate: SAMPLE_RATE,
222
+ numberOfFrames: SAMPLES_PER_FRAME,
223
+ numberOfChannels: AUDIO_CHANNELS,
224
+ timestamp,
225
+ data: samples,
226
+ });
227
+ audioEncoder.encode(audioData);
228
+ audioData.close();
229
+ // Draw visualization
230
+ ctx.fillStyle = COLORS.background;
231
+ ctx.fillRect(0, 0, WIDTH, HEIGHT);
232
+ drawGrid(ctx, WIDTH, HEIGHT);
233
+ // Waveform in top half
234
+ drawWaveform(ctx, samples, 20, 60, WIDTH - 40, HEIGHT / 2 - 80);
235
+ // Spectrum bars in bottom half
236
+ drawSpectrumBars(ctx, audioState.amplitudes, 20, HEIGHT / 2 + 20, WIDTH - 40, HEIGHT / 2 - 60, time);
237
+ // Labels
238
+ drawLabels(ctx, audioState.frequencies, time);
239
+ // Divider line
240
+ ctx.strokeStyle = COLORS.grid;
241
+ ctx.lineWidth = 2;
242
+ ctx.beginPath();
243
+ ctx.moveTo(0, HEIGHT / 2);
244
+ ctx.lineTo(WIDTH, HEIGHT / 2);
245
+ ctx.stroke();
246
+ // Create video frame
247
+ const pixels = getRawPixels(canvas);
248
+ const frame = new VideoFrame(pixels, {
249
+ format: 'RGBA',
250
+ codedWidth: WIDTH,
251
+ codedHeight: HEIGHT,
252
+ timestamp,
253
+ });
254
+ videoEncoder.encode(frame, { keyFrame: i % 30 === 0 });
255
+ frame.close();
256
+ // Progress indicator
257
+ if ((i + 1) % 60 === 0) {
258
+ const elapsed = Date.now() - startTime;
259
+ const fps = ((i + 1) / elapsed) * 1000;
260
+ console.log(` Frame ${i + 1}/${FRAME_COUNT} (${fps.toFixed(1)} fps)`);
261
+ }
262
+ }
263
+ // Flush encoders
264
+ await videoEncoder.flush();
265
+ await audioEncoder.flush();
266
+ videoEncoder.close();
267
+ audioEncoder.close();
268
+ const encodeTime = Date.now() - startTime;
269
+ console.log(`\n Encoding complete: ${encodeTime}ms`);
270
+ console.log(` Video chunks: ${videoChunks.length}`);
271
+ console.log(` Audio chunks: ${audioChunks.length}`);
272
+ // Mux using node-av Muxer
273
+ console.log(' Muxing with node-av...');
274
+ const muxStartTime = Date.now();
275
+ const muxer = new NodeAvMuxer({ path: OUTPUT_VIDEO });
276
+ await muxer.open();
277
+ // Add video track
278
+ await muxer.addVideoTrack({
279
+ codec: 'avc1.64001E',
280
+ codedWidth: WIDTH,
281
+ codedHeight: HEIGHT,
282
+ framerate: FRAME_RATE,
283
+ bitrate: 4_000_000,
284
+ description: videoDescription,
285
+ });
286
+ // Add audio track
287
+ await muxer.addAudioTrack({
288
+ codec: 'mp4a.40.2',
289
+ sampleRate: SAMPLE_RATE,
290
+ numberOfChannels: AUDIO_CHANNELS,
291
+ bitrate: 128_000,
292
+ description: audioDescription,
293
+ });
294
+ // Write video chunks
295
+ for (const chunk of videoChunks) {
296
+ await muxer.writeVideoChunk(chunk);
297
+ }
298
+ // Write audio chunks
299
+ for (const chunk of audioChunks) {
300
+ await muxer.writeAudioChunk(chunk);
301
+ }
302
+ await muxer.close();
303
+ const muxTime = Date.now() - muxStartTime;
304
+ console.log(` Muxing complete: ${muxTime}ms`);
305
+ const totalTime = Date.now() - startTime;
306
+ const stats = fs.statSync(OUTPUT_VIDEO);
307
+ console.log(`\n Output: ${OUTPUT_VIDEO}`);
308
+ console.log(` Size: ${(stats.size / 1024).toFixed(1)} KB`);
309
+ console.log(` Total time: ${totalTime}ms`);
310
+ console.log('\n╔═══════════════════════════════════════════════════════════════╗');
311
+ console.log('║ Demo Complete! ║');
312
+ console.log('╚═══════════════════════════════════════════════════════════════╝\n');
313
+ }
314
+ main().catch((err) => {
315
+ console.error(err);
316
+ process.exit(1);
317
+ });
318
+ //# sourceMappingURL=demo-audio-visualizer-nodeav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo-audio-visualizer-nodeav.js","sourceRoot":"","sources":["../../src/demos/demo-audio-visualizer-nodeav.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Demo: Muxer Fallback Test
3
+ *
4
+ * Tests the Muxer class which tries node-av first
5
+ * and falls back to FFmpeg spawn if it fails.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=demo-muxer-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo-muxer-fallback.d.ts","sourceRoot":"","sources":["../../src/demos/demo-muxer-fallback.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Demo: Muxer Fallback Test
3
+ *
4
+ * Tests the Muxer class which tries node-av first
5
+ * and falls back to FFmpeg spawn if it fails.
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { createCanvas, getRawPixels } from '../canvas/index.js';
10
+ import { VideoEncoder } from '../encoders/VideoEncoder.js';
11
+ import { AudioEncoder } from '../encoders/AudioEncoder.js';
12
+ import { VideoFrame } from '../core/VideoFrame.js';
13
+ import { AudioData } from '../core/AudioData.js';
14
+ import { muxChunks } from '../containers/index.js';
15
+ const WIDTH = 320;
16
+ const HEIGHT = 240;
17
+ const DURATION_SECONDS = 2;
18
+ const FRAME_RATE = 30;
19
+ const SAMPLE_RATE = 48000;
20
+ const AUDIO_CHANNELS = 2;
21
+ const FRAME_COUNT = DURATION_SECONDS * FRAME_RATE;
22
+ const FRAME_DURATION_US = Math.round(1_000_000 / FRAME_RATE);
23
+ const SAMPLES_PER_FRAME = Math.round(SAMPLE_RATE / FRAME_RATE);
24
+ const OUTPUT_DIR = path.resolve('media', 'fallback-test');
25
+ async function generateTestContent() {
26
+ const videoChunks = [];
27
+ const audioChunks = [];
28
+ let videoDescription;
29
+ let audioDescription;
30
+ const canvas = createCanvas({ width: WIDTH, height: HEIGHT });
31
+ const ctx = canvas.getContext('2d');
32
+ const videoEncoder = new VideoEncoder({
33
+ output: (chunk, metadata) => {
34
+ videoChunks.push(chunk);
35
+ if (metadata?.decoderConfig?.description && !videoDescription) {
36
+ const desc = metadata.decoderConfig.description;
37
+ videoDescription = desc instanceof Uint8Array ? desc : new Uint8Array(desc);
38
+ }
39
+ },
40
+ error: (err) => console.error('Video encoder error:', err),
41
+ });
42
+ videoEncoder.configure({
43
+ codec: 'avc1.42001E',
44
+ width: WIDTH,
45
+ height: HEIGHT,
46
+ framerate: FRAME_RATE,
47
+ bitrate: 500_000,
48
+ });
49
+ const audioEncoder = new AudioEncoder({
50
+ output: (chunk, metadata) => {
51
+ audioChunks.push(chunk);
52
+ if (metadata?.decoderConfig?.description && !audioDescription) {
53
+ const desc = metadata.decoderConfig.description;
54
+ audioDescription = desc instanceof Uint8Array ? desc : new Uint8Array(desc);
55
+ }
56
+ },
57
+ error: (err) => console.error('Audio encoder error:', err),
58
+ });
59
+ audioEncoder.configure({
60
+ codec: 'mp4a.40.2',
61
+ sampleRate: SAMPLE_RATE,
62
+ numberOfChannels: AUDIO_CHANNELS,
63
+ bitrate: 64_000,
64
+ });
65
+ for (let i = 0; i < FRAME_COUNT; i++) {
66
+ const timestamp = i * FRAME_DURATION_US;
67
+ const hue = (i / FRAME_COUNT) * 360;
68
+ // Draw simple colored frame
69
+ ctx.fillStyle = `hsl(${hue}, 70%, 50%)`;
70
+ ctx.fillRect(0, 0, WIDTH, HEIGHT);
71
+ ctx.fillStyle = 'white';
72
+ ctx.font = '24px sans-serif';
73
+ ctx.textAlign = 'center';
74
+ ctx.fillText(`Frame ${i}`, WIDTH / 2, HEIGHT / 2);
75
+ const pixels = getRawPixels(canvas);
76
+ const frame = new VideoFrame(pixels, {
77
+ format: 'RGBA',
78
+ codedWidth: WIDTH,
79
+ codedHeight: HEIGHT,
80
+ timestamp,
81
+ });
82
+ videoEncoder.encode(frame, { keyFrame: i % 30 === 0 });
83
+ frame.close();
84
+ // Generate audio
85
+ const samples = new Float32Array(SAMPLES_PER_FRAME * AUDIO_CHANNELS);
86
+ const freq = 440 + Math.sin(i * 0.1) * 100;
87
+ for (let s = 0; s < SAMPLES_PER_FRAME; s++) {
88
+ const t = s / SAMPLE_RATE;
89
+ const sample = Math.sin(2 * Math.PI * freq * t) * 0.3;
90
+ samples[s * AUDIO_CHANNELS] = sample;
91
+ samples[s * AUDIO_CHANNELS + 1] = sample;
92
+ }
93
+ const audioData = new AudioData({
94
+ format: 'f32-planar',
95
+ sampleRate: SAMPLE_RATE,
96
+ numberOfFrames: SAMPLES_PER_FRAME,
97
+ numberOfChannels: AUDIO_CHANNELS,
98
+ timestamp,
99
+ data: samples,
100
+ });
101
+ audioEncoder.encode(audioData);
102
+ audioData.close();
103
+ }
104
+ await videoEncoder.flush();
105
+ await audioEncoder.flush();
106
+ videoEncoder.close();
107
+ audioEncoder.close();
108
+ return { videoChunks, audioChunks, videoDescription, audioDescription };
109
+ }
110
+ async function testMuxer(name, outputPath, forceBackend) {
111
+ console.log(`\n Testing ${name}...`);
112
+ const { videoChunks, audioChunks, videoDescription, audioDescription } = await generateTestContent();
113
+ const startTime = Date.now();
114
+ const result = await muxChunks({
115
+ path: outputPath,
116
+ video: {
117
+ config: {
118
+ codec: 'avc1.42001E',
119
+ codedWidth: WIDTH,
120
+ codedHeight: HEIGHT,
121
+ framerate: FRAME_RATE,
122
+ description: videoDescription,
123
+ },
124
+ chunks: videoChunks,
125
+ },
126
+ audio: {
127
+ config: {
128
+ codec: 'mp4a.40.2',
129
+ sampleRate: SAMPLE_RATE,
130
+ numberOfChannels: AUDIO_CHANNELS,
131
+ description: audioDescription,
132
+ },
133
+ chunks: audioChunks,
134
+ },
135
+ forceBackend,
136
+ onFallback: (err) => console.log(` Fallback triggered: ${err.message}`),
137
+ });
138
+ const totalTime = Date.now() - startTime;
139
+ const stats = fs.statSync(outputPath);
140
+ console.log(` Backend: ${result.backend}`);
141
+ console.log(` Muxing time: ${result.durationMs}ms`);
142
+ console.log(` Total time: ${totalTime}ms`);
143
+ console.log(` Output: ${outputPath}`);
144
+ console.log(` Size: ${(stats.size / 1024).toFixed(1)} KB`);
145
+ }
146
+ async function main() {
147
+ console.log('╔═══════════════════════════════════════════════════════════════╗');
148
+ console.log('║ Muxer Fallback Test ║');
149
+ console.log('╚═══════════════════════════════════════════════════════════════╝');
150
+ fs.mkdirSync(OUTPUT_DIR, { recursive: true });
151
+ // Test 1: Node-av muxer (forced)
152
+ await testMuxer('node-av (forced)', path.join(OUTPUT_DIR, 'test-nodeav.mp4'), 'node-av');
153
+ // Test 2: FFmpeg spawn muxer (forced)
154
+ await testMuxer('FFmpeg spawn (forced)', path.join(OUTPUT_DIR, 'test-ffmpeg.mp4'), 'ffmpeg-spawn');
155
+ // Test 3: Automatic (node-av with fallback)
156
+ await testMuxer('Automatic (node-av with fallback)', path.join(OUTPUT_DIR, 'test-auto.mp4'));
157
+ console.log('\n╔═══════════════════════════════════════════════════════════════╗');
158
+ console.log('║ All Tests Passed! ║');
159
+ console.log('╚═══════════════════════════════════════════════════════════════╝\n');
160
+ }
161
+ main().catch((err) => {
162
+ console.error(err);
163
+ process.exit(1);
164
+ });
165
+ //# sourceMappingURL=demo-muxer-fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo-muxer-fallback.js","sourceRoot":"","sources":["../../src/demos/demo-muxer-fallback.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,8 @@ export declare class AudioEncoder extends WebCodecsEventTarget {
48
48
  private _flushPromise;
49
49
  /** Actual encoder sample rate (48kHz for Opus, config.sampleRate otherwise) */
50
50
  private _encoderSampleRate;
51
+ /** Cached codec base for hot path */
52
+ private _codecBase;
51
53
  constructor(init: AudioEncoderInit);
52
54
  get state(): CodecState;
53
55
  get encodeQueueSize(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"AudioEncoder.d.ts","sourceRoot":"","sources":["../../src/encoders/AudioEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGjE,KAAK,YAAY,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;AAkBpD,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,YAAY,GAAG,QAAQ,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,WAAW,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAClF,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,CAAC,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,UAAU,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAQD,qBAAa,YAAa,SAAQ,oBAAoB;IACpD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,eAAe,CAA4E;IACnG,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,aAAa,CAA8B;IACnD,+EAA+E;IAC/E,OAAO,CAAC,kBAAkB,CAAK;gBAEnB,IAAI,EAAE,gBAAgB;IAclC,IAAI,KAAK,IAAI,UAAU,CAAwB;IAC/C,IAAI,eAAe,IAAI,MAAM,CAAkC;IAE/D,0DAA0D;IAC1D,IAAI,SAAS,IAAI,YAAY,CAA4B;IACzD,IAAI,SAAS,CAAC,OAAO,EAAE,YAAY,EAAgC;IAEnE,OAAO,CAAC,kBAAkB;IAQ1B,sEAAsE;IACtE,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,mBAAmB;WAQd,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAWxF,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IA6C3C,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IA8DvB,KAAK,CAAC,OAAO,GAAE,MAA8B,GAAG,OAAO,CAAC,IAAI,CAAC;IA6DnE,KAAK,IAAI,IAAI;IAeb,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,mBAAmB;IAwD3B,OAAO,CAAC,eAAe;CAiDxB"}
1
+ {"version":3,"file":"AudioEncoder.d.ts","sourceRoot":"","sources":["../../src/encoders/AudioEncoder.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,8 @@ export class AudioEncoder extends WebCodecsEventTarget {
33
33
  _flushPromise = null;
34
34
  /** Actual encoder sample rate (48kHz for Opus, config.sampleRate otherwise) */
35
35
  _encoderSampleRate = 0;
36
+ /** Cached codec base for hot path */
37
+ _codecBase = null;
36
38
  constructor(init) {
37
39
  super();
38
40
  if (!init || typeof init.output !== 'function') {
@@ -119,8 +121,9 @@ export class AudioEncoder extends WebCodecsEventTarget {
119
121
  this._bitstreamFormat = config.format ?? 'adts';
120
122
  this._codecDescription = null;
121
123
  // Opus always encodes at 48kHz regardless of input sample rate
122
- const codecBase = getCodecBase(config.codec);
123
- const isOpus = codecBase === 'opus';
124
+ // Cache codec base for hot path in _onEncoderFrame
125
+ this._codecBase = getCodecBase(config.codec);
126
+ const isOpus = this._codecBase === 'opus';
124
127
  this._encoderSampleRate = isOpus ? OPUS_ENCODER_SAMPLE_RATE : config.sampleRate;
125
128
  this._startEncoder();
126
129
  }
@@ -290,8 +293,8 @@ export class AudioEncoder extends WebCodecsEventTarget {
290
293
  const timestamp = Math.max(0, (frame.timestamp * 1_000_000) / this._encoderSampleRate);
291
294
  const duration = (samplesPerFrame * 1_000_000) / this._encoderSampleRate;
292
295
  let payload = frame.data;
293
- const codecBase = getCodecBase(this._config.codec);
294
- const isAac = codecBase === 'mp4a' || codecBase === 'aac';
296
+ // Use cached codec base for hot path
297
+ const isAac = this._codecBase === 'mp4a' || this._codecBase === 'aac';
295
298
  // Use description from backend if provided (AAC, FLAC, Vorbis, etc.)
296
299
  // For AAC, the backend provides proper AudioSpecificConfig with correct channelConfiguration
297
300
  if (frame.description && !this._codecDescription) {