【问题标题】:Fade out volume of AVAudioPlayerNode programmatically以编程方式淡出 AVAudioPlayerNode 的音量
【发布时间】:2016-01-04 13:39:24
【问题描述】:

我有一个带有 AVAudioPlayerNode 的 AVAudioEngine 设置,它正在播放一些背景音乐。

我正在尝试找到一种最佳方法来在 2 秒的时间范围内在节点上创建音量淡出。我正在考虑使用 CADisplayLink 来做到这一点。我想知道是否有人有这种情况的经验并可以就他们的方法给我建议?

【问题讨论】:

    标签: ios objective-c iphone swift avaudioengine


    【解决方案1】:

    您可以在 EQ 中使用全局增益。

    例如

    AVAudioUnitEQ *Volume;
    Volume = [[AVAudioUnitEQ alloc] init];
    [engine attachNode:Volume];
    [engine connect:Volume to:engine.outputNode format:nil];
    

    然后

    Volume.globalGain = /*here your floatValue*/
    

    【讨论】:

      【解决方案2】:

      我的方法如下。请注意,我将计时器分配给成员 var,因此我可以在其他点(viewWillDisappeardelloc 等)使其无效。我担心它听起来不流畅,但我试了一下,它工作正常,不需要使用CADisplayLink

      - (void)fadeOutAudioWithDuration:(double)duration {
          double timerInterval = 0.1;
          NSNumber *volumeInterval = [NSNumber numberWithDouble:(timerInterval / duration)];
          self.fadeOutTimer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(fadeOutTimerDidFire:) userInfo:volumeInterval repeats:YES];
      }
      
      - (void)fadeOutTimerDidFire:(NSTimer *)timer {
          float volumeInterval = ((NSNumber *)timer.userInfo).floatValue;
          float currentVolume = self.audioEngine.mainMixerNode.outputVolume;
          float newValue = MAX(currentVolume - volumeInterval, 0.0f);
          self.audioEngine.mainMixerNode.outputVolume = newValue;
          if (newValue == 0.0f) {
              [timer invalidate];
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果像我这样的人仍在寻找答案:

        1. 从文档来看,AVAudioPlayerNode 不支持音量属性,只有 AVAudioMixerNode 节点支持。因此,请确保将 AVAudioPlayerNode 封装到 AVAudioMixerNode 中。

        2. 这是一个用于淡入、淡出和一般淡出的代码(Swift 5)

           typealias Completion = (() -> Void)
          
           let mixer = AVAudioMixerNode()
          
           func fade(from: Float, to: Float, duration: TimeInterval, completion: Completion?) {
               let stepTime = 0.01
               let times = duration / stepTime
               let step = (to - from) / Float(times)
               for i in 0...Int(times) {
                   DispatchQueue.main.asyncAfter(deadline: .now() + Double(i) * stepTime) {
                       mixer.volume = from + Float(i) * step
          
                       if i == Int(times) {
                           completion?()
                       }
                   }
               }
           }
          
           func fadeIn(duration: TimeInterval = 1.3, completion: Completion? = nil) {
               fade(from: 0, to: 1, duration: duration, completion: completion)
           }
          
           func fadeOut(duration: TimeInterval = 1.3, completion: Completion? = nil) {
               fade(from: 1, to: 0, duration: duration, completion: completion)
           }
          

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-13
          • 2015-04-29
          • 1970-01-01
          • 2023-03-14
          • 2010-11-16
          • 2013-01-24
          • 1970-01-01
          相关资源
          最近更新 更多