Live Demo
The live demo of the app is given here
Get Started
In order to get started by building this project you need to install the below dependencies for your node.js project
npm init -y
npm i express
npm i multer
npm i nodemon
Now we will create the starting point of the application which is index.js
and copy paste the following code to it
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
const express = require('express') const app = express() var dir = 'public'; var subDirectory = 'public/uploads' if (!fs.existsSync(dir)){ fs.mkdirSync(dir); fs.mkdirSync(subDirectory) } const PORT = process.env.PORT || 3000 app.get('/',(req,res) => { res.sendFile(__dirname + "/index.html") }) app.listen(PORT,() => { console.log(`App is listening on Port ${PORT}`) }) |
Creating Template File
Now we will create the template file which the user sees when it opens the application i.e. index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<!DOCTYPE html> <html> <head> <title>Currency Converter in Javascript</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" /> </head> <body> <div class="container"> <br><br> <h1 class="text-center"> Merge Videos </h1> <br> <form action="/merge" method="post" enctype="multipart/form-data"> <div class="form-group"> <input type="file" name="files" multiple class="form-control" required> </div> <div class="form-group"> <button class="btn btn-danger btn-block"> Merge Videos </button> </div> </form> </div> </body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> </html> |
Uploading Multiple Videos in Node.js Server
Now the next step is to upload multiple video files to node.js server so that we can process them with ffmpeg library and merge them together. For this we will be using multer library for this
Now copy paste the below code inside index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
const multer = require('multer') var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'public/uploads') }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)) } }) const videoFilter = function(req, file, cb) { // Accept videos only if (!file.originalname.match(/\.(mp4)$/)) { req.fileValidationError = 'Only video files are allowed!'; return cb(new Error('Only video files are allowed!'), false); } cb(null, true); }; var upload = multer({storage:storage,fileFilter:videoFilter}) app.use(express.static('public')) |
Merging Videos in POST Request
Now the main business logic of the application when we submit the form we need to make the post request and write this code inside index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
const fs = require('fs') const path = require('path') const { exec } = require('child_process') var list = "" var listFilePath = 'public/uploads/' + Date.now() + 'list.txt' var outputFilePath = Date.now() + 'output.mp4' app.post('/merge',upload.array('files',1000),(req,res) => { if(req.files){ req.files.forEach(file => { list += `file ${file.filename}` list += "\n" }); var writeStream = fs.createWriteStream(listFilePath) writeStream.write(list) writeStream.end() exec(`ffmpeg -safe 0 -f concat -i ${listFilePath} -c copy ${outputFilePath}`, (error, stdout, stderr) => { if (error) { console.log(`error: ${error.message}`); return; } else{ console.log("videos are successfully merged") res.download(outputFilePath,(err) => { if(err) throw err req.files.forEach(file => { fs.unlinkSync(file.path) }); fs.unlinkSync(listFilePath) fs.unlinkSync(outputFilePath) }) } }) } }) |
Full Index.js File
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
const express = require('express') const fs = require('fs') const path = require('path') const { exec } = require('child_process') var list = "" var listFilePath = 'public/uploads/' + Date.now() + 'list.txt' var outputFilePath = Date.now() + 'output.mp4' const bodyParser = require('body-parser') const multer = require('multer') const app = express() var dir = 'public'; var subDirectory = 'public/uploads' if (!fs.existsSync(dir)){ fs.mkdirSync(dir); fs.mkdirSync(subDirectory) } var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'public/uploads') }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname)) } }) const videoFilter = function(req, file, cb) { // Accept videos only if (!file.originalname.match(/\.(mp4)$/)) { req.fileValidationError = 'Only video files are allowed!'; return cb(new Error('Only video files are allowed!'), false); } cb(null, true); }; var upload = multer({storage:storage,fileFilter:videoFilter}) app.use(bodyParser.urlencoded({extended:false})) app.use(bodyParser.json()) app.use(express.static('public')) const PORT = process.env.PORT || 3000 app.get('/',(req,res) => { res.sendFile(__dirname + "/index.html") }) app.post('/merge',upload.array('files',1000),(req,res) => { list = "" if(req.files){ req.files.forEach(file => { list += `file ${file.filename}` list += "\n" }); var writeStream = fs.createWriteStream(listFilePath) writeStream.write(list) writeStream.end() exec(`ffmpeg -safe 0 -f concat -i ${listFilePath} -c copy ${outputFilePath}`, (error, stdout, stderr) => { if (error) { console.log(`error: ${error.message}`); return; } else{ console.log("videos are successfully merged") res.download(outputFilePath,(err) => { if(err) throw err req.files.forEach(file => { fs.unlinkSync(file.path) }); fs.unlinkSync(listFilePath) fs.unlinkSync(outputFilePath) }) } }) } }) app.listen(PORT,() => { console.log(`App is listening on Port ${PORT}`) }) |
DOWNLOAD SOURCE CODE