【问题标题】:Media Player filtering and prepending album plays album, a random song, and then the album again媒体播放器过滤和前置专辑播放专辑,随机歌曲,然后再次播放专辑
【发布时间】:2018-01-24 22:36:59
【问题描述】:

我正在尝试制作一个音乐播放器,目前我一直在过滤并将专辑添加到播放列表中。

我想要做的是随机播放音乐,然后当用户点击一个按钮时,仅从当前播放的专辑中继续播放歌曲,当它完成时我想知道它已经完成,所以我可以更改 UI 元素,然后继续播放库中的所有音乐。

但是,它会播放专辑中的其余歌曲 THEN 当它用尽该专辑中的所有歌曲时将播放一首随机歌曲,然后一首随机歌曲将返回该专辑..go通过它的整体,然后播放随机歌曲。一旦完成专辑后,它会随机播放歌曲。

我是单身

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 

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

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

【问题讨论】:

    标签: ios swift


    【解决方案1】:

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

    在我的单身中我添加了

    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 的​​通知

    在我有的 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()
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多