Однако я пытался воспроизвести тот же процесс в nodejs и подумал об использовании для этого ffmpeg. , теперь вместо того, чтобы сначала загружать все кадры в память и перебирать их, мне нужен был способ загружать каждый кадр по одному и иметь возможность быстро их обрабатывать, поэтому после долгих исследований в Интернете я придумал это решение: -
Код: Выделить всё
const fs = require('fs');
const { spawn } = require('child_process');
const width = 1920;
const height = 1080;
const bytesPerPixel = 3;
const frameSize = width * height * bytesPerPixel;
const spawnProcess = spawn('ffmpeg', [
'-i', 'test.mp4',
'-vcodec', 'rawvideo',
'-pix_fmt', 'rgb24',
'-f', 'rawvideo',
'-s', `${width}x${height}`, // size of one frame
'pipe:1'
]);
let buffer = Buffer.alloc(0);
let frameCount = 0;
spawnProcess.stdout.on('data', (data) => {
buffer = Buffer.concat([buffer, data]);
while (buffer.length >= frameSize) {
const frameBuffer = buffer.slice(0, frameSize);
buffer = buffer.slice(frameSize);
const outputPath = `frame-${frameCount++}.png`;
saveFrameAsPNG(frameBuffer, width, height, outputPath);
}
});
function saveFrameAsPNG(frameBuffer, width, height, outputPath) {
const { PNG } = require('pngjs');
const png = new PNG({
width: width,
height: height
});
// Copy the frame buffer to the PNG data
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const idx = (y * width + x) * 3;
const pngIdx = (y * width + x) * 4;
png.data[pngIdx] = frameBuffer[idx]; // Red
png.data[pngIdx + 1] = frameBuffer[idx + 1]; // Green
png.data[pngIdx + 2] = frameBuffer[idx + 2]; // Blue
png.data[pngIdx + 3] = 255; // Alpha
}
}
png.pack().pipe(fs.createWriteStream(outputPath));
}
spawnProcess.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
spawnProcess.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Однако обработка кадров происходит очень медленно: обработка 5-секундного видео со скоростью 60 кадров в секунду занимает около 1 минуты, что очень неэффективно по сравнению с Python OpenCV
Я действительно не понимаю, какой подход мне следует продолжать: -
- Я мог бы найти способ для обработки видео с помощью Python opencv и передачи буфера кадров/сохранения их по отдельности в файловой системе, и nodejs будет отслеживать сохранение любого файла в каталоге и продолжать обрабатывать и удалять их одновременно
- Или я мог бы продолжать попытки найти способ ускорить обработку фрейма чтения в nodejs.
Подробнее здесь: https://stackoverflow.com/questions/786 ... ing-ffmpeg