fluent-ffmpeg / node-fluent-ffmpeg

A fluent API to FFMPEG (http://www.ffmpeg.org)
MIT License
7.63k stars 873 forks source link

Events are not fired after one FFMPEG command. #1230

Closed rohankanhaisingh closed 7 months ago

rohankanhaisingh commented 9 months ago

Version information

Code to reproduce

command.on("progress", function (progress: FFMPEG.Progress) {

    const downloadedBytes: number = progress.targetSize / 1000;

    console.log(downloadedBytes);

    if (downloadedBytes >= maxFileSize) {

        try {
            const responseObject: DownloadFailResponse = {
                statusCode: 507,
                timestamp: Date.now(),
                reason: `Download has been stopped because the maximum file size of ${maxFileSize}MB has been reached. The downloaded file size was ${downloadedBytes} bytes.`
            };

            console.log(`[FFMPEG]: Maximum file size of ${maxFileSize}MB has been reached.`.red);

            videoStream.destroy();
            command.kill("SIGINT");

            return res.status(507).json(responseObject);
        } catch (err) {

            return res.status(500).send((err as Error).message);
        }
    }
});

Expected results

The .on("progress"), and other events being fired.

Observed results

fluent-ffmpeg has been combined with ytdl to physically save any YouTube video onto my drive. I am using the .on("progress") event listeners to handle the file size; if the file reaches the maximum size of 10MB, the download should be aborted.

It seems like the events get fired all at once but will stop working afterwards. A new ffmpeg command will be created after each request. Here is a snippet of the code; it's obviously being shortened because it is, in reality, longer.


async function downloadYoutubeVideo(req: Request, res: Response) {

  ...

  const videoStream = ytdl(videoUrl, { quality: videoQuality, filter: "videoandaudio" });

  const command = ffmpeg(videoStream)
      .save(outputFileName)
      .audioCodec('aac')
      .audioBitrate(128)
      .inputOptions("-threads 1");

   ...
}
njoyard commented 7 months ago

The snippets above look like incorrect usage: you should call save() last. Create the instance, set all options, set event handlers, then run save().