-1

I am trying to run this function but the it keeps returning undefined when I explicitly hardcode the return value.

const splitVideo = async (sid, video, part) => {
    let framesLocation =`${process.cwd()}/${dirs.videoFrames}/${sid}_${part}`;

    console.log(fs.existsSync(framesLocation));

    if(!fs.existsSync(framesLocation)) {
        console.log("making dir");
        f.s.mkdirSync(framesLocation);
    }

    ffmpeg(video)
        .on('end', () => {
             return "done";
         })
         .on('error', (err) => {
             throw err;
         })
         .screenshots({
              timestamps: [1,2],
              filename: `${sid}_${part}/frame-%s.png`,
              folder: `${process.cwd()}/${dirs.videoFrames}`
         });
};

Please help this is very frustrating.

Leon Wright
  • 401
  • 4
  • 12
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Andreas Apr 12 '18 at 17:00
  • 2
    What do you want it to return?, you can make it return a promise. What do you want to achieve here? – Abhishek Gupta Apr 12 '18 at 17:02
  • its an async function specified by the "async" keyword at the top. I "await" it from the other file. If I moved that return statement to the start of the function it works fine but when I move it to the the place it is at now It returns undefined; @AbhishekGupta – Leon Wright Apr 12 '18 at 17:06

3 Answers3

4

Your function does not return anything, thats why you are getting undefined. Wrap the ffmpeg call in new Promise(...) to be able to resolve its asynchronous result:

const splitVideo = async (sid, video, part) => {
    // ...

    return new Promise((resolve, reject) => {
        ffmpeg(video)
            .on('end', () => {
                resolve("done");
             })
            .on('error', (err) => {
                reject(err);
             })
             .screenshots({
                  timestamps: [1,2],
                  filename: `${sid}_${part}/frame-%s.png`,
                  folder: `${process.cwd()}/${dirs.videoFrames}`
             });
    };
};

const ret = await splitVideo(...);
console.log(ret);

Also note you need to await this function to be able to read the result (or get the result in then handler).

Martin Adámek
  • 16,771
  • 5
  • 45
  • 64
0

You can only await promises.

const splitVideo = async (sid, video, part) => {
// ...

const val = await new Promise((resolve, reject) => {
    ffmpeg(video)
        .on('end', () => {
            resolve("done");
         })
        .on('error', (err) => {
            reject(err);
         })
         .screenshots({
              timestamps: [1,2],
              filename: `${sid}_${part}/frame-%s.png`,
              folder: `${process.cwd()}/${dirs.videoFrames}`
         });
      //... more code using the val maybe?
      return val
  };
};
Abhishek Gupta
  • 1,297
  • 13
  • 28
0

The problem is that your ffmpeg(video) function inside your splitVideo async function is asynchronous. What's happening is that your splitVideo function is being called but it's returning undefined before your ffmpeg(video) function accomplishs. What can you do to resolve this?

You already defined your splitVideo function as an async function, this allows you to use the reserved word "await". But first let's encapsulate your ffmpeg(video) function inside a promise.

const splitVideo = async (sid, video, part) => {
    //Your code
    let promise = new Promise((resolve, reject) => {
         ffmpeg(video)
            .on('end', () => {
                  resolve("done");
             })
             .on('error', (err) => {
                 reject(err);
             })
             .screenshots({
                   timestamps: [1,2],
                   filename: `${sid}_${part}/frame-%s.png`,
                   folder: `${process.cwd()}/${dirs.videoFrames}`
             });
       });
try{
    return await promise;
 }catch(err){
    return err;        
}

This should be enough for your splitVideo function, but it's importante to pay attention cause unhandled promises rejections are deprecated and in the future will terminate your node.js process. What you need to do is also add a .catch() statement to you splitVideoFunction, something like:

splitVideo.catch((err) => {//your code}).then((result) => {//Your code})

Or your can call splitVideo inside an another async function and use:

try {
    await splitVideo(video);
}catch(err){
    //Your code
}

If you have any doubt about async/await like I had, you may find this question useful. Node.JS - Can`t get async throws with try/catch blocks

I hope it helps.

Henrique Borges
  • 479
  • 6
  • 15