const ffmpeg = require('fluent-ffmpeg');
const videoFile = './f1.mp4';
ffmpeg.ffprobe(videoFile, (err,metaData) => {
const {duration} = metaData.format;
const startingTime = parseInt(duration - 60);
const clipDuration = 20;
ffmpeg()
.input(videoFile)
.inputOptions([`-ss ${startingTime}`])
.outputOptions([`-t ${clipDuration}`])
.output('./result.mp4')
.on('end', ()=> console.log('Done!'))
.on('error',(err)=>console.error(err))
.run();
});
So this is my node js code where I am cutting a clip of the video my choice and giving me an output. I run it by node index. js ( code is in index.js file)
I want to create a script that can run on the below command line
node index.js start_time end_time input/file/path.mp4 output/directory/
I mean it will be dynamic, as any input file from any directory and any output file from any directory like a function that will take user inputs and will accordingly. No manual set up.
Is there a way to do that?? I have tried many but all are manually on the command line or a manual node setup. I am trying to create a dynamic js file that will run for any input
What you probably want is process.argv. This is the argument vector: list of arguments, where the first two are the node process and the file being run. Example:
const args = process.argv.slice(2);
if (!args.length !== 4) {
console.error('Incorrect number of arguments');
process.exit(1);
}
const [ startTime, endTime, inputFile, outputDirectory ] = args;
Related
how can I check if child_process can run a command?
'echo' is a valid command that can be run in a terminal, but 'echoes' is not one. For example, if I do this
const cp = require('child_process')
cp.exec('echo hello')
it will work.
If I do this, though
const cp = require('child_process')
cp.exec('echoes hello') //notice how it is echoes instead of echo
it will just error, but maybe the user has a program that adds 'echoes' to a terminal, and in that case, it would be able to run, but if it errors it will just exit out of the process and I won't be able to check if it works.
Is there any way to do this? Thank you so much in advance!
You have to manually loop through dirs in $PATH env & perform look up on those directory.
eg: $PATH is set to /bin:/usr/local/bin then you have to perform
fs.access('/bin/' + command, fs.constants.X_OK)
and
fs.access('/usr/local/bin/' + command, fs.constants.X_OK)
solution would look like this.
const { constants: fsconsts } = require('fs')
const fs = require('fs/promises')
const path = require('path')
const paths = process.env.PATH.split(':')
async function isExecutable(command) {
const cases = []
for (const p of paths) {
const bin = path.join(p, command)
cases.push(fs.access(bin, fsconsts.X_OK)) // X_OK is bit flag which makes sure file is executable
}
await Promise.any(cases)
return command
}
const found = (bin) => console.log('found', bin)
const notfound = (errors) => {
console.log('not found or not executable')
// console.error(errors)
}
// passes
isExecutable('echo').then(found).catch(notfound)
isExecutable('node').then(found).catch(notfound)
// fails
isExecutable('shhhhhh').then(found).catch(notfound)
isExecutable('echoes').then(found).catch(notfound)
NOTE: I think my solution works only on *nix based OSs
In my current codes, it does only can read a text file, How can I make an Image (base64) file opened with Photos Application (Windows)? Is there any chance to do that? If it's impossible, please let me know!
const fs = require('fs')
fs.readFile('./Test/a.txt', 'utf8' , (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data)
return
})
Another possible solution is like this:
const cp = require('child_process');
const imageFilePath = '/aaa/bbb/ccc'
const c = cp.spawn('a_program_that_opens_images', [ `"${imageFilePath}"` ]);
c.stdout.pipe(process.stdout);
c.stderr.pipe(process.stderr);
c.once('exit', exitCode => {
// child process has exited
});
Do something like this:
const cp = require('child_process');
const c = cp.spawn('bash'); // 1
const imageFilePath = '/aaa/bbb/ccc'
c.stdin.end(`
program_that_opens_images "${imageFilePath}"
`); // 2
c.stdout.pipe(process.stdout); // 3
c.stderr.pipe(process.stderr);
c.once('exit', exitCode => { // 4
// child process has exited
});
what it does:
spawns a bash child process (use sh or zsh instead if you want)
writes to bash stdin, (inputting the command to run)
pipes the stdio from the child to the parent
captures the exit code from the child
I'm in another pickle I've realized over the past week that my images are not loading due to the fact the links have expired so I wanna find out how to go about using a file directory in the code.
Here's what I've tried:
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
var fs = require('fs');
var files = fs.readdirSync('C:\Users\nevbw\Desktop\games\FBIBot\images\hugs')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
}
});
and
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
const path = 'C:\Users\nevbw\Desktop\games\FBIBot\images\hugs';
const fs = require('fs');
fs.readdirSync(path).forEach(file => {
ranfile = Math.floor(Math.random() * file.length);
message.channel.sendFile(ranfile);
})
}
});
found out through searching and searching but found a answer the modified it to this, i hope people use this in future reference!
const num = (Math.floor(Math.random()* 5)+1).toString(); message.channel.send({files: [`./slap/slap${num}.gif`]})
Using fs.readdirSync('./images/') instead of fs.readFileSync('./images/') works easier, but then you will have to create the folder inside of VSC and put the images in the folder, you can also drag and drop the images into the solution and use:
var files = fs.readdirSync(`./images/`).filter(file => file.endsWith('.png'))
so that when it looks for an image, it doesn't select anything else. hope it helps for some people.
Happy to help.
You're using FS the wrong way. This Is What It Should Look Like :D Also Here Is Some Documentation on It ( https://nodejs.org/dist/latest-v13.x/docs/api/fs.html ).
-- Code --
Also Just As A Tip! I See You Are Using Full Directories, That's Quite Innificeng (E.g if You Change Your Username, Drive ID, etc.) so in fs provided the image is in the same folder you can just do ./(ImageName), or if it is in the same folder but under another say /FBIBot/Images you can do ./Images/(ImageName). ^^
--
What The Error Was: (I Unfortunately Cannot Test it But I Am Like 99% Sure).
You Were Using fs.readdirSync(path).forEach(file => { When You Were Meant To Be Using fs.readfilesync(path).forEach(file => {.
-- First Code --
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
var fs = require('fs');
var files = fs.readfileSync('C:\Users\nevbw\Desktop\games\FBIBot\images\hugs')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
}
});
-- Second Code --
});
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
var fs = require('fs');
var files = fs.readFileSync('C:\Users\nevbw\Desktop\games\FBIBot\images\hugs')
/* now files is an Array of the name of the files in the folder and you can pick a random name inside of that array */
let chosenFile = files[Math.floor(Math.random() * files.length)]
}
});
^^
I tagged watchman as it MIGHT be the solution I'm looking for, but I don't quite know how to use it in this way!
I have a directory
/imgs
/icons
/bird.png
/cat.png
/dog.png
/pig.png
and I have a file
/imgs/index.js
My index.js is responsible for importing all of the images and then exporting a single object for the rest of my project to use.
const bird = require('./icons/bird.png');
const cat = require('./icons/cat.png');
const dog = require('./icons/dog.png');
const pig = require('./icons/pig.png');
const Icons = { bird, cat, dog, pig };
export default Icons;
What I want to do is watch my imgs folder for new additions, and automatically update my index.js to import these new files and add them to my object. I need to import them with Common.js and export them with ES6.
Does anyone know a good solution to this problem?
A potential solution is to write a JavaScript script that generates your index.js like so:
'use strict';
const fs = require('fs');
const DIR = __dirname + '/imgs/icons';
const output = __dirname + '/imgs/index.js';
return fs.readdir(DIR, (err, files) => {
let result = '';
let references = [];
files.forEach(item => {
// assuming item has the format animal.png
let newReference = item.split('.')[0];
references.push(newReference);
result += `const ${newReference} = require('./icons/${item}');\n`;
});
result += `\nconst Icons = { ${references} };\n\nexport default Icons;`;
fs.writeFile(output, result, err => {
if (err) throw err;
console.log(output + ' updated');
});
});
Place that file (let's call it watcher.js for this purpose) in imgs's parent directory and make watchman run it whenever changes in your icons directory are detected:
watchman imgs/icons "node watcher.js"
Notice that if a new file gets put into the watched directory, the index.js-creating script will not re-run. Only if it gets altered again (even if just gets saved again with the same data), the index.js will reflect that change.
You can simply test that by running touch imgs/icons/crabigator.png twice and look at the watchman log and/or content of index.js.
When working in Python I always have this simple utility function which returns the file name and line number from where the function is called:
from inspect import getframeinfo, stack
def d():
""" d stands for Debug. It returns the file name and line number from where this function is called."""
caller = getframeinfo(stack()[1][0])
return "%s:%d -" % (caller.filename, caller.lineno)
So in my code I simply put a couple debug lines like this to see how far we get before some error occurs:
print d()
# Some buggy code here
print d()
# More buggy code here
print d(), 'here is the result of some var: ', someVar
This works really well for me because it really helps debugging quickly.
I'm now looking for the equivalent in a node backend script. I was searching around but I can't find anything useful (maybe I'm looking for the wrong words?).
Does anybody know how I can create a Javascript/nodejs function which outputs the file name and line number from where the function is called? All tips are welcome!
You can create an Error to get where the Error is, and its stack trace. Then you can put that into a function, to get the line where it is.
function thisLine() {
const e = new Error();
const regex = /\((.*):(\d+):(\d+)\)$/
const match = regex.exec(e.stack.split("\n")[2]);
return {
filepath: match[1],
line: match[2],
column: match[3]
};
}
console.log(thisLine());
This works for me in Google Chrome.
And also in node.
Note to #j08691's comment:
Both this and this seem to be using lineNumber, which is not present (as far as I could test) in NodeJS.
Printing line number with custom string
const moment = require('moment');
const log = console.log;
const path = require('path');
function getTime(time) { return moment().format('YYYY-MM-DD HH:mm:ss') };
function line(num = 2) {
const e = new Error();
const regex = /\((.*):(\d+):(\d+)\)$/
const match = regex.exec(e.stack.split("\n")[num]);
const filepath = match[1];
const fileName = path.basename(filepath);
const line = match[2];
const column = match[3];
return {
filepath,
fileName,
line,
column,
str: `${getTime()} - ${fileName}:${line}:${column}`
};
}
log(line().str, "mylog1");
log(line().str, "mylog2");
log(line().str, "mylog3");
OUTPUT
2021-11-22 13:07:15 - test.js:44:5 mylog1
2021-11-22 13:07:15 - test.js:45:5 mylog2
2021-11-22 13:07:15 - test.js:46:5 mylog3
You can use this gulp plugin gulp-log-line . It Logs file and line number without the extra cost of reading the stack.
you just have to install gulp and gulp-log-line using the
npm install gulp --save and npm install gulp-log-line command. after that you need to create and write the below code in gulpfile.js and run
gulp log-line to create a duplicate file in the build folder :-
var gulp = require('gulp');
var logLine = require('gulp-log-line');
gulp.task('line-log', function() {
return gulp.src("file.js", {buffer : true})
//Write here the loggers you use.
.pipe(logLine(['console.log', 'winston.info']))
.pipe(gulp.dest('./build'))
})
gulp.task('default', ['line-log'])
Example
file.js :-
console.log('First log')
var someVariable
console.log('Second log')
Becomes
console.log('file.js:1', 'First log')
var someVariable
console.log('file.js:3', 'Second log')
The only way I've found to get anything relating to line numbers is to trap the window.onerror function, and when there's an error that will get passed the error message, the file URL and the line number:
window.onerror = function(msg, url, line) {
alert(msg + "\n" + url + ":" + line);
};
This works for me on Chrome - I don't know about other browsers.
EDIT when this answer was given in Feb' 15 there was no mention of NodeJS in the question. That was only added in November '17.