1

I am using the node.js as a backend and needs to upload the video on Amazon S3.

For that I am using the multer module but I need to know the efficient and standard way for uploading the video.

Generally we see that when we upload anything on the any good platfrom then there is a proper mechanism for uploading the video like:

  1. When video is on uploading state, user get the response that how much percent is left for uploading the video
  2. After uploading the video user get the response that video is uploaded successfully.
  3. There is a handler which allow specific type of format to allow video.
  4. There is a few limit size also which warn the user that maximum size is 20mb or 50 mb.

I am bit struggling about the good tutorial but unable to find as everywhere is sharing the tutorials about the image upload. So I thought I will raise the question which will help many others also regarding the same

I have implemented the process by which video will be uploaded on S3 but not getting the response after upload. It directly return the response and video will be uploaded in background.

I am sharing my implementation:

customapi.js file

const express = require('express');
const router = express.Router();
const helper = require('./file-upload');
const videoHandler = require('./videohandler');
// Post the video
router.post(
    '/uploadvideo',
    helper.single('media'),
    videoHandler .uploadVideo
);

file-upload.js file

const AWS = require('aws-sdk')
const multer = require('multer')
const multerS3 = require('multer-s3')
const uuid = require('uuid/v1');
AWS.config.update({
  accessKeyId: process.env.keyId,
  secretAccessKey: process.env.accessKey,
});
const s3 = new AWS.S3();

const upload = multer({
  storage: multerS3({
    s3:s3,
    bucket: process.env.bucketname,
    acl: 'public-read',
    contentType: multerS3.AUTO_CONTENT_TYPE,
    metadata: function (req, file, cb) {
      cb(null, {fieldName: file.fieldname})
    },
    key: function (req, file, cb) {
      console.log(file) // This will print the filename which we can search in s3.
      cb(null, uuid()+file.originalname)
      console.log(uuid() + file.originalname)
    }
  })
})

videohandler.js file

module.exports = {
  uploadVid: async (req, res) => {
        try {
            return res.send({message: "Done"})
        } catch (error) {
            console.log(error);
            return res.send({message: "Error"})
        }
    }
}

I know what is happening exactly by which I am getting the response instantly instead of after the file upload.

When api calls -> helper.single('media') will invoke and process to start performing the task -> meanwhile videoHandler.uploadVideo will also called which directly send the response as there is no callback which understand the uploading process and return response accordingly.

Please share the best and efficient way as it supports many people also who is struggling for uploading the video.

Any help or suggestion is really appreciated.

Update Question

Many people sharing the way that video first upload on local disk and then it upload on S3. I need to know that is it a good behaviour. I mean for performing the task we need to do the double work instead of directly upload. It will consume the bandwidth and storage of the application on server.

Aks
  • 1,092
  • 3
  • 12
  • 29

1 Answers1

0

I could handle it in this way. check whether is it applicable to your scenario.

App.js

router.post("/upload_service",
(req, res, next) => {
  const upload = UploadController.upload.single('file')
  upload(req, res, (err) => {
    if (err) {
      const error = new Error('Image upload error');
      return next(error);
    }
    return next()
  })
}, 
SomeController.createMethod)

UploadController.js

const multer = require('multer')
const multerS3 = require('multer-s3')
const AWS = require('aws-sdk')

const upload = multer({
    storage: multerS3({
        s3: new AWS.S3(),
        bucket: 'bucket_name',
        metadata: function (req, file, cb) {
            cb(null, { fieldName: file.fieldname });
        },
        key: function (req, file, cb) {
            const file_name_timestamp = Date.now().toString()
            cb(null, `path/${file_name_timestamp}.${String(file.mimetype).split('/').pop()}`);
        },
        ContentType: "application/octet-stream",
    })
})

module.exports = {
    upload
}

SomeController.js

const createMethod = async function (req, res) {
  if (!req.file) {
    res.send('File missing')
  }
}

Once file upload middleware was success, SomeController.createMethod will be triggered. using req.file, creation data can be visible.

Asanka
  • 552
  • 6
  • 15