首页 > 解决方案 > 在 iOS 上使用 AVAudioPlayer 播放静音的最佳方式

问题描述

我发现自己需要模拟音频播放以欺骗操作系统控件并MPNowPlayingInfoCenter认为正在播放音频。这是因为我正在构建一个播放多个音轨的播放器,在创建一个连续的“音频”音轨之间有暂停。我已经在应用程序本身内进行了所有设置,并且锁屏控件工作正常,但我面临的唯一问题是,当实际音频停止并且正在“播放”暂停时,锁屏信息中心会停止计时器,并且一旦另一个音轨开始播放,它只会继续显示正确​​的时间和整体状态。

这是我从音频文件和暂停项目构建的音轨示例:

let items: [AudioItem] = [
    .audio("part-1.mp3"),
    .pause(duration: 5), // value of type: TimeInterval
    .audio("part-2.mp3"),
    .pause(duration: 3),
    ... // the list goes on
]

然后在我的自定义播放器中,一旦AVAudioPlayer完成当前项目的工作,我会从数组中获取下一个并播放 a.pause与预定Timer或另一个.audioAVAudioPlayer.

extension Player: AVAudioPlayerDelegate {
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        playNextItem()
    }
}

问题就在这里,一旦AVAudioPlayer停止,正在播放的信息中心也会自动停止,即使我一直在喂它新鲜nowPlayingInfo。然后当它碰到另一个.audio项目时,它会正确恢复并显示当前时间等。

这就是问题所在

如何MPNowPlayingInfoCenter在我“播放”我的项目时让他们认为正在播放音频.pause

我意识到,我想要实现的目标可能仍然不清楚,但如果需要,我很乐意分享更多见解。谢谢!

我目前正在考虑的一些解决方案:

A. 保持 1 秒长的空音轨,只要需要暂停播放,就会循环播放。

B.以适当的长度以编程方式创建空音轨并播放它,而不是Timer用于跟踪暂停持续时间/进度,并完全依赖 AVAudioPlayer.audio.pause项目。虽然不确定这是可能的。

C. 也许有一种方法可以告诉MPNowPlayingInfoCenter音频在不需要使用AVAudioPlayer但我不熟悉的一些 API 的情况下继续播放?

标签: iosswiftavaudioplayeravkit

解决方案


AVAudioPlayer 在这里可能是错误的工具。您需要 AVAudioPlayerNode,它的级别略低。创建一个 AVAudioEngine,并附加一个AVAudioPlayerNode。然后,您可以scheduleFile(_:at:completionHandler:)在需要的时间拨打电话播放音频。

大部分关于AVAudioEngine的 Apple 文档此时似乎都已损坏,但希望这些链接很快会在Audio Engine Building Blocks的链接中再次可用。(如果它一直处于关闭状态并且您无法找到文档,请发表评论,我将搜索 WWDC 视频和其他有关使用 AVAudioEngine 的教程。对于简单的问题并不是特别困难。)

如果您事先知道要如何组合这些项目(看起来您可能会),另请参阅 AVMutableComposition,它可以让您非常有效地将资产粘合在一起,包括添加空的静音片段。有关该空间中的各种工具,请参阅媒体合成和编辑


推荐阅读