@tsparticles/plugin-export-video
Version:
tsParticles export video plugin
78 lines (77 loc) • 2.47 kB
JavaScript
import { millisecondsToSeconds, } from "@tsparticles/engine";
const videoTypes = ["webm", "ogg", "mp4", "x-matroska"], codecs = [
"vp9",
"vp9.0",
"vp8",
"vp8.0",
"avc1",
"av1",
"h265",
"h.265",
"h264",
"h.264",
"opus",
"pcm",
"aac",
"mpeg",
"mp4a",
];
function getVideoSupportedMimeTypes() {
const isSupported = (type) => MediaRecorder.isTypeSupported(type), supported = [];
videoTypes.forEach(type => {
const mimeType = `video/${type}`;
codecs.forEach(codec => [
`${mimeType};codecs=${codec}`,
`${mimeType};codecs=${codec.toUpperCase()}`,
].forEach(variation => {
if (isSupported(variation)) {
supported.push(variation);
}
}));
if (isSupported(mimeType)) {
supported.push(mimeType);
}
});
return supported;
}
export class ExportVideoInstance {
constructor(container, engine) {
this._supportedTypes = [];
this._exportVideo = async (data) => {
const element = this._container.canvas.element;
if (!element) {
return;
}
return new Promise(resolve => {
const stream = element.captureStream(data.fps ?? this._container.actualOptions.fpsLimit), firstIndex = 0, mimeType = data.mimeType ?? this._supportedTypes[firstIndex], recorder = new MediaRecorder(stream, {
mimeType,
}), chunks = [], defaultDuration = 5;
recorder.addEventListener("dataavailable", (event) => {
chunks.push(event.data);
});
recorder.addEventListener("stop", () => {
resolve(new Blob(chunks, { type: mimeType }));
});
recorder.start();
setTimeout(() => {
recorder.stop();
}, data.duration ?? defaultDuration * millisecondsToSeconds);
});
};
this._container = container;
this._engine = engine;
this._supportedTypes = getVideoSupportedMimeTypes();
}
async export(type, data) {
const res = {
supported: false,
};
switch (type) {
case "video":
res.supported = true;
res.blob = await this._exportVideo(data);
break;
}
return res;
}
}