媒体播放器过滤和预置专辑播放专辑、随机歌曲,然后再次播放专辑



我正在尝试制作音乐播放器,目前我被困在过滤和预置专辑到播放列表中。

我正在尝试做的是在随机播放音乐,然后当用户点击按钮时,仅继续播放当前正在播放的专辑中的歌曲,完成后我想知道它已完成,以便我可以更改 UI 元素,然后继续播放库中的任何和所有音乐。

但是,发生的情况是它将播放专辑中的其余歌曲,然后当它耗尽该专辑中的所有歌曲时,将播放一首随机歌曲,然后一首随机歌曲将返回该专辑..完整遍历,然后播放随机歌曲。一旦进入蓝月亮,在它完成专辑后,它只会播放随机歌曲。

在单身人士中,我有

func getAllSongs(completion: @escaping (_ songs: [MPMediaItem]?) -> Void) {
MPMediaLibrary.requestAuthorization { (status) in
if status == .authorized {
let query = MPMediaQuery()
let mediaTypeMusic = MPMediaType.music
let audioFilter = MPMediaPropertyPredicate(value: mediaTypeMusic.rawValue, forProperty: MPMediaItemPropertyMediaType, comparisonType: MPMediaPredicateComparison.equalTo)
query.addFilterPredicate(audioFilter)
let songs = query.items
completion(songs)
} else {
completion(nil)
}
}
}

func getSongsWithCurrentAlbumFor(item: MPMediaItem) -> MPMediaQuery {
let albumFilter = MPMediaPropertyPredicate(value: item.albumTitle, forProperty: MPMediaItemPropertyAlbumTitle, comparisonType: MPMediaPredicateComparison.equalTo)
let predicates: Set<MPMediaPropertyPredicate> = [albumFilter]
let query = MPMediaQuery(filterPredicates: predicates)
query.addFilterPredicate(albumFilter)
return query
}

在我的VC中设置我使用的音频

let mediaPlayer = MPMusicPlayerApplicationController.applicationMusicPlayer

func setUpAudioPlayerAndGetSongsShuffled() {
try?     AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
MBProgressHUD.showAdded(to: view, animated: true)
MediaManager.shared.getAllSongs { (songs) in
guard let theSongs = songs else {
return
}
self.newSongs = theSongs.filter({ (item) -> Bool in
return !self.playedSongs.contains(item)
})
self.mediaPlayer.setQueue(with: MPMediaItemCollection(items: self.newSongs))
self.mediaPlayer.shuffleMode = .songs
self.mediaPlayer.repeatMode = .none
self.mediaPlayer.prepareToPlay(completionHandler: { (error) in
DispatchQueue.main.async {
MBProgressHUD.hide(for: self.view, animated: true)
}
})
}
}

当用户点击按钮以继续仅播放我使用的该专辑中的歌曲时

if let nowPlaying = mediaPlayer.nowPlayingItem {
let albumQuery = MediaManager.shared.getSongsWithCurrentAlbumFor(item: nowPlaying)
print("(albumQuery)")
let descriptor = MPMusicPlayerMediaItemQueueDescriptor(query: albumQuery)
mediaPlayer.prepend(descriptor)
}

重新阅读文档后,我注意到它说我应该更改为

let mediaPlayer = MPMusicPlayerApplicationController. applicationQueuePlayer 

我不知道如何知道专辑何时耗尽,然后继续播放音乐库的其余部分。

很高兴知道专辑是否没有任何其他项目,以便用户无法按下按钮播放专辑中的更多内容

我发现了我的错误。我把我的逻辑放在错误的地方

在我的单身人士中,我添加了

func hasPlayedAllSongsFromAlbumFor(song: MPMediaItem) -> Bool {
if let allSongsInAlbum = getSongsWithCurrentAlbumFor(item: song).items {
return lockedSongsContains(songs: allSongsInAlbum)
}
return true
}

func lockedSongsContains(songs: [MPMediaItem]) -> Bool {
for aSong in songs {
if !lockedSongs.contains(aSong) {
return false
}
}
return true
}

我需要使用通知

我创建了一个函数,它在ViewDidLoad中有一个通知,名为songChanged

在歌曲中我有改变的功能

if albumIsLocked && MediaManager.shared.hasPlayedAllSongsFromAlbumFor(song: nowPlaying) {
albumLockButtonTapped(albumLockIconButton)
MediaManager.shared.lockedSongs.removeAll()
}

在我现在使用的相册锁定按钮上

if let nowPlaying = mediaPlayer.nowPlayingItem {
if sender.isSelected {
sender.isSelected = false
albumIsLocked = false
let lockRemovedQuery = MediaManager.shared.removeAlbumLockFor(item: nowPlaying)
let lockRemovedDescriptor = MPMusicPlayerMediaItemQueueDescriptor(query: lockRemovedQuery)
mediaPlayer.prepend(lockRemovedDescriptor)
mediaPlayer.prepareToPlay()
} else {
sender.isSelected = true
albumIsLocked = true
let albumQuery = MediaManager.shared.getSongsWithCurrentAlbumFor(item: nowPlaying)
let albumDescriptor = MPMusicPlayerMediaItemQueueDescriptor(query: albumQuery)
mediaPlayer.prepend(albumDescriptor)
mediaPlayer.prepareToPlay()
}
}

最新更新