代码之家  ›  专栏  ›  技术社区  ›  kentcdodds

使用ffmpeg将一个滤波器的输出多次馈送到一个滤波器的输入

  •  0
  • kentcdodds  · 技术社区  · 4 年前

    我有以下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',
    )
    
    0 回复  |  直到 4 年前
        1
  •  4
  •   kentcdodds    4 年前

    我从他那里得到了答案 @k1cc0 on 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 允许你做我想做的事情,所以如果你需要按顺序通过多个过滤器,那就是你需要的,然后你指定过滤器。