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

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -