AVAudioPlayer爆裂并弹出

时间:2017-12-07 03:40:17

标签: ios swift avaudioplayer

我有类似西蒙的记忆游戏,其中播放一系列音调并且用户尝试重复音调。问题是,我不时会听到一声可怕的噼啪声。它可能只是在几个笔记之后或多达二十个。声音都是长度为2秒的wav文件。我循环通过十个玩家,以便没有任何声音被剪裁。 (我已经尝试了50次,但这没有任何帮助。)我也尝试实施audioPlayerDidFinishPlaying,这样我就可以在声音完成后停止播放器,但这也无济于事。最后,我添加了prepareToPlay() - 遗憾的是,没有区别。

一个有趣或可能没有关系的有趣问题是,在大约15个音符的序列之后,音频停止一起工作。该应用程序继续正常,但没有任何声音。

以下是代码的音频部分:

func playSound(_ soundID: Int) {
        var soundName = ""

        switch soundID {
        case 0:
            soundName = "beep1"
        case 1:
            soundName = "beep2"
        case 2:
            soundName = "beep3"
        case 3:
            soundName = "beep4"
        case 4:
            soundName = "swish3"
        default:
            soundName = "clank"
        }

        guard let url = Bundle.main.url(forResource: soundName, withExtension: "wav") else { return }

        do {
            buttonSound.insert(try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue), at: playerIndex)
            buttonSound[playerIndex].prepareToPlay()
            buttonSound[playerIndex].delegate = self

            if playerIndex < 10 {
                buttonSound[playerIndex].play()
                playerIndex += 1
            } else {
                buttonSound[playerIndex].play()
                playerIndex = 0
            }

        } catch {
            // error
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if flag {
            player.stop()
        }
    }

/ ********更新********* /

我根据我跑过的某个过时的例子将AVAudioPlayer创建移动到了自己的类。它解决了15音调问题后完全切断的音频,然而,裂缝和爆裂仍然存在!我也试着没有运气重新录制声音。

以下是根据需要创建AVAudioPlayers的类:

import UIKit
import AVFoundation

private var players: [AVAudioPlayer] = []

class AVAudioPlayerPool: NSObject {

    class func playerWithURL(url: URL) -> AVAudioPlayer? {

        let availablePlayers = players.filter { (player) -> Bool in
            return player.isPlaying == false && player.url == url
        }

        if let playerToUse = availablePlayers.first {
            playerToUse.prepareToPlay()
            return playerToUse
        }

        do {
            let newPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
            players.append(newPlayer)
            newPlayer.prepareToPlay()
            return newPlayer

        } catch {
            return nil
        }
    }
}

播放声音很简单:

func playSound(_ soundID: Int) {
    var soundName = ""

    switch soundID {
    case 0:
        soundName = "tt1"
    case 1:
        soundName = "tt2"
    case 2:
        soundName = "tt3"
    case 3:
        soundName = "tt4"
    case 4:
        soundName = "swish3"
    default:
        soundName = "clank"
    }

    guard let url = Bundle.main.url(forResource: soundName, withExtension: "wav") else { return }
    let player = AVAudioPlayerPool.playerWithURL(url: url)
    player?.play()

}

如果有人有任何想法 - 即使只是下一步你可能会尝试......

3 个答案:

答案 0 :(得分:4)

在我看来,你的主要问题是声音加载是在应该播放声音本身的同一个函数内完成的。从概念上讲是错误的,为了能够尽可能快地播放声音,您应该在“播放”功能之外一劳永逸地加载声音。该功能应该发挥,就是这样。

答案 1 :(得分:1)

经过几个小时的实验,我会说这个问题是由我选择的声音引起的 - 一个带有混响的大而空心的方波合成声音。我首先尝试减少可能有帮助的水平思考。接下来,我尝试了各种不同的声音,但一切都爆裂了。我认为这更多地与我分配球员的方式有关。一旦我解决了播放器问题,我就不会再回去尝试不同的声音了。直到,我做了......它的确有效!

答案 2 :(得分:0)

我们刚刚遇到了团队中的问题。在我们的情况下,如果应用程序在连接了调试器的设备上运行,则可以重现失真的声音错误。一旦我们从调试器分离应用程序噼啪声消失。 看起来这个问题最初出现在新的Xcode 9.2(9C40b)中。