Node.js spawn not working with quotes inside argument - node.js

I'm trying to run this command with spawn
var args = ['-ss','00:00:15','-i',storage_path + doc.file_name,'-vframes','1','-vf','"scale='+size*2+':ih*'+size*2+'/iw,crop='+size+':'+size+'"','-f','image2','-q:v','5',storage_path + output_name];
var command = spawn('ffmpeg', args);
The issue seems to be with this part here: '"scale='+size*2+':ih*'+size*2+'/iw,crop='+size+':'+size+'"'
When I log the args, this is what I get:
[ '-ss',
'00:00:15',
'-i',
'/a/video.mp4',
'-vframes',
'1',
'-vf',
'"scale=150:ih*150/iw, crop=75:75"',
'-f',
'image2',
'-q:v',
'5',
'/a/75.jpg' ]
If I take that, and do .join(' '), I get the command:
-ss 00:00:15 -i /a/video.mp4 -vframes 1 -vf "scale=150:ih*150/iw, crop=75:75" -f image2 -q:v 5 /a/75.jpg
When I run ffmpeg with this, all is good.
Any ideas how to format this for spawn arguments?
Thank you!

Don't use quotes for vf:
'scale='+size*2+':ih*'+size*2+'/iw,crop='+size+':'+size

Related

spawn ffmpeg process fails with permission denied

I'm trying to spawn a ffmpeg process to encode some audio files to hls compatible mpegts files. I need to feed the data via pipe in order to handle the live stream part. I'm using the code below to spawn my process:
var file = fs.createReadStream('./audio.mp3');
var child = spawn('ffmpeg',
['-y', '-i', 'pipe:', '-c', 'aac', '-b:a', '32k', '-hls_segment_type', 'mpegts', '-hls_time', 1, '-hls_list_size', 0, './' + req.body.uri + '_32k.m3u8'], {
env: process.env,
stdio: ['pipe', 1, 2]
}
);
file.pipe(child.stdin);
strangely I get pipe:: Permission denied from stderr of ffmpeg.

Run imageMagick command with Nodejs

I am trying to improve the quality of a scanned PDF to proceed to OCR. I found the command textcleaner that uses ImageMagick. So how can I include this :
textcleaner -g -e normalize -f 30 -o 12 -s 2 original.jpg output.jpg in my Nodejs code ?
you can use exec:
exec(`textcleaner -g -e normalize -f 30 -o 12 -s 2 ${inputName} ${outputName}`);
or use a child process
const { spawn } = require('child_process');
const textcleaner = spawn('textcleaner', ['-g', '-e', 'normalize', '-f 30', '-o 12', '-s 2', inputName, outputName]);
textcleaner.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});

Generate ffmpeg thumbnail from stream in Node.js

Im using node.js together with ffmpeg to receive an rtmp-stream and output this into m3u8-format.
[ '-y',
'-fflags',
'nobuffer',
'-analyzeduration',
'1000000',
'-i',
'rtmp://localhost:1935/live/ANMZJ2ZRUiMhKaAoygRXwAfHe',
'-c:v',
'copy',
'-c:a',
'aac',
'-f',
'tee',
'-map',
'0:a?',
'-map',
'0:v?',
'-y',
'-an',
'[hls_time=10:hls_list_size=0]./media/live/ANMZJ2ZRUiMhKaAoygRXwAfHe/SX3otgDdf6/index.m3u8|' ]
Together with this functionality I would also like to output a thumbnail. I tried to do this using the following format but without success.
[ '-y',
'-fflags',
'nobuffer',
'-analyzeduration',
'1000000',
'-i',
'rtmp://localhost:1935/live/ANMZJ2ZRUiMhKaAoygRXwAfHe',
'-c:v',
'copy',
'-c:a',
'aac',
'-f',
'tee',
'-map',
'0:a?',
'-map','0:v?',
'-y',
'-an',
'-vf' ,
'fps=1',
'C:/Users/media/out.png'
'[hls_time=10:hls_list_size=0]./media/live/ANMZJ2ZRUiMhKaAoygRXwAfHe/SX3otgDdf6/index.m3u8|' ]
The way I send this information to ffmpeg is by
this.ffmpeg_exec = spawn(ffmpeg_path, args);
Im unable to create a thumbnail using this approach. Does anyone know the problem/solution?
You have a log of extra arguments in the second command! You really only need the input, number of frames, and output.
[ '-i',
'rtmp://localhost:1935/live/ANMZJ2ZRUiMhKaAoygRXwAfHe',
'-frames:v',
'1',
'C:/Users/media/out.png'
]
Docs for -frames:v
https://ffmpeg.org/ffmpeg.html#Video-Options
fluent-ffmpeg support stream input and output :
var FfmpegCommand = require('fluent-ffmpeg');
var ffmpeg = FfmpegCommand();
ffmpeg.input(stream)
.seekInput("00:00:01.000")
.outputFormat("image2")
.pipe(res,{end:true});

How can I execute bash command line in Exec resource type?

I have this Exec declaration:
exec { 'Normalize MP3 filename':
environment => ["t=0"],
command => 'for i in *mp3; do mv -v $i track_`seq -f "%03g" $t $t`.mp3 ; t=`expr $t + 1`; done',
cwd => "$resource_path/res/raw",
} ->
When my manifest runs it get this error:
Error: Could not find command 'for'
Error: /Stage[main]/Make_it::App_mp3files/Exec[Normalize MP3 filename]/returns: change from notrun to 0 failed: Could not find command 'for'
The default exec provider on *nix OSes is posix, which does not support shell built-ins such as for. You should change the provider to shell to use shell built-ins.
exec { 'Normalize MP3 filename':
environment => ["t=0"],
command => 'for i in *mp3; do mv -v $i track_`seq -f "%03g" $t $t`.mp3 ; t=`expr $t + 1`; done',
cwd => "$resource_path/res/raw",
provider => 'shell',
} ->

nodemon : Passing arguments to the executable when using as a required module

I'm trying to start a script with nodemon, using it as a required module, and I cannot pass arguments correctly.
For example, for
var args = [
process.argv[0], '--harmony',
'/path/to/script.js', '-i', 'logs'
];`
I'm expecting the script to be launched as :
node --harmony /path/to/script.js -i logs
But it doesn't work and all I can manage to get is
node --harmony /path/to/script.js -i logs /path/to/script.js
This is what I tried :
var app = require('nodemon')({
script: args[2],
exec: args.join(' ')
});
I know about execMap, but it's no good as I cannot pass arguments at the end anyway.
How can it be done?
Skimming through the source code, I found the args config options (undocumented...). It turns out to be what I needed.
var app = require('nodemon')({
exec: args.slice(0, 2),
script: args[2],
args: args.slice(3)
});
I recommend use gulp with nodemon
var argv = require('optimist').argv
gulp = require("gulp"),
nodemon = require("gulp-nodemon");
gulp.task("default", [], function(){
nodemon({
script: 'app.js',
ignore: ["public/*"],
env: {'NODE_ENV': 'development'},
args: ["--port="+argv.port],
exec: "node --harmony"
}).on("start");
});

Resources