【问题标题】:How can I execute a custom ffmpeg string command with fluent-ffmpeg如何使用 fluent-ffmpeg 执行自定义 ffmpeg 字符串命令
【发布时间】:2020-01-18 13:10:46
【问题描述】:

如何将自定义命令传递给 fluent-ffmpeg(https://www.npmjs.com/package/fluent-ffmpeg/v/1.7.0)?我只想传递命令字符串。像

var command = FFmpeg("ffmpeg -i input.mp4 -i input.mp3 -c copy -map 0:v:0 -map 1:a:0 output.mp4")

我已经看过提供的示例,但似乎需要 ffmpeg 知识来了解什么是文件管理器、编解码器等......

【问题讨论】:

  • 我从未使用过它,但在我看来,您需要向 FFmpeg 构造函数发送一个对象,如 npm 页面文档中所示,或者使用方法设置选项。 github page 有更多文档。目前尚不清楚您的问题是什么。

标签: node.js fluent-ffmpeg


【解决方案1】:

不幸的是,在编写此 Fluent-ffmpeg 时仍然不支持自定义复杂的 FFMPEG 属性,因此唯一的解决方案是分叉它或诉诸丑陋的“黑客”,这会破坏该库的主要目的(对于大多数例)。

我将 Fluent-ffmpeg 与这个“hack”一起用作处理多个复杂 FFMPEG 进程的简洁包装器,并具有良好的输出/错误/进度解析。

const fluent = require('fluent-ffmpeg');

const executeFfmpeg = args => {
    let command = fluent().output(' '); // pass "Invalid output" validation
    command._outputs[0].isFile = false; // disable adding "-y" argument
    command._outputs[0].target = ""; // bypass "Unable to find a suitable output format for ' '"
    command._global.get = () => { // append custom arguments
        return typeof args === "string" ? args.split(' ') : args;
    };
    return command;
};

executeFfmpeg('-i input.mp4 -i input.mp3 -c copy -map 0:v:0 -map 1:a:0 output.mp4')
    .on('start', commandLine => console.log('start', commandLine))
    .on('codecData', codecData => console.log('codecData', codecData))
    .on('error', error => console.log('error', error))
    .on('stderr', stderr => console.log('stderr', stderr))
    .run();

注意:此解决方案不支持“进度”事件,但您可以通过 fluent-ffmpeg/lib/options.js 中的 extractProgress 方法解析“stderr”事件来轻松完成

【讨论】:

    【解决方案2】:

    下面的代码就是你需要的:

    const ffmpeg = require('child_process').exec
    
    ffmpeg("ffmpeg -i input.mp4 -i input.mp3 -c copy -map 0:v:0 -map 1:a:0 output.mp4")
    

    【讨论】:

    • 太棒了!即使您已经绕过 FFmpeg 库来执行系统命令
    【解决方案3】:

    你只需要将它传递给 outputOptions 方法。

    const ffmpeg = require('fluent-ffmpeg');
    
    ffmpeg()
      .input('input.mp4')
      .input('input.mp3')
      .outputOptions('-c copy -map 0:v:0 -map 1:a:0')
      .save('output.mp4');
    

    【讨论】:

      【解决方案4】:

      Dušan Brejka 的回答对我有用。

      fluent-ffmeg 使用 parseProgressLine 处理进度 https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/blob/12667091eeea09b0d6a55b87eb886aa131178608/lib/utils.js#L20

      这是我对解析进度的看法。它还负责解析数值。

          function handleProgress(progressLine: string): Record<string, string | number> {
            // Remove all spaces after = and trim.
            // each progress part is a key-value pai. ex: "frame=123", "time=01:23:45.67"
            const progressParts: string[] = progressLine
              .replace(/=\s+/g, "=")
              .trim()
              .split(" ");
          
            // build progress object
            const progress: Record<string, string | number> = {};
            for (const keyValuePair of progressParts) {
              const [key, value] = keyValuePair.split("=", 2);
              if (typeof value === "undefined") return null;
              const valueAsNumber = +value;
              progress[key] = !Number.isNaN(valueAsNumber) ? valueAsNumber : value;
            }
          
            // do something with progress object
            console.log(progress);
            return progress;
          }
      

      用于:

          executeFfmpeg(cmd)
            // attach handles
            .on("stderr", handleProgress)
            .run()
      

      【讨论】:

        猜你喜欢
        • 2021-02-19
        • 2020-04-26
        • 2014-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-11
        • 1970-01-01
        • 2011-08-25
        相关资源
        最近更新 更多