Вероятно, вам следует пересмотреть свой проект, потому что сохранение всего видео в виде неподвижных изображений мгновенно выбьет память из большинства устройств. Вместо этого взгляните на MediaStreams и MediaRecorder API, которые способны выполнять перекодирование и сжатие в реальном времени. Вы можете запросить MediaStream с холста с помощью его метода captureStream()
.
Быстрее всего, вероятно, отправить ImageBitmap в ваш рабочий поток, это действительно быстро генерировать из холста (простая копия буфера пикселей), и может быть передал в ваш рабочий скрипт, откуда вы сможете нарисовать его на OffscreenCanvas.
Основной недостаток: в настоящее время поддерживается только в последних Chrome и Firefox (через webgl ), и это не может быть заполнено ...
main. js
else {
console.log("Adding frame...");
const bitmap = await createImageBitmap(preview);
videoWorker.postMessage({ action: "addFrame", data: bitmap }, [bitmap]);
currIndex++;
}
работник. js
const canvas = new OffscreenCanvas(width,height);
const ctx = canvas.getContext('2d'); // Chrome only
onmessage = async (evt) => {
// ...
ctx.drawImage( evt.data.data, 0, 0 );
const image = await canvas.convertToBlob();
storeImage(image);
};
Другим вариантом является передача данных ImageData . Не так быстро, как ImageBitmap, он по-прежнему обладает тем преимуществом, что не останавливает ваш основной поток с помощью компонента сжатия, и, поскольку его можно передавать, сообщение Worker также не требует больших вычислительных ресурсов.
Если вы go, это дорога, вы можете сжать данные, используя что-то вроде pako (который использует алгоритм сжатия, используемый изображениями PNG) из вашего рабочего потока.
main. js
else {
console.log("Adding frame...");
const img_data = prevCtx.getImageData(0,0,width,height);
videoWorker.postMessage({ action: "addFrame", data: img_data }, [img_data.data]);
currIndex++;
}
рабочий. js
onmessage = (evt) => {
// ...
const image = pako.deflate(evt.data.data); // compress to store
storeImage(image);
};