I wanted to find it here,but I found a similarity to this,but it wasn't for the node.js
how to mirror + add logo to video?
Here we can see a code:ffmpeg -i input.mp4 -i logo.png -filter_complex "hflip[flipped];[flipped]overlay=x=10:y=10" out.mp4
But i didn't understand how i can use it in Node.js
Please,help
you'll need to spawn FFMPEG from your node app:
var spawn = require('child_process').spawn;
var ffmpeg_process, feedStream=false;
var ops = [-i, input.mp4, -i, logo.png, -filter_complex, "hflip[flipped];[flipped]overlay=x=10:y=10", out.mp4];
ffmpeg_process=spawn('ffmpeg', ops);
//in this bit I was writing FFMPEG data to a socket, so I commented out those bits
ffmpeg_process.stderr.on('data',function(d){
//socket.emit('ffmpeg_stderr',''+d);
});
ffmpeg_process.on('error',function(e){
console.log('child process error'+e);
//socket.emit('fatal','ffmpeg error!'+e);
feedStream=false;
//socket.disconnect();
});
ffmpeg_process.on('exit',function(e){
console.log('child process exit'+e);
//socket.emit('fatal','ffmpeg exit!'+e);
//socket.disconnect();
});
a working example can be seen at livestream.a.video. GH: https://github.com/dougsillars/browserLiveStream
Related
I'm trying to merge a image to a video using ffmpeg.
This command works to me: ffmpeg -i merged-video.mp4 -loop 1 -i resized-image.png -shortest -c:a copy out.mp4
But it's not working when I do it in node.js, using fluent-ffmpeg.
My code is like this bellow:
const ffmpeg = require('fluent-ffmpeg');
ffmpeg()
.addInput(mergedVideo)
.loop(1)
.addInput(image)
.audioCodec('copy')
.outputOptions([
'-pix_fmt', 'yuv420p',
'-shortest'
])
.on('error', err => reject(err.message))
.on('end', resolve)
.save(finalResultVideo);
But it's getting error ffmpeg exited with code 1: Option loop not found.
When my ffmpeg command is built by my node.js application it does not run.
error
Unrecognized option 'ss 3.2 -t 1.9 -i videoplayback.mp4 -vf fps=15,scale=240:-1:flags=lanczos,palettegen palette.png'.
command
ffmpeg -ss 3.2 -t 1.9 -i videoplayback.mp4 -vf \ fps=15,scale=240:-1:flags=lanczos,palettegen palette.png
this is my code
var child_process = require('child_process')
function recordVideo() {
var spawn = child_process.spawn;
var args = [
'-y',
'-ss', '3.2',
'-t', '1.9',
'-i', '../getback/bin/videos/videoplayback.mp4',
'-vf', ' \\ ',
'fps=', '15',
'scale=', '320:-1',
'flags=','lanczos,palettegen palette.png',
];
var ffmpeg = spawn('ffmpeg', args);
ffmpeg.stdout.on('data', function (data) {
console.log(data);
});
ffmpeg.stderr.on('data', function (data) {
console.log('grep stderr: ' + data);
});
ffmpeg.on('close', (code) => {
console.log('child process exited with code ' + code);
});
};
recordVideo();
what is this error?
I think.. 'fps=', '15', In the following code
'=' options a problem.
I am still learning English.
I'm sorry if it was hard to understand.
Node will put a space between every argument in the array you give to child_process.spawn function, as the second argument, when it's building your command. Try replacing the argument pairs like "fps=" and "15" with a single argument: "fps=15".
For future reference one can view the spawned arguments by reading the spawnargs property from the created child process.
my problem is that when i try to turn a series of jpegs into a webm video. I either get a webm file with a single frame or a webm file with nothing in it (0 kb).
var fs = require('fs');
var path = require('path');
var outStream = fs.createWriteStream(__dirname+'/output.webm');
var ffmpeg = require('fluent-ffmpeg');
this one is a mjpeg stream URL. it produces a file with nothing.
//var proc = new ffmpeg({source:'http://xxx.xxx.xxx.xxx/goform/stream?cmd=get&channel=0',timeout:0})
this one is a snapshot URL. it produces a file with a single frame.
var proc = new ffmpeg({source:'http://xxx.xxx.xxx.xxx/snapshot/view0.jpg',timeout:0})
.fromFormat('mjpeg')
.size('2048x1536')
.toFormat('webm')
.withVideoBitrate('800k')
.withFps(20)
I have tried to use pipe instead but no dice :(
//.pipe(outStream,{end:false});
.writeToStream(outStream,{end:false})
any help is appreciated.
at this point i am up for using a basic shell command with exec but when i try that i just get errors also. Yes, it goes without saying I am a noob.
Side note:
I have tried things like zoneminder but it just breaks with our cameras and the number of cameras. so i am making a bare bones solution to record them. With our current cloud service we are missing very important moments and its costing more in energy and time.
thanks everyone that had a look and tried to figure it out :)
i have had some success with this method. It essentially works off a snapshot URL instead of the MJPEG. this uses request. but you could technically use anything since the method is using a pipe. image2pipe.
var spawn = require('child_process').spawn;
var request = require('request');
var args = '-f image2pipe -r 1 -vcodec mjpeg -i - -f webm -r 1 test3.webm';
var encoder = spawn('ffmpeg', args.split(' '));
encoder.stderr.pipe(process.stdout);
var interval = function(){
request('http://xxx.xxx.xxx.xxx/snapshot/view0.jpg',function(er){
if(er){console.log(er)}
setTimeout(function(){interval()},1000)
}).pipe(encoder.stdin,{end:false})
}
interval();
i could have used setInterval but i only wanted it to try again after it finished the request.
EDIT:
it turns out my camera was down when i was trying to use the method in the initial questions so im not sure if it works... but i know this does for MJPEG
var spawn = require('child_process').spawn;
var args = '-f mjpeg -framerate 1 -i http://xxx.xxx.xxx.xxx/goform/stream?cmd=get&channel=0 -vcodec libvpx -framerate 1 -bitrate 256k video_file.webm -y';
console.log(args)
var encoder = spawn('ffmpeg', args.split(' '));
encoder.stderr.pipe(process.stdout);
I want to use fluent-ffmpeg module to call ffmpeg with complex filter from Electron but have no success. The error '[AVFilterGraph # 0xb8.......] No such filter " Error initalizing complex filters . Invalid argument' is the same as in this question Error : Running FFmpeg command in Android ,splitting command in array not working but the context is different.
What is needed?
Run this ffmpeg command using fluent-ffmpeg:
ffmpeg -i safework-background-0.mp4 -i image1.png -i image2.png -i
image3.png -filter_complex "[0:v][1:v]
overlay=1:1:enable='between(t,5,8.5)' [tmp]; [tmp][2:v]
overlay=1:1:enable='between(t,8.5,12)' [tmp]; [tmp][3:v]
overlay=1:1:enable='between(t,12,15)'" test-video-safework3.mp4
It uses a complex filter to overlay three images on a video in sequence and exports a new video.
What doesn't work?
Obviously fluent-ffmpeg chokes with required quotes for complex filter, that is my conclusion (and is the same as for the Android variant question above).
What works without fluent-ffmpeg in Electron?
As you can guess I have to resort to calling ffmpeg directly. To help others, the following command, with input and output video filenames parametrized, translates to Electron as:
var spawn = require('child_process').spawn
var fargs = ['-y', '-i', sourceDir.path() + '/' + inVideoName, '-i', tempDir.path() + '/' + 'image1.png',
'-i', tempDir.path() + '/' + 'image2.png', '-i', tempDir.path() + '/' + 'image3.png',
'-filter_complex', '[0:v][1:v]overlay=1:1:enable=\'between(t,5,8.5)\'[tmp];' +
'[tmp][2:v]overlay=1:1:enable=\'between(t,8.5,12)\'[tmp];[tmp][3:v]' +
'overlay=1:1:enable=\'between(t,12,15)\'', targetDir.path() + '/' + outVideoName]
var ffmpeg = spawn(ffmpegc, fargs, { cwd:jetpack.cwd(app.getPath('home')).path() })
// some code ommitted
ffmpeg.on('close', (code) => {
console.log(`child process exited with code ${code}`)
webContents.send('notify-user-reply', 'Video processing done.')
})
The above command already has removed spaces between various filters (in complex filter) for each image or it would also choke.
I would really love to use fluent-ffmpeg in Electron, not just for the convenience of calling ffmpeg more elegantly but also for some additional features like easy progress reporting.
I am using node-rtsp-stream module to stream RTSP to web with nodejs.
I am streaming RTSP source with ffmpeg, for example RTSP SOURCE - EXAMPLE
I know that I can save one or many inputs to many outputs but I dont know if there is option to stream the input and save it to file at the same time without executing two process of ffmpeg.
With the following example I am able to stream the RTSP source
ffmpeg -i rtsp-url -rtsp_transport tcp -f mpeg1video -b:v 800k -r 30
On the module is look like that:
this.stream = child_process.spawn("ffmpeg", [ "-i", this.url, "-rtsp_transport", "tcp",'-f', 'mpeg1video', '-b:v', '800k', '-r', '30', '-'], {
detached: false
});
ff =child_process.spawn("ffmpeg", [ "-i", this.url, '-b:v', '800k', '-r', '30', '1.mp4'], {
detached: false
});
this.inputStreamStarted = true;
this.stream.stdout.on('data', function(data) {
return self.emit('mpeg1data', data);
});
this.stream.stderr.on('data', function(data) {
return self.emit('ffmpegError', data);
});
As you can see I am using two process of ffmpeg to do what I want but
If anyone faced with this issue and solve it with one command ( process ), I would like to get some suggestions.
How to stream RTSP source and save it to file at the same time.
for more information about the module I use:
node-rtsp-stream
try the code: (it will read RTSP and save to a jpg file (overwrite it every 3 seconds))
var fs = require('fs');
var spawn = require('child_process').spawn;
var rtspURI = 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov';
var fps = 1/3;
//avconv -i rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov \
// -r 1/3 -an -y -update 1 test.jpg
var ffmpeg = spawn('avconv', ['-i',rtspURI,'-r',fps,'-an','-y','-update','1','test.jpg']);
// var ffmpeg = spawn('avconv',
// ['-i','rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov',
// '-r','1/3','-an','-y','-update','1','test.jpg']);
ffmpeg.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ffmpeg.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
ffmpeg.on('close', function (code) {
console.log('child process exited with code ' + code);
});