Как объединить видео загрузку порций Node.js - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь загрузить большое (8,3 ГБ) видео на мой сервер Node.js (Express), используя чанк, используя busboy .Как я могу получить каждый кусок (busboy делает эту часть) и собрать его вместе как одно целое видео?

Я изучал читаемые и записываемые потоки, но я никогда не получаю целое видео.Я продолжаю переписывать его части, получая около 1 ГБ.

Вот мой код:

req.busboy.on('file', (fieldname, file, filename) => {
    logger.info(`Upload of '${filename}' started`);

    const video = fs.createReadStream(path.join(`${process.cwd()}/uploads`, filename));
    const fstream = fs.createWriteStream(path.join(`${process.cwd()}/uploads`, filename));

    if (video) {
        video.pipe(fstream);
    }

    file.pipe(fstream);

    fstream.on('close', () => {
        logger.info(`Upload of '${filename}' finished`);
        res.status(200).send(`Upload of '${filename}' finished`);
    }); 
});

Ответы [ 4 ]

0 голосов
/ 06 февраля 2019

Через 12+ часов я понял это, используя кусочки из этой статьи, которую мне дали .Я придумал этот код:

//busboy is middleware on my index.js
const fs = require('fs-extra');
const streamToBuffer = require('fast-stream-to-buffer');

//API function called first
uploadVideoChunks(req, res) {
    req.pipe(req.busboy);

    req.busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
        const fileNameBase = filename.replace(/\.[^/.]+$/, '');

        //save all the chunks to a temp folder with .tmp extensions
        streamToBuffer(file, function (error, buffer) {
            const chunkDir = `${process.cwd()}/uploads/${fileNameBase}`;
            fs.outputFileSync(path.join(chunkDir, `${Date.now()}-${fileNameBase}.tmp`), buffer);
        });
    });

    req.busboy.on('finish', () => {
        res.status(200).send(`Finshed uploading chunk`);
    });
}

//API function called once all chunks are uploaded
saveToFile(req, res) {
    const { filename, profileId, movieId } = req.body;

    const uploadDir = `${process.cwd()}/uploads`;
    const fileNameBase = filename.replace(/\.[^/.]+$/, '');
    const chunkDir = `${uploadDir}/${fileNameBase}`;
    let outputFile = fs.createWriteStream(path.join(uploadDir, filename));

    fs.readdir(chunkDir, function(error, filenames) {
       if (error) {
           throw new Error('Cannot get upload chunks!');
       }

       //loop through the temp dir and write to the stream to create a new file
       filenames.forEach(function(tempName) {
           const data = fs.readFileSync(`${chunkDir}/${tempName}`);
                outputFile.write(data);
                //delete the chunk we just handled
                fs.removeSync(`${chunkDir}/${tempName}`);
           });

            outputFile.end();
        });

        outputFile.on('finish', async function () {
            //delete the temp folder once the file is written
            fs.removeSync(chunkDir);
        }
    });
}
0 голосов
/ 06 февраля 2019

Использование потоков

multer позволяет легко обрабатывать загрузку файлов как часть экспресс-маршрута.Это прекрасно работает для небольших файлов, которые не оставляют значительного объема памяти.

Проблема с загрузкой большого файла в память заключается в том, что вы можете фактически исчерпать память и вызвать сбой приложения.

использовать запрос multipart / form-data.Это можно сделать, назначив readStream этому полю, вместо этого в параметрах запроса

потоки чрезвычайно важны для оптимизации производительности.

0 голосов
/ 06 февраля 2019

Попробуйте с этим примером кода, я думаю, он будет работать для вас.

busboy.on("file", function(fieldName, file, filename, encoding, mimetype){
    const writeStream = fs.createWriteStream(writePath);
    file.pipe(writeStream);

    file.on("data", data => {
        totalSize += data.length;
        cb(totalSize);
    });

    file.on("end", () => {
        console.log("File "+ fieldName +" finished");
    });
});

Вы также можете обратиться по этой ссылке для решения этой проблемы

https://github.com/mscdex/busboy/issues/143

0 голосов
/ 06 февраля 2019

Я думаю, что с этим хорошо работает multer, вы пробовали multer?

...