如何在流媒体的苹果音乐中显示专辑封面?

5
在使用iOS 9的新Apple Music API(发布于2016年5月12日)来开发我的音乐播放器时,我可以显示流媒体歌曲的信息,但无法显示艺术作品。我正在使用MediaPlayer、UIKit和StoreKit框架。我已经成功请求授权以添加到云音乐库和音乐目录播放。我已经成功地显示了从苹果音乐应用程序下载的歌曲中的艺术作品,以及来自我的个人歌曲收藏的艺术作品。但我看到其他人也遇到了这个问题,但都没有解决...

在此之前,我想再问一次大家是否有帮助,否则我将不得不显示默认图像(这对错误处理是必要的),或从其他服务中获取。任何帮助都将是极好的!由于这不是代码中的错误,所以我不会展示它,除非需要帮助解决这个问题。

这是我第一次尝试发布代码...这里是在一个名为Authorization的swift文件中的代码。我是否需要在任何地方引用这段代码,还是它应该在AppDelegate文件中?这是我项目中唯一不确定的部分。

import StoreKit
import MediaPlayer
import UIKit

class AppleMusicPlayer: NSObject {

    let applePlayer = MPMusicPlayerController.systemMusicPlayer()

    func playID(productID: String) {
        SKCloudServiceController.requestAuthorization { status in
            let controller = SKCloudServiceController()
            controller.requestCapabilitiesWithCompletionHandler { capabilities, error in
                if capabilities != SKCloudServiceCapability.None {
                    MPMediaLibrary.defaultMediaLibrary().addItemWithProductID(productID) { entities, error in
                        self.appPlayer.setQueueWithStoreIDs([productID])
                        self.appPlayer.shuffleMode = .Songs
                        self.appPlayer.play()
                    }
                }
            }
        }
    }
}
5个回答

5

当前Apple Music API存在一个bug。正如您所提到的,用户库中没有但从AM流式传输的歌曲将不会返回专辑封面。

您应该在bugreport.apple.com上提交一个功能增强请求(您也可以复制我的请求编号25413082,该请求已有6个月的历史记录)。

与此同时,您最好使用iTunes API来检索专辑封面,但不幸的是,这种方法并不能100%准确地返回正确结果...


很好,我很高兴你找到了这个。那个问题确实让我卡了一段时间!我马上会在这里提交一个错误报告... - Jake Dobson
它每次都返回一张图片吗?它可能不正确吗?它有多少次是不正确的? - Jake Dobson
@JakeDobson 每次都会返回一张图片,但很难确定你是否从API中获取了正确的歌曲。如果你搜索艺术家、标题和专辑标题,例如(单曲、乐队名称听起来像另一个乐队的歌曲/专辑标题等),可能无法获取正确的歌曲。 - Jordi Bruin

1

我曾经为此苦苦挣扎。如果这真的是一个 bug,我不确定,但是你不能像你期望的那样将 UIImageView 设置为 nowPlayingItem。你必须从 Apple Music 服务 API 中获取图像。请参见文档 这里。另外,请查看苹果提供的示例项目 这里以获得全面的了解。此外, 这里 是我如何克服这个问题的完整示例。

func updateUserInterface() {
    if musicPlayerManager.musicPlayerController.playbackState == .playing { //Check if anything is playing
        if let currentItem = musicPlayerManager.musicPlayerController.nowPlayingItem {
            songAlbumLabel.text = currentItem.albumTitle
            songTitleLabel.text = currentItem.title
            songArtistNameLabel.text = currentItem.artist
            let albumTitle = currentItem.albumTitle  //Changes here!
            let artist = currentItem.artist  //Changes here!
            if let artwork = musicPlayerManager.musicPlayerController.nowPlayingItem?.artwork, let image = artwork.image(at: artworkImageView.frame.size) { // Check for local image
                print("using local image")
                artworkImageView.image = image 
        } else { 
            guard let developerToken = appleMusicManager.fetchDeveloperToken() else {print("oops");return}
            let searchTypes = "songs"
            var searchURLComponents = URLComponents()
            searchURLComponents.scheme = "https"
            searchURLComponents.host = "api.music.apple.com"
            searchURLComponents.path = "/v1/catalog/"
            searchURLComponents.path += "\(authorizationManager.cloudServiceStoreFrontCountryCode)"
            searchURLComponents.path += "/search"
            let expectedArtist = artist?.replacingOccurrences(of: " ", with: "+")  //Changes here!
            let artistExpected = expectedArtist?.replacingOccurrences(of: "&", with: "")  //Changes here!
            let expectingArtist = artistExpected?.replacingOccurrences(of: "++", with: "+")  //Changes here!
            let expectedAlbum = albumTitle?.replacingOccurrences(of: " ", with: "+")  //Changes here!
            searchURLComponents.queryItems = [
                    URLQueryItem(name: "term", value: (expectingArtist! + "-" + expectedAlbum!)),
                    URLQueryItem(name: "types", value: searchTypes)
                ]  //Changes here!
            var request = URLRequest(url: searchURLComponents.url!)
            request.httpMethod = "GET"
            request.addValue("Bearer \(developerToken)", forHTTPHeaderField: "Authorization")
            let dataTask = URLSession.shared.dataTask(with: request) {
                (data, response, error) in
                print(response!)
                if let searchData = data {
                    guard let results = try? self.appleMusicManager.processMediaItemSections(searchData) else { return}
                    self.mediaItem = results
                    let album = self.mediaItem[0][0]
                    let albumArtworkURL = album.artwork.imageUrl(self.artworkImageView.frame.size)
                    if let image = self.imageManager.cachedImage(url: albumArtworkURL) {
                        print("using cached image")
                        self.artworkImageView.image = image
                    }
                    else {
                        self.imageManager.fetchImage(url: albumArtworkURL) {(image) in
                            print("fetching image")
                            self.artworkImageView.image = image
                        }
                    }
                }
            }
            dataTask.resume()
        }
    } else { // Need to set it to some kind of default values
        artworkImageView.image = nil
        songArtistNameLabel.text = " "
        songTitleLabel.text = " "
        songAlbumLabel.text = " "
        }
    }
}

我已更新我的答案以反映Apple Music API的变化。你确定你的开发者令牌是有效的吗?你是否收到状态码200?如果没有,那就是问题所在。请参考我更新的Github示例。 - CarpenterBlood

0
我发现最好的方法是使用从 Apple Music API 的歌曲目录获取请求在此处记录

你只需要传入歌曲标识符(用于播放的标识符)和正在使用的商店标识符来播放该歌曲。这将始终产生准确的结果,相比使用可能失败的搜索请求答案。


0
在MediaItem类中有一个名为MPMediaItemPropertyArtwork的属性。您可以通过以下方式检索专辑的艺术品:
MPMediaItemArtwork *artwork = [mediaItem valueForProperty:MPMediaItemPropertyArtwork];
UIImage *albumImage = [itemArtwork imageWithSize:cgSizeYouWant];

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Jake Dobson
Apple Music Toolbox 不确定链接如何工作,但如果您或任何人不熟悉,可以使用该链接。 - Jake Dobson
抱歉,@Sean,我刚开始使用Stack Overflow!你能看一下我的代码和上面的注释吗? - Jake Dobson

0

使用SwiftUI,它变得超级简单 -

if let artwork = mediaItem.artwork {
     ArtworkImage(artwork, width: 85) // or whatever width you need. 
         .cornerRadius(10)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接