允许使用 Swift 的背景音频不起作用
Posted
技术标签:
【中文标题】允许使用 Swift 的背景音频不起作用【英文标题】:Allowing background audio with Swift not working 【发布时间】:2017-10-21 08:36:41 【问题描述】:我想在应用未聚焦时允许背景音频。我目前有这段代码,应该允许:
do
try AKSettings.setSession(category: .playback, with: .mixWithOthers)
catch
print("error")
AKSettings.playbackWhileMuted = true
我还在功能设置中启用了“音频、Airplay 和画中画”设置。但是,当我按下设备上的主页按钮时,音频不会继续播放。我究竟做错了什么?如果这很重要,我正在使用AudioKit 来产生声音。
我使用单例来容纳我命名为 AudioPlayer.swift 的所有 AudioKit 组件。这是我的 AudioPlayer.swift 单例文件中的内容:
class AudioPlayer: NSObject
var currentFrequency = String()
var soundIsPlaying = false
var leftOscillator = AKOscillator()
var rightOscillator = AKOscillator()
var rain = try! AKAudioFile()
var rainPlayer: AKAudioPlayer!
var envelope = AKAmplitudeEnvelope()
override init()
super.init()
do
try AKSettings.setSession(category: .playback, with: .mixWithOthers)
catch
print("error")
AKSettings.playbackWhileMuted = true
AudioKit.output = envelope
AudioKit.start()
func setupFrequency(left: AKOscillator, right: AKOscillator, frequency: String)
currentFrequency = frequency
leftOscillator = left
rightOscillator = right
let leftPanner = AKPanner(leftOscillator)
leftPanner.pan = -1
let rightPanner = AKPanner(rightOscillator)
rightPanner.pan = 1
//Set up rain and rainPlayer
do
rain = try AKAudioFile(readFileName: "rain.wav")
rainPlayer = try AKAudioPlayer(file: rain, looping: true, deferBuffering: false, completionHandler: nil)
catch print(error)
let mixer = AKMixer(leftPanner, rightPanner, rainPlayer)
//Put mixer in sound envelope
envelope = AKAmplitudeEnvelope(mixer)
envelope.attackDuration = 2.0
envelope.decayDuration = 0
envelope.sustainLevel = 1
envelope.releaseDuration = 0.2
//Start AudioKit stuff
AudioKit.output = envelope
AudioKit.start()
leftOscillator.start()
rightOscillator.start()
rainPlayer.start()
envelope.start()
soundIsPlaying = true
下面是我的一个音效视图控制器的示例,它引用 AudioKit 单例来向其发送特定频率(我有大约十几个这样的视图控制器,每个都有自己的频率设置):
class CalmView: UIViewController
let leftOscillator = AKOscillator()
let rightOscillator = AKOscillator()
override func viewDidLoad()
super.viewDidLoad()
leftOscillator.amplitude = 0.3
leftOscillator.frequency = 220
rightOscillator.amplitude = 0.3
rightOscillator.frequency = 230
@IBAction func playSound(_ sender: Any)
if shared.soundIsPlaying == false
AudioKit.stop()
shared.setupFrequency(left: leftOscillator, right: rightOscillator, frequency: "Calm")
else if shared.soundIsPlaying == true && shared.currentFrequency != "Calm"
AudioKit.stop()
shared.leftOscillator.stop()
shared.rightOscillator.stop()
shared.rainPlayer.stop()
shared.envelope.stop()
shared.setupFrequency(left: leftOscillator, right: rightOscillator, frequency: "Calm")
else
shared.soundIsPlaying = false
shared.envelope.stop()
我在 ViewController.swift 文件中实例化了 AudioPlayer 单例。
【问题讨论】:
拥有足够的代码和拥有太多的代码之间只有一线之隔。您提出的问题已在下面得到解答。您似乎已正确设置。测试 AudioKit 示例 SongProcessor 以查看它是否按照应有的方式运行,然后将您的代码与它进行比较。有时没有捷径和简单的解决方案。 【参考方案1】:这取决于您进行配置的时间与 AudioKit 的启动时间有关。如果你使用 AudioKit,你应该使用它的 AKSettings 来管理你的会话类别。基本上不仅是播放类,还有mixWithOthers。默认情况下,这样做:
/// Set the audio session type
@objc open static func setSession(category: SessionCategory,
with options: AVAudiosessionCategoryOptions = [.mixWithOthers]) throws
所以你会在你的 ViewController 中做这样的事情:
do
if #available(iOS 10.0, *)
try AKSettings.setSession(category: .playAndRecord, with: [.defaultToSpeaker, .allowBluetooth, .allowBluetoothA2DP])
else
// Fallback on earlier versions
catch
print("Errored setting category.")
所以我认为这是直截了当的问题。设置应用间音频也可能会有所帮助。如果您仍然遇到问题并提供更多信息,我可以提供更多帮助,但根据您目前提供的信息,这是我所能收集到的最佳答案。
【讨论】:
我应该在设置这些设置之后还是之前启动 AudioKit?现在我的 ViewController.swift 中有这段代码,但我在另一个视图控制器中启动 AudioKit。这会导致问题吗? AudioKit 可能会覆盖您正在执行的设置,如果您先执行它们。我不建议在视图控制器中做任何音频。相反,为您的音频创建一个单例类 - 有时我们将其称为引擎或导体,并从您的所有视图控制器中引用它。您不希望视图控制器生命周期对音频引擎的状态产生任何影响。 我的音频播放器是单例的,我将原始帖子中的代码移到其中,但问题仍然存在。 好吧,我只是逐字使用更新问题中的代码来证明 AudioKit 中的 SongProcessor 示例在后台播放,所以我的回答对您的问题有效。也许你做错了什么。 github.com/AudioKit/AudioKit/commit/… 是否有我应该放置此代码的特定位置?我从您的链接中复制了突出显示的部分并将其放入我的 AudioPlayer.swift 单例中,但它仍然无法正常工作。以上是关于允许使用 Swift 的背景音频不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Windows 8.1 背景音频播放器在应用程序的其他页面中不起作用