node.js - Promise 链接和解析

标签 node.js express ffmpeg promise multer

我正在尝试在 Promise 的帮助下一一转换视频。我使用 ffmpeg 进行转换,使用 multer 上传多个文件。

multer 一次上传多个文件,之后我必须一一链接转换。截至目前,它只是转换第一个文件。

我认为在数组中链接 promise ..like 应该可以工作,但是如果我可以在数组中定义新的 promise ,我很困惑,因为 ffmpeg 也返回了一个 promise

我的路由器:

const router = require('express').Router();
const multer = require('multer');
const ffmpeg = require('ffmpeg');

let str;
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, './uploads');
  },
  filename: (req, file, cb) => {
    str = file.originalname.replace(/\.[^/.]+$/, "");
    str = str.replace(/[^a-z0-9+]+/gi, '_') + '.' + file.originalname.replace(/^.*\./, '');
    cb(null, str);
  }
});

const upload = multer({ storage: storage }).array('files', 12);

router.post('/upload', (req, res, next) => {
  // req.files is an array of files
  // req.body will contain the text fields, if there were any
  function uploadFile() {
    return new Promise((resolve, reject) => {
      upload(req, res, (err) => {
        if (err) {
          res.send(err) // Pass errors to Express.
          reject(`Error: Something went wrong!`);
        } else if (req.files == undefined) {
          res.send(`No File selected.`);
          resolve();
        } else if (!err && req.files.length > 0) {
          res.status(201).send(`${req.files.length} File(s): ${req.files} uploaded successfully.`);
          console.log('uploaded');
          resolve();
        }
      });
    });
  }

  uploadFile().then(() => {
    try {
      var process = new ffmpeg('./uploads/' + str);
      process.then(function (video) {
        console.log('The video is ready to be processed');
        video.addCommand('-hide_banner', '');
        video.addCommand('-y', '');
        video.addCommand('-c:a', 'aac');
        video.addCommand('-ar', '48000');
        video.addCommand('-c:v', 'h264');
        video.addCommand('-profile:v', 'main');
        video.addCommand('-crf', '20');
        video.addCommand('-sc_threshold', '0');
        video.addCommand('-g', '50');
        video.addCommand('-keyint_min', '50');
        video.addCommand('-hls_time', '4');
        video.addCommand('-hls_playlist_type', 'vod');
        video.addCommand('-vf', 'scale=-2:720');
        video.addCommand('-b:v', '1400k');
        video.addCommand('-maxrate', '1498k');
        video.addCommand('-bufsize', '2100k');
        video.addCommand('-b:a', '128k');
        video.save('./converted/' + str, function (error, file) {
          if (!error)
            console.log('Video file: ' + file);
        });
        }, function (err) {
          console.log('Error: ' + err);
        });
    } catch (e) {
      console.log(e.code);
      console.log(e.msg);
    }
  }).catch((err) => {
    console.log(Error, err);
  });
});

module.exports = router;

最佳答案

我会使用 Promise.all异步处理上传,它本身返回一个带有结果数组的 promise 。

例子:

const express = require ( 'express' );
const router = express.Router ( {} );
const multer = require ( 'multer' );
const upload = multer ( { dest: 'uploads/' } );

// Process a single upload - returns a promise
const processUpload = file => {
    return new Promise ( ( resolve, reject ) => {

        // Processing code here
        // ...

        // Return the promise when done
        return resolve ( path );

    } );
};

// Handle upload route
router.post ( '/upload', [

    // Process the multiple file upload
    upload.array ( 'files', 12 ),

    // Controller - process the uploaded files
    ( req, res, next ) => {

        // Create an array of promises for each uploaded file in req.files
        let promises = req.files.map ( file => processUpload ( file ) );
        Promise.all ( promises )
            .then ( results => {

                // Handle the finished results here
                return res
                    .status ( 201 )
                    .json ( {
                        message: `${results.length} files successfully uploaded`
                    } )
                ;

            } )
            .catch ( e => next ( e ) )
        ;

    }

] );

更新以按顺序处理上传:

使用异步库进行更好的控制:http://caolan.github.io/async/docs.html#eachSeries
const express = require ( 'express' );
const router = express.Router ( {} );
const async = require ( 'async' );
const multer = require ( 'multer' );
const upload = multer ( { dest: 'uploads/' } );

// Process a single upload - returns a promise
const processUpload = file => {
    return new Promise ( ( resolve, reject ) => {

        // Processing code here
        const process = new ffmpeg ( /../ );
        process
            .then ( video => {

                // Return the promise when done
                return resolve ( something );

            } )
            .catch ( e => reject ( e ) )
        ;

    } );
};

// Handle upload route
router.post ( '/upload', [

    // Process the multiple file upload
    upload.array ( 'files', 12 ),

    // Controller - process the uploaded files
    ( req, res, next ) => {

        // Process multiple files sequentially
        let results = [];
        async.eachSeries (

            // Array to iterate through
            req.files,

            // Callback per file
            ( file, callback ) => {

                processUpload(file)
                    .then(r => {

                        // Compile results and return this callback
                        results.push(r);
                        callback()

                    })
                    .catch ( e => callback ( e ) )
                ;

            },

            // Completion handler
            e => {

                if ( e ) {
                    return next ( e );
                }

                // Handle the finished results here
                return res
                    .status ( 201 )
                    .json ( {
                        message: `${results.length} files successfully uploaded`
                    } )
                    ;

            }
        );

    }

] );

希望这可以帮助..

关于node.js - Promise 链接和解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54324152/

相关文章:

powershell - 将输出重定向到不同的路径

ffmpeg - 支持转换器的多种文件格式如何工作?

node.js - 如何在 Heroku 上部署的 Loopback 应用程序中记录 HTTP JSON 请求?

Node.js - "listener"参数必须是 Function 类型

javascript - 验证 Node/Express 中的 pubsubhubbub 内容签名

angularjs - 在查询参数中使用 mongoDB ObjectID,它会影响 SEO 吗?

javascript - 使用 fs.rename() 的 EPERM 错误

node.js - 将表更改迁移到生产 sailsjs 表的最佳方法

javascript - 链接到另一个 html 文件在本地主机上有效,但在我将其上传到服务器时却无效

python - OpenCV (3.3.0) 在带有视频的 VideoCapture 上返回失败,但适用于网络摄像头 [OS X]