【问题标题】:Feed output of one filter to the input of one filter multiple times with ffmpeg使用 ffmpeg 将一个过滤器的输出多次馈送到一个过滤器的输入
【发布时间】:2021-10-27 15:36:34
【问题描述】:

我有以下 ffmpeg 命令来创建播客剧集:

# remove all silence at start and end of the audio files
ffmpeg -i call.mp3 -af silenceremove=1:0:-50dB call1.mp3
ffmpeg -i response.mp3 -af silenceremove=1:0:-50dB response1.mp3

# remove silence longer than 1 second anywhere within the audio files
ffmpeg -i call1.mp3 -af silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB call2.mp3
ffmpeg -i response1.mp3 -af silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB response2.mp3

# normalize audio files
ffmpeg -i call2.mp3 -af loudnorm=I=-16:LRA=11:TP=0.0 call3.mp3
ffmpeg -i response2.mp3 -af loudnorm=I=-16:LRA=11:TP=0.0 response3.mp3

# cross fade audio files with intro/interstitial/outro
ffmpeg -i intro.mp3 -i call3.mp3 -i interstitial.mp3 -i response3.mp3 -i outro.mp3
  -filter_complex "[0][1]acrossfade=d=1:c2=nofade[a01];
                   [a01][2]acrossfade=d=1:c1=nofade[a02];
                   [a02][3]acrossfade=d=1:c2=nofade[a03];
                   [a03][4]acrossfade=d=1:c1=nofade"
  output.mp3

虽然这个“工作”很好,但我不禁觉得在一个 ffmpeg 命令中完成这一切会更有效率。根据我在网上发现的情况,这应该是可能的,但我对语法的理解不够好,无法知道如何使其工作。这是我尝试过的:

ffmpeg -i intro.mp3 -i call.mp3 -i interstitial.mp3 -i response.mp3 -i outro.mp3
       -af [1]silenceremove=1:0:-50dB[trimmedCall]
       -af [3]silenceremove=1:0:-50dB[trimmedResponse]
       -af [trimmedCall]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceCall]
       -af [trimmedResponse]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceResponse]
       -af [noSilenceCall]loudnorm=I=-16:LRA=11:TP=0.0[call]
       -af [noSilenceResponse]loudnorm=I=-16:LRA=11:TP=0.0[response]
      -filter_complex "[0][call]acrossfade=d=1:c2=nofade[a01];
                       [a01][2]acrossfade=d=1:c1=nofade[a02];
                       [a02][response]acrossfade=d=1:c2=nofade[a03];
                       [a03][4]acrossfade=d=1:c1=nofade"
  output.mp3

但我觉得我对此有一个根本的误解,因为我遇到了这个我不明白的错误:

Stream specifier 'call' in filtergraph description 
[0][call]acrossfade=d=1:c2=nofade[a01];
[a01][2]acrossfade=d=1:c1=nofade[a02];
[a02][response]acrossfade=d=1:c2=nofade[a03];
[a03][4]acrossfade=d=1:c1=nofade
       matches no streams.

为了增加上下文,我通过@ffmpeg/ffmpeg 运行所有这些命令,所以最后一个命令实际上看起来像这样(在 JavaScript 中):

await ffmpeg.run(
  '-i', 'intro.mp3',
  '-i', 'call.mp3',
  '-i', 'interstitial.mp3',
  '-i', 'response.mp3',
  '-i', 'outro.mp3',
  '-af', '[1]silenceremove=1:0:-50dB[trimmedCall]',
  '-af', '[3]silenceremove=1:0:-50dB[trimmedResponse]',
  '-af', '[trimmedCall]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceCall]',
  '-af', '[trimmedResponse]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceResponse]',
  '-af', '[noSilenceCall]loudnorm=I=-16:LRA=11:TP=0.0[call]',
  '-af', '[noSilenceResponse]loudnorm=I=-16:LRA=11:TP=0.0[response]',
  '-filter_complex', `
[0][call]acrossfade=d=1:c2=nofade[a01];
[a01][2]acrossfade=d=1:c1=nofade[a02];
[a02][response]acrossfade=d=1:c2=nofade[a03];
[a03][4]acrossfade=d=1:c1=nofade
  `,
  'output.mp3',
)

【问题讨论】:

    标签: javascript audio ffmpeg


    【解决方案1】:

    得到了@k1cc0on twitter的答复。根据他们的建议,我将我的代码更新为这个,它就像一个魅力:

    await ffmpeg.run(
      '-i', 'intro.mp3',
      '-i', 'call.mp3',
      '-i', 'interstitial.mp3',
      '-i', 'response.mp3',
      '-i', 'outro.mp3',
      '-filter_complex', `
        [1]silenceremove=1:0:-50dB[trimmedCall];
        [3]silenceremove=1:0:-50dB[trimmedResponse];
    
        [trimmedCall]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceCall];
        [trimmedResponse]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceResponse];
    
        [noSilenceCall]loudnorm=I=-16:LRA=11:TP=0.0[call];
        [noSilenceResponse]loudnorm=I=-16:LRA=11:TP=0.0[response];
    
        [0][call]acrossfade=d=1:c2=nofade[a01];
        [a01][2]acrossfade=d=1:c1=nofade[a02];
        [a02][response]acrossfade=d=1:c2=nofade[a03];
        [a03][4]acrossfade=d=1:c1=nofade
      `,
      'output.mp3',
    )
    

    实际上,这里是 ffmpeg 命令:

    ffmpeg  -i intro.mp3 -i call.mp3 -i interstitial.mp3 -i response.mp3 -i outro.mp3
      -filter_complex "[1]silenceremove=1:0:-50dB[trimmedCall];
                       [3]silenceremove=1:0:-50dB[trimmedResponse];
    
                       [trimmedCall]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceCall];
                       [trimmedResponse]silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB[noSilenceResponse];
    
                       [noSilenceCall]loudnorm=I=-16:LRA=11:TP=0.0[call];
                       [noSilenceResponse]loudnorm=I=-16:LRA=11:TP=0.0[response];
    
                       [0][call]acrossfade=d=1:c2=nofade[a01];
                       [a01][2]acrossfade=d=1:c1=nofade[a02];
                       [a02][response]acrossfade=d=1:c2=nofade[a03];
                       [a03][4]acrossfade=d=1:c1=nofade"
      output.mp3
    

    这里的关键是-filter_complex 允许你做我想做的事,所以如果你需要按顺序传递多个过滤器,那就是你需要的,然后你指定过滤器。

    【讨论】:

    • 如果有办法给输入加上别名,这样我就不必使用索引号了。如果有人知道该怎么做,请告诉我:)
    猜你喜欢
    • 1970-01-01
    • 2011-09-05
    • 2018-04-23
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    相关资源
    最近更新 更多