AVAudioPlayer produces lag despite prepareToPlay() in Swift

后端 未结 3 1149
情话喂你
情话喂你 2020-12-09 03:15

Playing a very short sound (~0.5s) produces a hiccup (like a lag) in my SpriteKit iOS game programmed in Swift. In other questions, I read that I should prepareToPlay(

相关标签:
3条回答
  • 2020-12-09 03:58

    I ran into this same problem and played the sound in the backgroundQueue.

    This is a good example: https://stackoverflow.com/a/25070476/586204.

    let qualityOfServiceClass = QOS_CLASS_BACKGROUND
    let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
    dispatch_async(backgroundQueue, {
        audioPlayer.play()
    })
    
    0 讨论(0)
  • 2020-12-09 03:58

    Just adding a Swift 3 version of the solution from @brilliantairic.

    DispatchQueue.global().async {
        audioPlayer.play()
    }
    
    0 讨论(0)
  • 2020-12-09 04:00

    When I called play multiple times it would cause bad access. I believe the player is being deallocated since this is not thread safe. I created a serial queue to alleviate this problem.

    class SoundManager {
    
        static let shared = SoundManager()
    
        private init() {
            try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try? AVAudioSession.sharedInstance().setActive(true)
        }
    
        private let serialQueue = DispatchQueue(label: "SoundQueue", qos: .userInitiated)
        private var player: AVAudioPlayer?
    
        static func play(_ sound: Sound) {
            shared.play(sound)
        }
    
        func play(_ sound: Sound) {
            guard let url = Bundle.main.url(forResource: sound.fileName, withExtension: "mp3")
                else { return }
    
            do {
                try serialQueue.sync {
                    self.player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)
                    DispatchQueue.main.async {
                        self.player?.play()
                    }
                }
            } catch let error as NSError {
                print("error: \(error.localizedDescription)")
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题