Подтвердить что ты не робот

Node.js: преобразование в реальном времени из jpeg-изображений в видеофайл

Я использую node.js и через библиотеку socket.io я получаю куски данных, которые на самом деле являются изображениями jpeg. Эти изображения представляют собой кадры видео в реальном времени, снятые с удаленной веб-камеры. Я вынужден передавать видео в виде jpeg-кадров. Я ищу способ конвертировать на лету эти jpeg-изображения в видеофайл (файл mpeg 4 или mjpeg). У библиотеки node есть библиотека, которая может это сделать? Я уже рассмотрел библиотеку Node-fluent-FFMPEG, но единственными приведенными примерами были конверсии jpeg файлов в видео, а не преобразование "на лету" из потока jpeg-изображения. Или, наоборот, ffmpeg для Windows поддерживает поток jpeg-изображений в качестве входных данных?

4b9b3361

Ответ 1

Используя require("child_process"), вы можете использовать ffmpeg или, возможно, модули npm, чтобы помочь с этим. ffmpeg позволит вам сначала взять список jpegs и преобразовать его в видео, во-вторых, вы можете добавить список (или только один) jpegs в начало или конец видео.

Ответ 2

Думаю, вам стоит взглянуть на videofy

var exec = require("child_process").exec;
var escape = require("shell-escape");
var debug = require("debug")("videofy");
var mkdirp = require("mkdirp");
var uid = require("uid2");

/*
 *  Expose videofy
 */

module.exports = videofy;

/**
 * Convert `input` file to `output` video with the given `opts`:
 *
 *  - `rate` frame rate [10]
 *  - `encoders` the video codec format, default is libx264
 *
 * @param {String} input
 * @param {String} output
 * @return
 * @api public
 */
function videofy(input, output, opts, fn) {
    if (!input) throw new Error('input filename required');
    if (!output) throw new Error('output filename required');

    var FORMAT = '-%05d';

    // options
    if ('function' == typeof opts) {
        fn = opts;
        opts = {};
    } else {
        opts = opts || {};
    }

    opts.rate = opts.rate || 10;
    opts.codec = opts.codec || 'libx264';

    // tmpfile(s)
    var id = uid(10);
    var dir = 'tmp/' + id;
    var tmp = dir + '/tmp' + FORMAT + '.jpg';


    function gc(err) {
        debug('remove %s', dir);
        exec('rm -fr ' + dir);
        fn(err);
    }

    debug('mkdirp -p %s', dir);

    mkdirp(dir, function(error) {
        if (error) return fn(error);

        // convert gif to tmp jpg
        var cmd = ['convert', input, tmp];
        cmd = escape(cmd);

        debug('exec %s', cmd);
        // covert jpg collection to video
        exec(cmd, function(err) {

            if (err) return gc(err);

            var cmd = ['ffmpeg'];

            cmd.push('-f', 'image2');
            cmd.push('-r', String(opts.rate));
            cmd.push('-i', tmp);
            cmd.push('-c:v', String(opts.codec));
            cmd.push(output);

            cmd = escape(cmd);

            debug("exec %s", cmd);

            exec(cmd, gc);
        });
    });
}

Ответ 3

FFMPEG поддерживает потоки как входы, как указано в docs.

Вы можете добавить любое количество входов в команду Ffmpeg. Вход может быть [...] читаемым потоком

Так, например, он поддерживает использование

ffmpeg().input(fs.createReadStream('/path/to/input3.avi'));

который создает Readable stream из файла в '/path/to/input3.avi'.

Я ничего не знаю о FFMPEG, но вы можете вытаскивать ваши сообщения из socket.io(сообщения уже могут быть буфером) и оберните его собственной реализацией Readable stream.