I'm having quite the trouble understanding how fps output works.
I have a video workflow through node and ffmpeg that transform picture into scrolling videos, here is the command :
const ffmpeg = spawn('ffmpeg', ['-f', 'lavfi', '-i', 'color=s=1280x720', '-loop', '1', '-i', `${path}/${video.name}`, '-filter_complex', `[1:v]scale=1280:-2,format=yuv420p,fps=fps=60[fg]; [0:v][fg]overlay=y=-\'t*h*0.02\'[v]`, '-map', '[v]', '-t', `${clipDuration}`, `./${path}/${video.name}-wip.mp4`])
ffmpeg.stderr.on('data', (data) => {
console.log(`${data}`);
});
ffmpeg.on('close', (code) => {
const ffmpeg2 = spawn('ffmpeg', ['-i', `./${path}/${video.name}-wip.mp4`, '-vf', `tpad=stop_mode=clone:stop_duration=3,fade=type=in:duration=1,fade=type=out:duration=1:start_time=${clipDuration + 2}`, `./${path}/${video.name}.mp4`])
ffmpeg2.stderr.on('data', (data) => {
console.log(`${data}`);
});
ffmpeg2.on('close', (code) => {
resolve();
});
})
First ffmpeg command create a scrolling video from picture,
second ffmpeg command add a fade out transition and a pause to this video.
FPS output for this is 25. How can i increase it to 60 so that scrolling isn't stuttering anymore ?
Thanks for your time.
try this
const ffmpeg2 = spawn('ffmpeg', ['-i', `./${path}/${video.name}-wip.mp4`, '-vf', `framerate=fps=60,tpad=stop_mode=clone:stop_duration=3,fade=type=in:duration=1,fade=type=out:duration=1:start_time=${clipDuration + 2}`, `./${path}/${video.name}.mp4`])
Note this from https://superuser.com/questions/1265642/ffmpeg-slideshow-with-crossfade:
ffmpeg -i temp.mp4 -vf "framerate=fps=60" -codec:v mpeg4 out.mp4
In commmand , Use it
ffmpeg -i main.mp4 -vf "framerate=fps=60" -codec:v mpeg4 out.mp4
Related
I have succesfully managed to establish a WebRTC connection between Node (server) and a browser. Server gets the video track on onTrack callback inside the RTCPeerConnection. Is there any way I can potentially convert the video track and make it work on ffmpeg so I can output it to rtmp.
Thanks in advance.
The way I have done this is to use a socket to the node server, and then use ffmpeg to convert to RTMP:
I spawn FFMPEG
var spawn = require('child_process').spawn;
spawn('ffmpeg',['-h']).on('error',function(m){
console.error("FFMpeg not found in system cli; please install ffmpeg properly or make a softlink to ./!");
process.exit(-1);
});
I make sure Im getting video from the socket, and then I pipe it into FFMPEG and out to my RTMP server:
var ops=[
'-i','-',
'-c:v', 'libx264', '-preset', 'ultrafast', '-tune', 'zerolatency', // video codec config: low latency, adaptive bitrate
'-c:a', 'aac', '-ar', audioBitrate, '-b:a', audioEncoding, // audio codec config: sampling frequency (11025, 22050, 44100), bitrate 64 kbits
//'-max_muxing_queue_size', '4000',
//'-y', //force to overwrite
//'-use_wallclock_as_timestamps', '1', // used for audio sync
//'-async', '1', // used for audio sync
//'-filter_complex', 'aresample=44100', // resample audio to 44100Hz, needed if input is not 44100
//'-strict', 'experimental',
'-bufsize', '5000',
'-f', 'flv', socket._rtmpDestination
];
}
console.log("ops", ops);
console.log(socket._rtmpDestination);
ffmpeg_process=spawn('ffmpeg', ops);
console.log("ffmpeg spawned");
you can see my code:https://github.com/dougsillars/browserLiveStream/blob/master/server.js
and a working example at livestream.a.video
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.
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);
});
i try to create a video thumbnail with fluent-ffmpeg here is my code
var ffmpeg = require('fluent-ffmpeg');
exports.thumbnail = function(){
var proc = new ffmpeg({ source: 'Video/express2.mp4',nolog: true })
.withSize('150x100')
.takeScreenshots({ count: 1, timemarks: [ '00:00:02.000' ] }, 'Video/', function(err, filenames) {
console.log(filenames);
console.log('screenshots were saved');
});
}
but i keep getting this error
"mate data contains no duration, aborting screenshot creation"
any idea why,
by the way am on windows, and i put the ffmpeg folder in c/ffmpeg ,and i added the ffmpeg/bin in to my environment varable, i dont know if fluent-ffmpeg need to know the path of ffmpeg,but i can successfully create a thumbnail with the code below
exec("C:/ffmpeg/bin/ffmpeg -i Video/" + Name + " -ss 00:01:00.00 -r 1 -an -vframes 1 -s 300x200 -f mjpeg Video/" + Name + ".jpg")
please help me!!!
I think the issue can be caused by the .withSize('...') method call.
The doc says:
It doesn't interract well with filters. In particular, don't use the size() method to resize thumbnails, use the size option instead.
And the size() method is an alias of withSize().
Also - but this is not the problem in your case - you don't need to set either the count and the timemarks at the same time. The doc says:
count is ignored when timemarks or timestamps is specified.
Then you probably could solve with:
const ffmpeg = require('fluent-ffmpeg');
exports.thumbnail = function(){
const proc = new ffmpeg({ source: 'Video/express2.mp4',nolog: true })
.takeScreenshots({ timemarks: [ '00:00:02.000' ], size: '150x100' }, 'Video/', function(err, filenames) {
console.log(filenames);
console.log('screenshots were saved');
});
}
Have a look at the doc:
https://github.com/fluent-ffmpeg/node-fluent-ffmpeg#screenshotsoptions-dirname-generate-thumbnails
FFmpeg needs to know the duration of a video file, while most videos have this information in the file header some file don't, mostly raw videos like a raw H.264 stream.
A simple solution could be to remux the video prior to take the snapshot, the FFmpeg 0.5 command for this task it's quite simple:
ffmpeg -i input.m4v -acodec copy -vcodec copy output.m4v
This command tells FFmpeg to read the "input.m4v" file, to use the same audio encoder and video encoder (no encoding at all) for the output, and to output the data into the file output.m4v.
FFmpeg automatically adds all extra metadata/header information needed to take the snapshot later.
Try this code to create thumbnails from Video
// You have to Install Below packages First
var ffmpegPath = require('#ffmpeg-installer/ffmpeg').path;
var ffprobePath = require('#ffprobe-installer/ffprobe').path;
var ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath);
var proc = ffmpeg(sourceFilePath)
.on('filenames', function(filenames) {
console.log('screenshots are ' + filenames.join(', '));
})
.on('end', function() {
console.log('screenshots were saved');
})
.on('error', function(err) {
console.log('an error happened: ' + err.message);
})
// take 1 screenshots at predefined timemarks and size
.takeScreenshots({ count: 1, timemarks: [ '00:00:01.000' ], size: '200x200' }, "Video/");