在后台播放预定的音频

时间:2017-04-01 17:45:30

标签: ios iphone swift audio background

我在应用程序的后台播放音频非常困难。该应用程序是一个倒计时和播放铃声的计时器,一切都使用计时器工作。由于你无法在后台运行超过3分钟的计时器,我需要以另一种方式播放铃声。

用户可以选择铃铛并设置播放铃声的时间(例如,立即播放铃声,5分钟后播放铃声,每10分钟重复一次铃声等)。

到目前为止,我已尝试使用DispatchQueue.main使用通知,如果用户没有暂停计时器,这将正常工作。如果他们重新进入应用程序并暂停,我似乎无法取消此队列或暂停它。

接下来我尝试使用AVAudioEngine,并创建了一组节点。这些将在应用程序处于前台时播放,但似乎在后台停止时停止。此外,当我暂停引擎并稍后恢复时,它不会正确暂停序列。它会把钟声压得一个接一个地打或者根本不打。

如果有人对如何解决我的问题有任何想法,那就太棒了。从技术上讲,我可以尝试从引擎中删除所有内容,并在用户暂停/恢复的暂停时间重新创建它,但这似乎相当昂贵。它也没有解决后台音频停止的问题。我有所需的背景模式'App播放音频或使用Airplay播放音频/视频',并且还在功能的后台模式下进行检查。

以下是我尝试设置音频引擎的示例。 registerAndPlaySound方法被多次调用以创建节点链(或者这样做不正确?)。这段代码有点混乱,因为我一直在努力尝试让它发挥作用。

func setupSounds{     
 if (attached){
        engine.detach(player)
    }
    engine.attach(player)
    attached = true

    let mixer = engine.mainMixerNode
    engine.connect(player, to: mixer, format: mixer.outputFormat(forBus: 0))
    var bell = ""
    do {
        try engine.start()
    } catch {
        return
    }
if (currentSession.bellObject?.startBell != nil){
        bell = (currentSession.bellObject?.startBell)!
        guard let url = Bundle.main.url(forResource: bell, withExtension: "mp3") else {
            return
        }
        registerAndPlaySound(url: url, delay: warmUpTime)
    }
}



func registerAndPlaySound(url: URL, delay: Double) {
    do {
        let file = try AVAudioFile(forReading: url)
        let format = file.processingFormat
        let capacity = file.length
        let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(capacity))
        do {
            try file.read(into: buffer)
        }catch {
            return
        }
        let sampleRate = buffer.format.sampleRate
        let sampleTime = sampleRate*delay
        let futureTime = AVAudioTime(sampleTime: AVAudioFramePosition(sampleTime), atRate: sampleRate)
        player.scheduleBuffer(buffer, at: futureTime, options: AVAudioPlayerNodeBufferOptions(rawValue: 0), completionHandler: nil)
        player.play()
    } catch {
        return
    }
}

0 个答案:

没有答案