MPRemoteCommandCenter 如何使用线程播放下一首歌曲?
How to use thread to play next song by MPRemoteCommandCenter?
我想使用 MPRemoteCommandCenter 来控制我的音乐播放器应用程序。现在可以播放和暂停音乐,但不能播放next/previous首歌曲,只有很小的机会才能播放。
当用户点击 MPRemoteCommandCenter 中的下一首歌曲按钮时(例如在锁定屏幕中),它会调用 startExtendBGJob() 函数,然后我请求一个线程来完成换歌工作(我认为错误就在这里,因为我不完全了解后台作业的结构)。
func startExtendBGJob(taskBlock: @escaping () -> Void) {
registerBackgroundTask()
DispatchQueue.global(qos: .userInitiated).async {
DLog("APP into BG")
DispatchQueue.global(qos: .default).async {
taskBlock()
}
while self.isPlaying == false || self.tmpPlayer == nil { // waiting for new avplayer been created.
Thread.sleep(forTimeInterval: 1)
}
DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 10) {
self.endBackgroundTask()
}
}
}
func registerBackgroundTask() {
bgIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
[weak self] in
guard let strongSelf = self else { return }
strongSelf.endBackgroundTask()
})
assert(bgIdentifier != UIBackgroundTaskInvalid)
}
func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(bgIdentifier)
bgIdentifier = UIBackgroundTaskInvalid
isExtendingBGJob = false
DLog("App exit BG!")
}
在 startNextPlay() 函数中只是找到下一首歌曲的 url,而 prepareToPlay() 用于创建一个新的 AVPlayer 来播放下一首歌曲。
self.tmpPlayer = AVPlayer(url: streamURL)
我不是英语母语者,如果你明白我在说什么,非常感谢你阅读这里:]。欢迎任何帮助。
对不起,是我的错。它不需要任何后台作业。
只需更改如下内容:
UIApplication.shared.beginReceivingRemoteControlEvents()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
DLog("fail to set category: \(error)")
}
确保它是 AVAudioSessionCategoryPlayback
我想使用 MPRemoteCommandCenter 来控制我的音乐播放器应用程序。现在可以播放和暂停音乐,但不能播放next/previous首歌曲,只有很小的机会才能播放。
当用户点击 MPRemoteCommandCenter 中的下一首歌曲按钮时(例如在锁定屏幕中),它会调用 startExtendBGJob() 函数,然后我请求一个线程来完成换歌工作(我认为错误就在这里,因为我不完全了解后台作业的结构)。
func startExtendBGJob(taskBlock: @escaping () -> Void) {
registerBackgroundTask()
DispatchQueue.global(qos: .userInitiated).async {
DLog("APP into BG")
DispatchQueue.global(qos: .default).async {
taskBlock()
}
while self.isPlaying == false || self.tmpPlayer == nil { // waiting for new avplayer been created.
Thread.sleep(forTimeInterval: 1)
}
DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 10) {
self.endBackgroundTask()
}
}
}
func registerBackgroundTask() {
bgIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: {
[weak self] in
guard let strongSelf = self else { return }
strongSelf.endBackgroundTask()
})
assert(bgIdentifier != UIBackgroundTaskInvalid)
}
func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(bgIdentifier)
bgIdentifier = UIBackgroundTaskInvalid
isExtendingBGJob = false
DLog("App exit BG!")
}
在 startNextPlay() 函数中只是找到下一首歌曲的 url,而 prepareToPlay() 用于创建一个新的 AVPlayer 来播放下一首歌曲。
self.tmpPlayer = AVPlayer(url: streamURL)
我不是英语母语者,如果你明白我在说什么,非常感谢你阅读这里:]。欢迎任何帮助。
对不起,是我的错。它不需要任何后台作业。 只需更改如下内容:
UIApplication.shared.beginReceivingRemoteControlEvents()
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
DLog("fail to set category: \(error)")
}
确保它是 AVAudioSessionCategoryPlayback