Can't set MPMusicPlayerController queue with MPMusicPlayerMediaItemQueueDescriptor

前端 未结 3 1821
遇见更好的自我
遇见更好的自我 2021-01-28 06:12

This code results in silence:

let query = MPMediaQuery.songs()
let result = query.items
guard let items = result, items.count > 0 else {return}
let song = ite         


        
3条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-28 06:44

    Swift 5

    I am a little late to the show, but this is what I came up with. (I was trimming songs for playback with descriptors).

    Make sure that you run every thing with Music Player on the Main Thread. If not you will run into weird bugs.

    Getting a song by persistentId:

    /// Retrieves a song in the MPMediaItem format using the persistentId passed.
    /// - Parameter persistentID: (UInt64) The songs persistentId.
    /// - Returns: (MPMediaItem?) Nil if not found other wise the MPMediaItem (song).
    private static func getSong(forId persistentID: UInt64) -> MPMediaItem? {
        let query = MPMediaQuery.songs()
        let predicate = MPMediaPropertyPredicate(value: persistentID, forProperty: MPMediaItemPropertyPersistentID)
        query.addFilterPredicate(predicate)
        return query.items?.first
    }
    

    Playing a song by persistentId:

    private var startTime: Double = 0
    private var endTime: Double = 0
    
    
    /// Plays the song with the identifier.
    /// - Note: Trims song to start and end time.
    /// - Parameter persistentId: (UInt64) The song persistent identifier.
    private func play(forId persistentId: UInt64) {
        DispatchQueue.main.async {
            if let song = Self.getSong(forId: persistentId) {
                let identifier = MPMediaItemPropertyPersistentID
                let predicate = MPMediaPropertyPredicate(value: persistentId, forProperty: identifier)
                let query = MPMediaQuery(filterPredicates: [predicate])
                let descriptor = MPMusicPlayerMediaItemQueueDescriptor(query: query)
                descriptor.setStartTime(self.startTime, for: song)
                descriptor.setEndTime(self.endTime, for: song)
                self.musicPlayer.setQueue(with: descriptor)
                self.musicPlayer.prepareToPlay()
                self.musicPlayer.repeatMode = .none
                self.musicPlayer.play()
            }
        }
    }
    

    Also I found that the way I initialize my music controller is important:

    private lazy var musicPlayer: MPMusicPlayerController = { MPMusicPlayerController.applicationQueuePlayer }()
    

    Please note: Some of the code isn't drag and drop. You would need to define things like start and end time variables.

提交回复
热议问题