Как быстрее обрабатывать видеокадры в nodejs с помощью ffmpegPython

Программы на Python
Anonymous
Как быстрее обрабатывать видеокадры в nodejs с помощью ffmpeg

Сообщение Anonymous »

Я работаю над приложением для редактирования видео, в которое пользователь может загружать видео, и я хочу выполнить некоторые манипуляции с кадрами поверх видео, поэтому я хочу извлечь видеокадры и нарисовать их поверх API холста в nodejs и отредактируйте их соответствующим образом. Раньше я манипулировал видео с помощью opencv, и существовала функция cv2.VideoCapture(inputFilePath), которая считывала видеокадры по одному, и мы могли выполнять наши манипуляции с кадром. Обработка была очень быстрой, и я пробовал обрабатывать большие видеофайлы, и это работало очень быстро.
Однако я пытался воспроизвести тот же процесс в 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}`);
});

Сначала я вводил видео в ffmpeg, работающий в дочерних процессах, и выводил в стандартный вывод данные буфера, а затем использовал функцию для определения значения одного кадра и извлечения этот один кадр и сохраните его в файловой системе.
Однако обработка кадров происходит очень медленно: обработка 5-секундного видео со скоростью 60 кадров в секунду занимает около 1 минуты, что очень неэффективно по сравнению с Python OpenCV
Я действительно не понимаю, какой подход мне следует продолжать: -
  • Я мог бы найти способ для обработки видео с помощью Python opencv и передачи буфера кадров/сохранения их по отдельности в файловой системе, и nodejs будет отслеживать сохранение любого файла в каталоге и продолжать обрабатывать и удалять их одновременно
  • Или я мог бы продолжать попытки найти способ ускорить обработку фрейма чтения в nodejs.
Любая помощь с кодом будет принята с благодарностью :)

Подробнее здесь: https://stackoverflow.com/questions/786 ... ing-ffmpeg

Вернуться в «Python»