媒体播放器过滤和预先添加专辑播放专辑,随机播放歌曲,然后再播放专辑

时间:2018-01-24 22:36:59

标签: ios swift

我正在尝试制作一个音乐播放器,目前我仍然坚持过滤并将相册添加到播放列表中。

我要做的是在随机播放音乐,然后当用户点击按钮继续播放当前正在播放的专辑中的歌曲时,当它完成时我想知道它完成了所以我可以更改UI元素然后继续播放图书馆的所有音乐。

然而,会发生什么呢?它会播放专辑中的其余歌曲THEN当它已经用尽时,该专辑中的所有歌曲将播放随机歌曲然后一首随机歌曲将返回该专辑..通过它的整体,然后播放随机歌曲。一旦在完成专辑后的蓝色月亮,它将只播放随机歌曲。

在单身人士中我有

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 

我无法弄清楚如何知道专辑何时用尽,然后继续播放音乐库的其余部分。

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

1 个答案:

答案 0 :(得分:2)

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

在我的单身中,我添加了

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

的通知的func

在歌曲变化中,我有

  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()
  }
}