NodeJS + FFMPEG -sending response when FFMPEG is completed - node.js

I have a working NodeJS+FFMPEG application. I am able to upload video files and have them converted on the server. I am using this NodeJS FFMPEG library
https://github.com/fluent-ffmpeg/node-fluent-ffmpeg
I get a message on the server when the job is complete, but how do I notify the client?? In this case a simple AIR application. Right now I can only 'hear' the initial response after a successful upload.
The initial video file was uploaded via a http POST request.
My primary node application without the dependencies is as follows
var ffmpeg = require('./lib/fluent-ffmpeg');
var express = require('express'),
multer = require('multer');
var app = express();
//auto save file to uploads folder
app.use(multer({ dest: './uploads/'}))
var temp;
app.post('/', function (req, res) {
console.log(req.body); //contains the variables
console.log("req.files ="+ req.files); //contains the file references
console.log("req.files.Filedata.path ="+ req.files.Filedata.path );
temp=req.files.Filedata.path;
// make sure you set the correct path to your video file
var proc = ffmpeg('./'+temp)
// set video bitrate
.videoBitrate(1024)
// set audio codec
.audioCodec('libmp3lame')
// set output format to force
.format('avi')
// setup event handlers
.on('end', function() {
console.log('file has been converted succesfully');
})
.on('error', function(err) {
console.log('an error happened: ' + err.message);
})
// save to file
.save('./converted/converted.avi');
res.send('Thank you for uploading!');
});
app.listen(8080);

There are two approaches you can use. The first is to poll the server from the client with AJAX GET requests every x seconds. The second approach is to use WebSockets and notify the client by sending a message to them directly.

Related

How to upload file from nodeJS to nodeJS

I have 2 nodeJS services and I would want to upload file in a dir, from one NodeJS (backend) to another NodeJS(backend). The receiver nodeJS is an express app.
Looking for some working code sample.
PS: Couldn't find any code samples in search, since everywhere it was Multer from client to server uploads that receives multipart/form-data.
Uploading file using POST request in Node.js
Receive the file first as you correctly said using Multer. Then, you may either save the file to a temporary directory before uploading it again or just send the file as-is.
You need to setup a server running with Multer on the 2nd server that wishes to receive the file.
const express = require('express');
const app = express();
const upload = multer({ dest: 'files/' });
app.post('/upload', upload.single('file'), (req, res) => {
res.sendStatus(200);
});
app.listen(3001);
Then on the server you wish to send the file from, do something like this:
const request = require('request');
const req = request.post('localhost:3001/upload', (err, res, body) => {
if (err) throw new Error(err);
if (res && res.statusCode == 200) {
console.log('Success');
} else {
console.log('Error');
};
});
const form = req.form();
form.append('file', fs.createReadStream('./location/to/file'));

nodejs send mp3 from another server to the client

I have an express server it grabs stuff from my other server, edits it, and sends it to the client using the curl library (I tried request but it did the same thing). Everything works great except when I try sneding an MP3 file. If I try that then Chrome can't decode the MP3. However, If I access the MP3 from the original server it decodes fine and plays. I don't edit the MP3's. Here is what my code looks like:
// server2.example.com source
const curl = require("curl");
const edit = (b, p) => {};
const express = require("express");
/* ... express app stuff ... */
app.get("*", (req, res) => {
curl.get(
"http://server1.example.com" + req.path, {},
(err, response, body) => {
if (err) return;
res.type(response.headers["content-type"]).status(response.statusCode).send(edit(body, patches));
}
);
});
app.listen(80);
Once again the file is un-edited and the exact same file as the one on server1. Here is a screenshot of what I see when visiting server1.example.com/audio.mp3 versus server2.example.com/audio.mp3:
server2.example.com/audio.mp3 screenshot
server1.example.com/audio.mp3 screenshot

Download a youtube video file in node js using ytdl

