6

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

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

4

3 回答 3

5

我的方法如下。请注意,我将计时器分配给成员 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];
    }
}
于 2016-07-01T13:53:58.247 回答
2

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

例如

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

接着

Volume.globalGain = /*here your floatValue*/
于 2016-01-13T10:58:10.937 回答
0

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

  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)
     }
    
于 2021-03-17T11:10:14.063 回答