I am trying to create video using MediaStreamTrackGenerator and a couple of still images:
async function createVideo() {
const trackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });
const stream = new MediaStream();
stream.addTrack(trackGenerator);
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm;codecs=vp9' });
mediaRecorder.ondataavailable = event => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
} else {
console.error('Empty chunk');
}
};
mediaRecorder.start();
for (let i = 0; i < 10; i++) {
const writer = trackGenerator.writable.getWriter();
await writer.ready;
const height = 640;
const width = 480;
const duration = 1000 * 1000;
const timestamp = i * duration;
const canvas = new OffscreenCanvas(width, height);
const ctx = canvas.getContext('2d', { alpha: false });
ctx.fillStyle = `rgba(50, 100, 150, 255)`;
ctx.fillRect(0, 0, width, height);
const frame = new VideoFrame(canvas.transferToImageBitmap(), {
duration,
timestamp,
alpha: 'keep' ,
codedWidth: width,
codedHeight: height
});
await writer.write(frame);
frame.close();
await writer.ready;
writer.releaseLock();
}
mediaRecorder.stop();
const blob = new Blob(recordedChunks, {
type: 'video/webm'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = url;
a.download = 'test.webm';
a.click();
window.URL.revokeObjectURL(url);
}
The problem is that if I write the images quickly in a loop (as shown in my code), the ondataavailable event is never raised and I get an empty blob. If on the other hand I delay the writing of each frame with 1second, then I get correct results.
So my question is if it is possible to create a video by batch adding the frames with their respective timestamp and duration?