node.js - ENOENT Error in Node When Calling Ffmpeg binary from Fluent-Ffmpeg Api -
background
i wiring firebase function in node. purpose parse inbound audio clip set length. using ffmpeg , fluent-ffmpeg.
problem
when function triggered in firebase, getting enoent error when fluent-ffmpeg attempts access ffmpeg binary
firebase debug output
error: { error: spawn ./cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg enoent @ exports._errnoexception (util.js:1018:11) @ process.childprocess._handle.onexit (internal/child_process.js:193:32) @ onerrornt (internal/child_process.js:367:16) @ _combinedtickcallback (internal/process/next_tick.js:80:11) @ process._tickdomaincallback (internal/process/next_tick.js:128:9) code: 'enoent', errno: 'enoent', syscall: 'spawn ./cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg', path: './cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg',
spawnargs: [ '-formats' ] }
expected outcome
inbound file downloaded temp directory, cropped, , re-uploaded firebase storage cropped file.
environment
- mac client / firebase storage
- node v8.1.0
- ffmpeg v3.2.2
- fluent-ffmpeg v2.1.2
code [updated reflect svenskunganka's change. works]
const ffmpeg = require('fluent-ffmpeg'); const preview_prefix = 'preview_'; exports.generatepreviewclip = functions.storage.object('audiofiles').onchange(event => { //console.log('times function has run: ', run++); const object = event.data; // storage object. const filebucket = object.bucket; // storage bucket contains file. const filepath = object.name; // file path in bucket. const contenttype = object.contenttype; // file content type. const resourcestate = object.resourcestate; // resourcestate 'exists' or 'not_exists' (for file/folder deletions). const metageneration = object.metageneration; // number of times metadata has been generated. new objects have value of 1. // exit if triggered on file not audio file. if (!contenttype.startswith('audio/')) { console.log('this not audio file.'); console.log('this file:', filepath); return; } // file name. const filename = path.basename(filepath); console.log('working filename', filename); // exit if file audio clip. if (filename.startswith(preview_prefix)) { console.log('already preview clip.'); return; } // exit if move or deletion event. if (event.data.resourcestate === 'not_exists') { console.log('this deletion event.'); return; } // exit if file exists not new , being triggered // because of metadata change. if (resourcestate === 'exists' && metageneration > 1) { console.log('this metadata change event.'); return; } // download file bucket. const bucket = gcs.bucket(filebucket); const tempfilepath = path.join(os.tmpdir(), filename); return bucket.file(filepath).download({ destination: tempfilepath }).then(() => { console.log('audio file downloaded locally temp directory', tempfilepath); var ffmpegpath = require("ffmpeg-binaries").ffmpegpath(); var ffprobepath = require("ffmpeg-binaries").ffprobepath(); // generate croped file using ffmpeg. var command = new ffmpeg(tempfilepath); command.setffmpegpath(ffmpegpath); command.setffprobepath(ffprobepath); command .setstarttime('00:00:03') .setduration('10') .output(tempfilepath) .on('end', function() { console.log('audio crop done successfully'); }) .on('error', function(err) { console.log('error:', err); }).run(); }).then(() => { console.log('preview file created at', tempfilepath); // add 'preview_' prefix audio file name. that's how appear in firebase. const previewfilename = preview_prefix + filename; console.log('previewfilename is', previewfilename) const previewfilepath = path.join(path.dirname(filepath), previewfilename); console.log('previewfilepath is', previewfilepath); // uploading preview file. return bucket.upload(tempfilepath, {destination: previewfilepath}); // once file has been uploaded delete local file free disk space. }).then(() => fs.unlinksync(tempfilepath)); // [end audio file generation] });
contents , structure of ffmpeg-binaries/bin directory
-rwxrwxrwx 1 sherpa staff 24m dec 10 2016 ffmpeg -rwxr--r-- 1 sherpa staff 35m jan 12 2017 ffmpeg.exe -rwxr--r-- 1 sherpa staff 35m jan 12 2017 ffplay.exe -rwxrwxrwx 1 sherpa staff 24m dec 10 2016 ffprobe -rwxr--r-- 1 sherpa staff 35m jan 12 2017 ffprobe.exe -rwxrwxrwx 1 sherpa staff 22m dec 10 2016 ffserver
things have tried
- i can execute ffmpeg command line
- sudo chmod -r u+x ffmpeg-binaries/
- ffmpeg set in global path
- used ffmpeg.exe binary in setffmpegpath, got same result
- error: { error: spawn ./cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg.exe enoent
- played numerous different setffmpegpath path structures, e.g:
- ./cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg
- node_modules/ffmpeg-binaries/bin/ffmpeg
- ./cloud/functions/node_modules/ffmpeg-binaries/bin/
thanks suggestions.
we solved issue in comments question, i'll post answer future users might have same issue. problem path supplied setffmpegpath()
method relative, , should instead absolute. ffmpeg-binaries
module exports couple helper-functions can call paths binaries:
var ffmpeg = require("fluent-ffmpeg") var ffmpegbinaries = require("ffmpeg-binaries") var ffmpegpath = ffmpegbinaries.ffmpegpath() // path ffmpeg binary var ffprobepath = ffmpegbinaries.ffprobepath() // path ffprobe binary ffmpeg .setffmpegpath(ffmpegpath) ...
make sure have ffmpeg-binaries
installed npm -s ffmpeg-binaries
.
Comments
Post a Comment