How to access uploaded file from multer?
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.
Somename
Interested in building responsive database driven websites and application. Beginner level but quick learner.
Updated on June 12, 2022Comments
-
Somename almost 2 years
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 toS3
. I am able to convert a.gif
to.mp4
withffmpeg
only if I give the path of the file. How do I access the uploaded file fromMulter
? 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)
sincefile
is an argument passed in themulter
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.