我的音乐应用程序有问题。这个想法是点击一个按钮并播放更多来自当前正在播放的艺术家的歌曲。当我在应用程序中并点击下一首歌曲时,它运行良好。但是,如果我让歌曲自然结束,应用程序会随机播放一首歌曲。因此,我添加了逻辑来说明歌曲剩余时间是否为 0,然后使用媒体播放器 func 播放下一首歌曲,因为我知道这是可行的。这解决了它,除非应用程序在后台。如果它在后台,我试图让应用程序保持活动状态,但我想这不起作用。
每次我认为我已经解决了一些问题时,问题就会回来。
我期望发生的是锁定艺术家,将应用程序关闭到背景,当歌曲结束时播放艺术家的另一首歌曲。
实际发生的情况是,当我锁定艺术家并将应用程序关闭到后台时,歌曲将结束,有时它会播放正确的歌曲。有时它不会。但是,当它播放错误的歌曲并且我打开应用程序备份时,它会结束当前(错误)播放的歌曲并开始播放适当艺术家的歌曲
明确地说,我认为需要在歌曲剩余时间为 0 时运行的逻辑以跳到下一首歌曲是不明智的,但无论出于何种原因我都需要它
我已将功能设置为后台获取和音频 Airplay 和画中画
我试图只按顺序发布相关代码..
我有财产
let mediaPlayer = MPMusicPlayerController.systemMusicPlayer
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
在我的ViewDidLoad
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
DispatchQueue.main.async {
self.clearSongInfo()
MediaManager.shared.getAllSongs { (songs) in
guard let theSongs = songs else {
return
}
self.mediaPlayer.nowPlayingItem = nil
self.newSongs = theSongs.filter({ (item) -> Bool in
return !MediaManager.shared.playedSongs.contains(item)
})
self.aSongIsInChamber = true
self.mediaPlayer.setQueue(with: MPMediaItemCollection(items: self.newSongs.shuffled())
)
self.mediaPlayer.shuffleMode = .off
self.mediaPlayer.repeatMode = .none
}
NotificationCenter.default.addObserver(self, selector: #selector(self.songChanged(_:)), name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, object: self.mediaPlayer)
self.mediaPlayer.beginGeneratingPlaybackNotifications()
}
我有一个更新播放时间和剩余时间的函数,我有
if Int(self.songProgressSlider.maximumValue - self.songProgressSlider.value) < 1 {
print("song ended naturally, skipped")
mediaPlayer.prepareToPlay(completionHandler: { (error) in
DispatchQueue.main.async {
self.mediaPlayer.skipToNextItem()
}
})
}
当我播放音乐时,我有一个 bool isPlaying
如果是,那么时间在流逝,我有这个
let app = UIApplication.shared
var task: UIBackgroundTaskIdentifier?
task = app.beginBackgroundTask {
app.endBackgroundTask(task!)
}
我有它可以在后台保持计时器开启,这样当剩余时间为 0 时它将播放下一首歌曲
现在要锁定艺术家,我有以下代码在按钮点击时执行
let artistPredicate: MPMediaPropertyPredicate = MPMediaPropertyPredicate(value: nowPlaying.artist, forProperty: MPMediaItemPropertyArtist)
let query: MPMediaQuery = MPMediaQuery.artists()
let musicPlayerController: MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer
query.addFilterPredicate(artistPredicate)
musicPlayerController.setQueue(with: query)