无法将类型 'PlayParameters?' 的值转换为预期的参数类型“[MPMusicPlayerPlayParameters]”

Cannot convert value of type 'PlayParameters?' to expected argument type '[MPMusicPlayerPlayParameters]'

我正在尝试使用 Swift 和 MusicKit 创建音乐播放器,但在尝试使用 MusicKit 中的所选专辑加载队列时出现此错误。我不明白为什么专辑的播放参数和 MPMusicPlayerPlayParametersQueueDescriptor 不同。

let player = MPMusicPlayerController.applicationMusicPlayer
let queue  = MPMusicPlayerPlayParametersQueueDescriptor(playParametersQueue: heavyRotation[album].playParameters)
player.prepareToPlay()
player.play()

let queue 行出错:

无法将类型 'PlayParameters?' 的值转换为预期的参数类型“[MPMusicPlayerPlayParameters]”

新编辑

        var requestURLComponents = URLComponents()
        requestURLComponents.scheme = "https"
        requestURLComponents.host = "api.music.apple.com"
        requestURLComponents.path = "/v1/me/history/heavy-rotation"
        
        requestURLComponents.queryItems = [
            URLQueryItem(name: "limit", value: "5")
        ]
        
        guard let url = requestURLComponents.url else { return }
        
        let request = MusicDataRequest(urlRequest: URLRequest(url: url))
        do {
            let response = try await request.response()
            let decodedResponse = try JSONDecoder().decode(MusicItemCollection<Album>.self, from: response.data)
            heavyRotation = decodedResponse
//            print(response.debugDescription)
        } catch {
            print("error")
            print(error)
            print(error.localizedDescription)
        }

...

Button(action: {
    Task {
        guard let album = heavyRotation[album] as Album? else { return }
        print(album)
        let player = ApplicationMusicPlayer.shared
        player.queue = [album]
        try await player.prepareToPlay()
        try await player.play()
    }
}) {
    Image(systemName: "play.fill")
        .frame(width: 50, height: 50, alignment: .center)
        .fontSize(30)
        .foregroundColor(.white)
}

虽然 MusicKit 的 PlayParameters 是一个结构和一个不透明的对象,但 MPMusicPlayerPlayParameters 初始化程序需要一个 [String: Any] 字典。您必须将 PlayParameters 编码和解码为 MPMusicPlayerParameters.

这是你的例子:

guard let parameters = heavyRotation[album].playParameters else { return }

let data = try JSONEncoder().encode(parameters)
let playParameters = try JSONDecoder().decode(MPMusicPlayerPlayParameters.self, from: data)

let queue = MPMusicPlayerPlayParametersQueueDescriptor(playParametersQueue: [playParameters])

let player = MPMusicPlayerController.applicationMusicPlayer
player.setQueue(with: queue)
player.prepareToPlay()
player.play()

如果您使用 Swift 的 MusicKit 及其音乐播放器,您可以像这样直接将专辑设置到队列中:

guard let album = heavyRotation[album] else { return }

let player = ApplicationMusicPlayer.shared
player.queue = [album]
try await player.prepareToPlay()
try await player.play()

更新 - 如果您尝试播放库中的专辑,那么我也遇到了问题。作为解决方法,您可以获取相册的 local ID,然后再向目录发出另一个请求。如果 Apple Music 上有专辑,那应该可以。

这是一个适合我的示例:

do {
  /// First request to get the heavy rotation albums
  guard let url = URL(string: "https://api.music.apple.com/v1/me/history/heavy-rotation") else { return }
  
  let request = MusicDataRequest(urlRequest: URLRequest(url: url))
  let response = try await request.response()
  
  let heavyRotationAlbums = try JSONDecoder().decode(MusicItemCollection<Album>.self, from: response.data)
  
  /// Get the first album
  guard let album = heavyRotationAlbums.first else { return }
  
  /// Get the local album ID
  let albumID = album.id

  /// Another request to get the album from Apple Music Catalog
  guard let catalogURL = URL(string: "https://api.music.apple.com/v1/me/library/albums/\(albumID)/catalog") else { return }

  let catalogRequest = MusicDataRequest(urlRequest: URLRequest(url: catalogURL))
  let catalogResponse = try await catalogRequest.response()

  let albums = try JSONDecoder().decode(MusicItemCollection<Album>.self, from: catalogResponse.data)

  /// Get the same album, but with the catalog ID
  guard let catalogAlbum = albums.first else { return }

  /// Encode the parameters 
  let data = try JSONEncoder().encode(catalogAlbum.playParameters)

  /// Decode the parameters to `MPMusicPlayerPlayParameters`
  let playParameters = try JSONDecoder().decode(MPMusicPlayerPlayParameters.self, from: data)
  
  // Create the queue
  let queue = MPMusicPlayerPlayParametersQueueDescriptor(playParametersQueue: [playParameters])
  
  let player = MPMusicPlayerController.applicationMusicPlayer

  /// Set the queue
  player.setQueue(with: queue)
  try await player.prepareToPlay()

  /// Finally, play the album!
  player.play()
} catch {
  print(error)
}