Complete Alpha Video Example
Copy
const { VideoEncoder, VideoFrame } = require('node-webcodecs');
const fs = require('fs');
async function encodeAlphaVideo() {
console.log('Encoding VP9 video with alpha channel...');
const chunks = [];
const encoder = new VideoEncoder({
output: (chunk) => {
const buffer = Buffer.alloc(chunk.byteLength);
chunk.copyTo(buffer);
chunks.push(buffer);
},
error: (err) => {
console.error('Error:', err);
throw err;
}
});
// VP9 with alpha
encoder.configure({
codec: 'vp09.00.10.08',
width: 1280,
height: 720,
bitrate: 4_000_000,
framerate: 30,
alpha: 'keep' // ← Preserve transparency
});
console.log('Creating 60 frames with circular alpha...');
for (let i = 0; i < 60; i++) {
const data = createAlphaFrame(1280, 720, i);
const frame = new VideoFrame(data, {
format: 'RGBA',
codedWidth: 1280,
codedHeight: 720,
timestamp: i * 33333
});
encoder.encode(frame, { keyFrame: i % 30 === 0 });
frame.close();
}
await encoder.flush();
encoder.close();
const output = Buffer.concat(chunks);
fs.writeFileSync('alpha_video.vp9', output);
console.log(`✓ Encoded ${output.length} bytes with alpha channel`);
console.log('Verify: ffprobe -show_streams alpha_video.vp9');
}
function createAlphaFrame(width, height, frameNum) {
const data = new Uint8Array(width * height * 4);
const centerX = width / 2;
const centerY = height / 2;
const radius = Math.min(centerX, centerY) * 0.8;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const idx = (y * width + x) * 4;
const dx = x - centerX;
const dy = y - centerY;
const dist = Math.sqrt(dx * dx + dy * dy);
// Rainbow gradient
const hue = ((x / width) + (frameNum / 60)) % 1.0;
const rgb = hslToRgb(hue, 1, 0.5);
data[idx] = rgb[0];
data[idx + 1] = rgb[1];
data[idx + 2] = rgb[2];
// Circular alpha (fade from center)
if (dist < radius) {
data[idx + 3] = 255;
} else {
const fade = Math.max(0, 255 - (dist - radius) * 5);
data[idx + 3] = fade;
}
}
}
return data;
}
function hslToRgb(h, s, l) {
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
encodeAlphaVideo().catch(console.error);