在 iOS 上使用 AVAudioPlayer 播放静音的最佳方式

Wit*_*ski 6 avaudioplayer ios swift avkit

我发现自己处于一种需要模拟音频播放来欺骗操作系统控件并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
]
Run Code Online (Sandbox Code Playgroud)

然后在我的自定义播放器中,一旦AVAudioPlayer完成当前项目的工作,我就会从数组中获取下一个项目,并.pause使用预定的播放器播放 aTimer.audio使用AVAudioPlayer.

extension Player: AVAudioPlayerDelegate {
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        playNextItem()
    }
}
Run Code Online (Sandbox Code Playgroud)

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

这就是问题所在

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

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

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

A. 保留 1 秒长的空音轨,只要需要暂停即可循环播放。

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

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

Rob*_*ier 4

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

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

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

  • 我已经用“AVMutableComposition”重新实现了整个过程,它按预期工作!多谢。 (2认同)