【问题标题】:How to access uploaded file from multer?如何从 multer 访问上传的文件?
【发布时间】:2017-08-30 20:32:48
【问题描述】:

我可以将图片上传到S3。现在,如果选择的文件是.gif,我希望能够将.gif 文件转换为.mp4 并将转换后的文件上传到S3。仅当我提供文件的路径时,我才能将 .gif 转换为 .mp4ffmpeg。如何从Multer 访问上传的文件?下面是我的代码:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var aws = require('aws-sdk');
var multer = require('multer');
var multerS3 = require('multer-s3');
var s3 = new aws.S3();
var ffmpeg = require('fluent-ffmpeg');


var upload = multer({
    storage: multerS3({
        s3: s3,
        bucket: 'myBucket',
        key: function (req, file, cb) {
            console.log(file);
            var extension = file.originalname.substring(file.originalname.lastIndexOf('.')+1).toLowerCase();

                if(extension=="gif"){
                console.log("Uploaded a .gif file");

                ffmpeg(file) //THIS IS NOT WORKING
                    .setFfmpegPath("C:\\ffmpeg\\bin\\ffmpeg.exe")
                      .output('./outputs/2.mp4')    //TRYING TO UPLOAD LOCALLY, WHICH FAILS
                      .on('end', function() {
                        console.log('Finished processing');
                      })
                      .run();
            }

            cb(null, filename);
        }
    })
});

我正在尝试像这样访问上传的文件:ffmpeg(file),因为file 是在multer 函数中传递的参数。

我的表格:

<form action="/upload" method="post"  enctype="multipart/form-data">
    <input type="file" name="file"> <br />
    <input type="submit" value="Upload">
</form>

我应该在哪个过程中转换文件?

请帮忙。非常感谢。

【问题讨论】:

    标签: node.js amazon-s3 ffmpeg multer multer-s3


    【解决方案1】:

    您正在尝试在本地处理s3 上的文件。该文件必须是您服务器的文件系统,或者至少在s3 上公开可用。所以你在这里有两个选择。

    a) 您可以先将所有文件上传到运行 express 的服务器(不是s3,我们先暂时存储它们)。如果文件是.gif,则处理它并上传生成的.mp4 文件,否则上传到s3。这是一个工作示例:

    var fs         = require('fs')
    var path       = require('path')
    var express    = require('express');
    var bodyParser = require('body-parser');
    var aws        = require('aws-sdk');
    var multer     = require('multer');
    var ffmpeg     = require('fluent-ffmpeg');
    var shortid    = require('shortid');
    
    
    aws.config.update(/* your config */);
    
    
    var app    = express();
    var s3     = new aws.S3();
    var bucket = 'myBucket';
    
    var upload = multer({
        storage: multer.diskStorage({
            destination: './uploads/',
            filename: function (req, file, cb){
                // user shortid.generate() alone if no extension is needed
                cb( null, shortid.generate() + path.parse(file.originalname).ext);
            }
        })
    });
    
    
    //----------------------------------------------------
    app.post('/upload', upload.single('file'), function (req, res, next) {
    
        var fileInfo = path.parse(req.file.filename);
    
        if(fileInfo.ext === '.gif'){
    
            var videoPath = 'uploads/' + fileInfo.name + '.mp4';
    
            ffmpeg(req.file.path)
                .setFfmpegPath("C:\\ffmpeg\\bin\\ffmpeg.exe")
                .output(videoPath)
                .on('end', function() {
                    console.log('[ffmpeg] processing done');
                    uploadFile(videoPath, fileInfo.name + '.mp4');
                })
                .run();
        }
        else {
            uploadFile(req.file.path, req.file.filename);
        }
    
        res.end();
    });
    
    
    //----------------------------------------------------
    function uploadFile(source, target){
    
        fs.readFile(source, function (err, data) {
    
            if (!err) {
    
                var params = {
                    Bucket      : bucket,
                    Key         : target,
                    Body        : data
                };
    
                s3.putObject(params, function(err, data) {
                    if (!err) {
                        console.log('[s3] file uploaded:');
                        console.log(data);
                        fs.unlink(source); // optionally delete the file
                    }
                    else {
                        console.log(err);
                    }
                });
            }
        });
    }
    
    
    app.listen(3000);
    

    b) 或者,如果您同意公开您的s3 文件,您可以使用multer-s3 将它们全部上传。由于ffmpeg 也接受网络位置作为输入路径,您可以将.gif 文件的s3 位置传递给它,然后上传转换后的.mp4 文件:

    var fs         = require('fs')
    var path       = require('path')
    var express    = require('express');
    var bodyParser = require('body-parser');
    var aws        = require('aws-sdk');
    var multer     = require('multer');
    var ffmpeg     = require('fluent-ffmpeg');
    var multerS3   = require('multer-s3');
    
    
    aws.config.update(/* your config */);
    
    
    var app    = express();
    var s3     = new aws.S3();
    var bucket = 'myBucket';
    
    var upload = multer({
        storage: multerS3({
            s3: s3,
            bucket: bucket,
            key: function (req, file, cb) {
                cb(null, file.originalname);
            },
            acl: 'public-read'
        })
    });
    
    ----------------------------------------------------
    app.post('/upload', upload.single('file'), function (req, res, next) {
    
        var fileInfo = path.parse(req.file.originalname);
    
        if(fileInfo.ext === '.gif'){
    
            var videoPath = 'uploads/' + fileInfo.name + '.mp4';
    
            ffmpeg(req.file.location)
                .setFfmpegPath("C:\\ffmpeg\\bin\\ffmpeg.exe")
                .output(videoPath)
                .on('end', function() {
                    console.log('[ffmpeg] processing done');
                    uploadFile(videoPath, fileInfo.name + '.mp4');
                })
                .run();
        }
    
        res.end();
    })
    
    
    //----------------------------------------------------
    function uploadFile(source, target){
    
        fs.readFile(source, 'base64', function (err, data) {
    
            if (!err) {
    
                var params = {
                    Bucket      : bucket,
                    Key         : target,
                    Body        : data,
                    ContentType : 'video/mp4'
                };
    
                s3.putObject(params, function(err, data) {
                    if (!err) {
                        console.log('[s3] file uploaded:');
                        console.log(data);
                        fs.unlink(source); // optionally delete the file
                    }
                    else {
                        console.log(err);
                    }
                });
            }
        });
    }
    
    app.listen(3000);
    

    对于这两个示例,请记住创建一个 uploads/ 文件夹并使用您的 aws 配置。

    【讨论】:

    • 很抱歉出差了。尝试了第一个示例。上传到 S3 的文件将获得 .mp4 扩展名,无论它们是否为 .gif。上传的.mp4 无法播放,提示未知文件格式。这是针对上传的.gif,它在S3 中保存为.mp4
    • .mp4 文件夹中的/uploads 文件被转换为.mp4 并且可以播放。我评论了取消链接部分以检查这一点。因此,似乎转换后的文件没有上传到 S3,任何进入 S3 的文件都获得了 .mp4 扩展名。我喜欢第一种方法。请帮助使其工作。
    • 已编辑选项 a),文件现在保留其结尾。读取时还删除了base64 编码,s3 上的文件现在可以了。使用shortid 代替原来的名称。
    • 为所有上传设置ContentType : 'video/mp4',删除了该部分。现在应该可以了。
    • 没错。太棒了,很高兴为您提供帮助!
    猜你喜欢
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 2017-10-20
    • 1970-01-01
    • 2018-07-21
    • 2018-02-25
    • 2021-06-17
    相关资源
    最近更新 更多