首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVAudioPlayerNode卷更改不会立即应用

AVAudioPlayerNode卷更改不会立即应用
EN

Stack Overflow用户
提问于 2017-12-16 19:54:04
回答 2查看 1.7K关注 0票数 3

在Xcode9.2 (9C40b)上使用AVFoundation和AVAudioPlayerNode播放声音,并部署到iOS 11.2

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

在Xcode中启动一个新项目,选择iOS游戏,然后给出任意名称。然后将GameScene.swift中的代码替换为:

代码语言:javascript
复制
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的声音文件添加到项目中。

控制台输出为:

代码语言:javascript
复制
playing at 1.0
playing at 1.0
playing at 0.0
playing at 0.0
playing at 1.0
playing at 1.0

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

我真的听到了:响亮,什么都没有,柔和,响亮

(“软”这个词特别奇怪)

我还尝试使用以下命令更改主卷:

代码语言:javascript
复制
audioEngine.mainMixerNode.outputVolume = volume

但是声音是一样的。

在较老的游戏中,使用OpenAL,但这需要Obj-C,并且在桥接头等方面相当混乱。另外,OpenAL应该不再被支持。基于SKAction的音频无法快速处理大量重复的声音而不会出现故障和划痕(这是一个太空射击游戏……)模拟器和设备上的问题是相同的。感谢任何人的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-16 21:46:46

好了,我找到答案了。为了使更改立即生效,需要在卷更改后重置AudioEngine:

代码语言:javascript
复制
audioEngine.reset()

此play()函数起作用:

代码语言:javascript
复制
    func play(volume:Float) {
        print("playing at \(volume)")
        audioFilePlayer.volume = volume
        audioEngine.reset()
        audioFilePlayer.stop()
        audioFilePlayer.scheduleFile(audioFile, at: nil, completionHandler: nil)
        audioFilePlayer.play()
    }
票数 2
EN

Stack Overflow用户

发布于 2020-12-12 21:55:09

是的,如果其他人感兴趣,我还通过在输入源和engine.mainMixerNode之间添加一个AVAudioMixerNode解决了这个问题

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47845376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档