AVAudioPlayerNode音量更改不会立即应用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVAudioPlayerNode音量更改不会立即应用相关的知识,希望对你有一定的参考价值。

使用AVFoundation和AVAudioPlayerNode使用Xcode版本9.2(9C40b)播放声音并部署到ios 11.2

问题是当你改变音量时,第一次播放声音时不会应用改变,还有其他奇怪的效果。

在Xcode中启动一个新项目,选择iOS Game,并提供任何名称。然后用以下代码替换GameScene.swift中的代码:

import SpriteKit
import GameplayKit
import AVFoundation

class GameScene: SKScene {

    var entities = [GKEntity]()
    var graphs = [String : GKGraph]()

    let audioFilePlayer = AVAudioPlayerNode()
    var audioFile:AVAudioFile! = nil
    var audioFileBuffer:AVAudioPCMBuffer! = nil

    override func sceneDidLoad() {
        do {
            let path = Bundle.main.path(forResource: "sound", ofType: "caf")!
            let url = URL(fileURLWithPath: path)
            audioFile = try AVAudioFile(forReading: url)
            audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat, frameCapacity: UInt32(audioFile.length))
            try audioFile.read(into: audioFileBuffer!)
            audioEngine.attach(audioFilePlayer)
            audioEngine.connect(audioFilePlayer, to: audioEngine.mainMixerNode, format: audioFileBuffer?.format)
            try audioEngine.start()
        }
        catch {
            print(error)
        }

        let playAction = SKAction.sequence([
            SKAction.wait(forDuration: 3.0),
            SKAction.run { self.play(volume: 1.0) },
            SKAction.wait(forDuration: 1.0),
            SKAction.run { self.play(volume: 1.0) },
            SKAction.wait(forDuration: 1.0),
            SKAction.run { self.play(volume: 0.0) },
            SKAction.wait(forDuration: 1.0),
            SKAction.run { self.play(volume: 0.0) },
            SKAction.wait(forDuration: 1.0),
            SKAction.run { self.play(volume: 1.0) },
            SKAction.wait(forDuration: 1.0),
            SKAction.run { self.play(volume: 1.0) },
            ])
        self.run(playAction)

    }

    func play(volume:Float) {
        print("playing at (volume)")
        audioFilePlayer.stop()
        audioFilePlayer.volume = volume
        audioFilePlayer.scheduleFile(audioFile, at: nil, completionHandler: nil)
        audioFilePlayer.play()
    }

}

为可怜的选项道歉......另外,在项目中添加一个名为sound.caf的声音文件。

控制台输出是:

playing at 1.0
playing at 1.0
playing at 0.0
playing at 0.0
playing at 1.0
playing at 1.0

我希望听到:响亮,响亮,没有,没有,没有,响亮,响亮。

我实际上听到:响亮,响亮,响亮,没有,柔软,响亮

('软'特别奇怪)

我也尝试用以下方法更改主音量:

audioEngine.mainMixerNode.outputVolume = volume

但声音是一样的。

在较旧的游戏中,曾经使用OpenAL,但这需要Obj-C并且在桥接标题等方面非常混乱。而且,OpenAL据说不再受支持了。基于SKAction的音频无法处理大量快速重复的声音而没有毛刺和划痕(这是一个太空射击游戏......)问题在模拟器和设备上是相同的。任何帮助赞赏!

答案

好的,我找到了答案。音量变化后需要重置AudioEngine才能使更改立即生效:

audioEngine.reset()

这个play()函数有效:

    func play(volume:Float) {
        print("playing at (volume)")
        audioFilePlayer.volume = volume
        audioEngine.reset()
        audioFilePlayer.stop()
        audioFilePlayer.scheduleFile(audioFile, at: nil, completionHandler: nil)
        audioFilePlayer.play()
    }

以上是关于AVAudioPlayerNode音量更改不会立即应用的主要内容,如果未能解决你的问题,请参考以下文章

带有 AVAudioPlayerNode 的 SpriteKit 位置音频

在 iOS 上的 flex 中更改 StageVideo 的音量

如何实时改变音量

更改不会立即出现在 drupal 的首页

didSelectRowAtIndexPath - colorText 更改不会立即更新

插入后不会立即更改 Blazor 文本