2
votes

Comment combiner des morceaux de téléchargement vidéo Node.js

J'essaie de télécharger une vidéo volumineuse (8,3 Go) sur mon serveur Node.js (Express) en la segmentant à l'aide de busboy . Comment recevoir chaque morceau (busboy fait cette partie) et le reconstituer en une seule vidéo?

J'ai cherché des flux lisibles et inscriptibles, mais je ne reçois jamais la vidéo entière. J'en écrase certaines parties, ce qui fait environ 1 Go.

Voici mon code:

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`);
    }); 
});


0 commentaires

4 Réponses :


0
votes

Je pense que multer est bon avec ça, avez-vous essayé multer?


1 commentaires

Oui, j'ai essayé multer. À ma connaissance, il ne gère pas la segmentation.



2
votes

Utiliser les flux

multer vous permet de gérer facilement les téléchargements de fichiers dans le cadre d'un itinéraire express. Cela fonctionne très bien pour les petits fichiers qui ne laissent pas une empreinte mémoire importante.

Le problème avec le chargement d'un gros fichier en mémoire est que vous pouvez en fait manquer de mémoire et provoquer le blocage de votre application.

utilise une requête multipart / form-data. Cela peut être géré en attribuant le readStream à ce champ à la place dans vos options de requête

les flux sont extrêmement utiles pour optimiser les performances.


0 commentaires

1
votes

Essayez avec cet exemple de code, je pense que cela fonctionnera pour vous.

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");
    });
});

Vous pouvez également consulter ce lien pour résoudre ce problème

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


0 commentaires

2
votes

Après plus de 12 heures, je l'ai compris en utilisant des éléments de cet article qui m'a été donné . J'ai trouvé ce code:

//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 commentaires