I want to make user able to download a youtube video using node-ytdl.
For example when client side make a GET request for certain route the video should be downloaded in response.
var ytdl = require('ytdl-core');
var express= require('express');
//Init App Instance
var app=express();
app.get('/video',function(req,res){
var ytstream=ytdl("https://www.youtube.com/watch?v=hgvuvdyzYFc");
ytstream.on('data',function(data){
res.write(data);
})
ytstream.on('end',function(data){
res.send();
})
})
Above is my nodejs code. Even though in network it seems to download the response it does not make user download as a file.I don't want to store any file on server.It would be great if someone could help me how to solve the issue.
res object is a writable stream so you can directly pipe the output of ytdl to res object like this -
ytdl("http://www.youtube.com/watch?v=xzjxhskd")
.on("response", response => {
// If you want to set size of file in header
res.setHeader("content-length", response.headers["content-length"]);
})
.pipe(res);
You have to also pass the headers. Try it:
app.get('/video', (req, res) => {
var url = "https://www.youtube.com/watch?v=hgvuvdyzYFc";
res.header("Content-Disposition", 'attachment; filename="Video.mp4');
ytdl(url, {format: 'mp4'}).pipe(res);
});
If someone is still getting an error just update the package to latest version by running:
npm i ytdl-core#latest
Ok, so make a string var, then add data to it on the data event. On end, send everything. Here is an example:
const ytdl = require("ytdl-core"),
app = require("express")();
app.get("/video", (req, res) => {
let data = "", vid = ytdl("https://www.youtube.com/watch?v=hgvuvdyzYFc");
vid.on("data", d => data += d);
vid.on("end", () => res.send(data));
res.header("Content-Disposition", 'attachment; filename="Video.mp4');
});

Uploading large file to NodeJS webserver

I am serving up my web application using NodeJS server (ExpressJS) currently. One of the new requirements is for the users to be able to upload large videos (potentially in gigs) to the server. They will later then be able to download them again. Could I achieve this with the current stack?
I came across tutorials using Multer JS with "multipart/form-data" specified by the front-end. If I use this, would my Express be able to serve up other HTTP requests while writing a giant single video file to the server's disk?
Having done this myself (~20GB files, without multer) I can recommend the following (Probably most of which you have considered, but for completeness):
Choose an appropriate upload control (or write your own, but basically something that chunks up the data is best. I used plupload I think)
On the server make an API to handle the received chunk data, and write it out to a temp location during upload (You may want to hash and check individual pieces as well).
Once upload complete, check file (I used a hash generated by the client, and checked it against the uploaded data)
Multer should work fine. It'll stream the data as it comes in over HTTP to a file on disk. It won't lock up your server. Then in your endpoint you have access to that file location and can do whatever you need with it.
var express = require("express");
var app = express();
var async = require('async');
var fs = require('fs');
var client = redis.createClient();
var multiparty = require('multiparty');
var util = require('util');
app.post('/',function(req,res){
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
client.get(fields.otp, function(err, reply) {
var oldpath = files.file[0].path;
var newpath = path + files.file[0].originalFilename;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
});
}
}
app.listen(2001,function(){
console.log("Server is running on port 2001");
});

serve pdf files using node js & express

All the PDF files are saved in the filesystem on the server, how to make the files to be downloadable in client side.
for Ex :
app.use('/pdfDownload', function(req, res){
var pathToTheFile = req.body.fileName;
readFile(pathToTheFile, function(data){
//code to make the data to be downloadable;
});
});
is the request made
function readFile(pathToTheFile, cb){
var fs = require('fs');
fs.readFile(pathToTheFile, function(err, data){
//how to make the file fetched to be downloadable in the client requested
//cb(data);
});
}
You can use express.static, set it up early in your app:
app.use('/pdf', express.static(__dirname + '/pathToPDF'));
And it will automatically do the job for you when browser navigates to e.g. '/pdf/fooBar.pdf'.

Resources