Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Output format mp4 is not available #1262

Open
alpacaPwaa opened this issue Apr 10, 2024 · 14 comments
Open

Error: Output format mp4 is not available #1262

alpacaPwaa opened this issue Apr 10, 2024 · 14 comments

Comments

@alpacaPwaa
Copy link

alpacaPwaa commented Apr 10, 2024

Version information

  • fluent-ffmpeg version: 7.0-full_build-www.gyan.dev
  • ffmpeg version: 2.1.2
  • OS: Windows 11

Code to reproduce

createVideo: privateProcedure
    .input(
      z.object({
        fileId: z.string(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const { getUser } = getKindeServerSession();
      const user = await getUser();

      if (!user || !user.id || !user.email) {
        throw new TRPCError({ code: "UNAUTHORIZED" });
      }

      const dbUser = await db.user.findFirst({
        where: {
          id: user.id,
        },
      });

      if (!dbUser) {
        throw new TRPCError({
          code: "UNAUTHORIZED",
          message: "User not found in the database.",
        });
      }

      const putObjectCommand = new PutObjectCommand({
        Bucket: process.env.AWS_BUCKET_NAME!,
        Key: generateFileName(),
      });

      const s3 = new S3Client({
        region: process.env.AWS_BUCKET_REGION!,
        credentials: {
          accessKeyId: process.env.AWS_ACCESS_KEY!,
          secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
        },
      });

      const signedURL = await getSignedUrl(s3, putObjectCommand, {
        expiresIn: 60,
      });

      const ffmpeg = require("fluent-ffmpeg");
      const passthroughStream = new PassThrough();

      ffmpeg({ source: "./template1.mp4" })
        .on("end", async () => {
          console.log("Job done");
          await uploadToS3(passthroughStream);
        })
        .on("error", (error: string) => {
          console.error("Error:", error);
        })
        .videoFilter({
          filter: "drawtext",
          options: {
            text: "hi",
            fontsize: 100,
            fontcolor: "white",
            x: "(w-text_w)/2",
            y: "(h-text_h)/2",
            box: 1,
            boxcolor: "[email protected]",
            boxborderw: 5,
            fontfile: "/Windows/fonts/calibri.ttf",
          },
        })
        .noAudio()
        .addOutputOption("-f", "mp4")
        .videoCodec("libx264")
        .outputFormat("mp4")
        .outputOptions(["-movflags frag_keyframe+empty_moov"])
        .pipe(passthroughStream, { end: true });

      const uploadToS3 = async (stream: PassThrough) => {
        const upload = new Upload({
          client: s3,
          params: {
            Bucket: process.env.AWS_BUCKET_NAME!,
            Key: generateFileName(),
            Body: stream,
          },
        });
        await upload.done();
      };

      const createdVideo = await db.video.create({
        data: {
          name: "Test Name",
          url: signedURL.split("?")[0],
          key: signedURL,
          fileId: input.fileId,
        },
      });

      return createdVideo;
    }),

(note: if the problem only happens with some inputs, include a link to such an input file)

Expected results

I should be able to save the video to s3

Observed results

Error: Output format mp4 is not available
at eval (webpack-internal:///(rsc)/./node_modules/fluent-ffmpeg/lib/capabilities.js:589:21)
at nextTask (webpack-internal:///(rsc)/./node_modules/async/dist/async.mjs:5892:9)
at next (webpack-internal:///(rsc)/./node_modules/async/dist/async.mjs:5900:9)
at eval (webpack-internal:///(rsc)/./node_modules/async/dist/async.mjs:430:16)
at eval (webpack-internal:///(rsc)/./node_modules/fluent-ffmpeg/lib/capabilities.js:549:7)
at handleExit (webpack-internal:///(rsc)/./node_modules/fluent-ffmpeg/lib/processor.js:170:11)
at ChildProcess.eval (webpack-internal:///(rsc)/./node_modules/fluent-ffmpeg/lib/processor.js:184:11)
at ChildProcess.emit (node:events:518:28)
at ChildProcess._handle.onexit (node:internal/child_process:294:12)
at Process.callbackTrampoline (node:internal/async_hooks:130:17)

@Prameelagolusula
Copy link

same issue with me

@benharp
Copy link

benharp commented Apr 11, 2024

I have a similar issue (although all the formats seem broken for me)
Recently upgraded my ffmpeg version. Looks like newer versions of ffmpeg -formats have added a new info column for devices, which adds a space between the mux/demux columns and the format name:

New (build from March 2024):

Formats:
 D.. = Demuxing supported
 .E. = Muxing supported
 ..d = Is a device
 ---
  E  mp4             MP4 (MPEG-4 Part 14)

Old (build from June 2023):

File formats:
 D. = Demuxing supported
 .E = Muxing supported
 --
  E mp4             MP4 (MPEG-4 Part 14)

(Obviously, mp4 is just an example, I'm not going to paste the whole format list here.)

My guess at what is happening:
The regex that Fluent-FFmpeg uses to read FFmpeg's format list and determine its format support doesn't know how to read the extra space, so Fluent thinks there aren't any valid formats.
Regex is here:

var formatRegexp = /^\s*([D ])([E ]) ([^ ]+) +(.*)$/;

Then, when you try to run a command, the error checking at line 589 compares its (empty) list of valid formats to your format, determines it can't support the format, and throws the error.

@alpacaPwaa
Copy link
Author

alpacaPwaa commented Apr 11, 2024

@benharp I try running ffmpeg -format and I also had the same column for devices. Does this mean I have to downgrade my ffmpeg version? What version works for you?

Formats:
 D.. = Demuxing supported
 .E. = Muxing supported
 ..d = Is a device
 ---

@alpacaPwaa
Copy link
Author

alpacaPwaa commented Apr 12, 2024

@benharp followed your comment and downgraded my ffmpeg to ffmpeg version 6.1-full now it can finish the stream. Thanks your hint helps a lot!

@vimtor
Copy link

vimtor commented Apr 17, 2024

@alpacaPwaa should this issue be closed? I mean, you can fix it by downgrading the version, but now Homebrew installs version 7 by default so maybe this should be taken into account now.

@MarianoFacundoArch
Copy link

We should fix the regexpr and make a new fluent-ffmpeg version? Is that possible?
Any maintainer?

@alpacaPwaa
Copy link
Author

It seems like I have to re-open the issue, everyone here's right although there's a workaround for this issue it's still better to address the root cause.

@alpacaPwaa alpacaPwaa reopened this Apr 18, 2024
@DoomsdayDevice
Copy link

Use patch-package until it gets fixed. This worked in my case:

diff --git a/node_modules/fluent-ffmpeg/lib/capabilities.js b/node_modules/fluent-ffmpeg/lib/capabilities.js
index 3722ff1..3434210 100644
--- a/node_modules/fluent-ffmpeg/lib/capabilities.js
+++ b/node_modules/fluent-ffmpeg/lib/capabilities.js
@@ -15,7 +15,7 @@ var ffCodecRegexp = /^\s*([D\.])([E\.])([VAS])([I\.])([L\.])([S\.]) ([^ ]+) +(.*
 var ffEncodersRegexp = /\(encoders:([^\)]+)\)/;
 var ffDecodersRegexp = /\(decoders:([^\)]+)\)/;
 var encodersRegexp = /^\s*([VAS\.])([F\.])([S\.])([X\.])([B\.])([D\.]) ([^ ]+) +(.*)$/;
-var formatRegexp = /^\s*([D ])([E ]) ([^ ]+) +(.*)$/;
+var formatRegexp = /^\s*([D ])([E ])([d ]) ([^ ]+) +(.*)$/;
 var lineBreakRegexp = /\r\n|\r|\n/;
 var filterRegexp = /^(?: [T\.][S\.][C\.] )?([^ ]+) +(AA?|VV?|\|)->(AA?|VV?|\|) +(.*)$/;
 
@@ -527,7 +527,7 @@ module.exports = function(proto) {
       lines.forEach(function(line) {
         var match = line.match(formatRegexp);
         if (match) {
-          match[3].split(',').forEach(function(format) {
+          match[4].split(',').forEach(function(format) {
             if (!(format in data)) {
               data[format] = {
                 description: match[4],

@MarianoFacundoArch
Copy link

Fixed here #1266

You can also install package from: https://www.npmjs.com/package/fluent-ffmpeg-7 and just change the import to from 'fluent-ffmpeg-7'

I did a quick version there till official version gets fixed.

@Azarattum
Copy link

Is there a way to skip format checks? I want my code to work on both version of ffmpeg

@MarianoFacundoArch
Copy link

You can use my code, it works on both versions!

@MarianoFacundoArch
Copy link

You can directly install from the npm with npm i fluent-ffmpeg-7. I called like that just to reinforce that it also works on FFmpeg 7

@totallytavi
Copy link
Contributor

@njoyard Old issue

@vimtor
Copy link

vimtor commented May 29, 2024

This has been fixed in #1266

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants