Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
821 views
in Technique[技术] by (71.8m points)

node.js - How to access uploaded file from multer?

Im able to upload an image to S3. Now, if the file selected is .gif, I want to be able to convert the .gif file to .mp4 and upload the converted file to S3. I am able to convert a .gif to .mp4 with ffmpeg only if I give the path of the file. How do I access the uploaded file from Multer? Below is my code :

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

I'm trying to access the uploaded file like this: ffmpeg(file) since file is an argument passed in the multer function.

My form :

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

In which part of the process do I convert the file?

Please help. Many thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are trying to process a file locally that's on s3. The file needs to be your server's file system or at the very least be publicly available on s3. So you have two options here.

a) You could first upload all the files to the server where express is running (not on s3, first we store them temporarily). If the file is a .gif, process it and upload the resulting .mp4 file, otherwise upload to s3. Here's a working example:

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) Alternatively if you're ok with making your s3 files public you could upload them all using multer-s3. Since ffmpeg also accepts network locations as input paths you can pass it the s3 location of your .gif files and then upload the converted .mp4 files:

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

For both examples, remember to create an uploads/ folder and use your aws configuration.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...