简体   繁体   中英

How to use thread to play next song by MPRemoteCommandCenter?

I want to use MPRemoteCommandCenter to control my music player app. And now it can play and pause music, but can not play next/previous song, only a poor chance can make it.

When user tap next song button in MPRemoteCommandCenter(eg in the lock screen), it will call startExtendBGJob() function, then I ask for a thread to do the change song job(I think the bug is here, because I'm don't totally understand the background job's anatomy).

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!")
}

In startNextPlay() function just finding the next song's url, and prepareToPlay() is for creating a new AVPlayer to play next song.

self.tmpPlayer = AVPlayer(url: streamURL)

I'm not english native spearker, thank you so much to read here if you understand what I'm talking about :]. Any help is welcome.

Sorry, It's my fault. It doesn't need any backgournd job. Just change something like following:

UIApplication.shared.beginReceivingRemoteControlEvents()
do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)
} catch {
            DLog("fail to set category: \(error)")
}

Make sure it's AVAudioSessionCategoryPlayback

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM