我正在尝试在ImageView中显示本地存储的.MP3曲目的专辑封面。有谁知道如何在Swift中获取这件艺术品才能实现这一目标?
我找到了这个解决方案(iOS AVFoundation: How do I fetch artwork from an mp3 file?),但是代码是用Objective C编写的。我只是想抓住嵌入在MP3中的图像并将其显示在我的ImageView中。
我已经查看了MPMediaItemArtwork的API文档,并找到了一个示例,它也完成了我在Objective C中尝试完成的任务(http://www.codeitive.com/0zHjkUjUWX/not-able-to-get-the-uiimage-from-mpmediaitempropertyartwork.html),但无法提出解决方案。我的代码如下:
import UIKit
import AVFoundation
import MediaPlayer
class ViewController: UIViewController {
let audioPath:NSURL! = NSBundle.mainBundle().URLForResource("SippinOnFire", withExtension: "mp3")
@IBOutlet var artistImage: UIImageView!
@IBOutlet var trackLabel: UILabel!
@IBOutlet var artistLabel: UILabel!
@IBOutlet var sliderValue: UISlider!
var player:AVAudioPlayer = AVAudioPlayer()
@IBAction func play(sender: AnyObject) {
let audioInfo = MPNowPlayingInfoCenter.defaultCenter()
println(audioInfo)
player.play()
//println("Playing \(audioPath)")
let playerItem = AVPlayerItem(URL: audioPath)
let metadataList = playerItem.asset.metadata as! [AVMetadataItem]
for item in metadataList {
if let stringValue = item.value {
println(item.commonKey)
if item.commonKey == "title" {
trackLabel.text = stringValue as? String
}
if item.commonKey == "artist" {
artistLabel.text = stringValue as? String
}
if item.commonKey == "artwork" {
if let audioImage = UIImage(data: item.value as! NSData) {
let audioArtwork = MPMediaItemArtwork(image: audioImage)
println(audioImage.description)
}
}
}
}
}
@IBAction func pause(sender: AnyObject) {
player.pause()
}
@IBAction func stop(sender: AnyObject) {
player.stop()
player.currentTime = 0;
}
@IBAction func sliderChanged(sender: AnyObject) {
player.volume = sliderValue.value
}
override func viewDidLoad() {
super.viewDidLoad()
var error:NSError? = nil
player = AVAudioPlayer(contentsOfURL: audioPath!, error: &error)
player.volume = 0.5;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
以下是我的示例.mp3文件的屏幕截图。正如您所看到的,确实有专辑图片在Finder的“获取信息”部分中都可见。我还在我的iTunes中打开了.mp3,以确保并确认其中的“获取信息”部分以及“艺术品”标签下都有艺术作品。
但是,当尝试使用commonKey将图像分配给我的imageView时,我发现“艺术品”没有commonKey。
由于
答案 0 :(得分:8)
将您的代码片段更改为此内容(我已对其进行了测试):
我添加了在感兴趣的地方评论的println行,请随意取消注释以查看正在发生的事情。
for item in metadataList {
if item.commonKey == nil{
continue
}
if let key = item.commonKey, let value = item.value {
//println(key)
//println(value)
if key == "title" {
trackLabel.text = value as? String
}
if key == "artist" {
artistLabel.text = value as? String
}
if key == "artwork" {
if let audioImage = UIImage(data: value as! NSData) {
//println(audioImage.description)
artistImage.image = audioImage
}
}
}
}
更新:稍微清理一下这段代码
for item in metadataList {
guard let key = item.commonKey, let value = item.value else{
continue
}
switch key {
case "title" : trackLabel.text = value as? String
case "artist": artistLabel.text = value as? String
case "artwork" where value is NSData : artistImage.image = UIImage(data: value as! NSData)
default:
continue
}
}
更新:适用于Swift 4
for item in metadataList {
guard let key = item.commonKey?.rawValue, let value = item.value else{
continue
}
switch key {
case "title" : trackLabel.text = value as? String
case "artist": artistLabel.text = value as? String
case "artwork" where value is Data : artistImage.image = UIImage(data: value as! Data)
default:
continue
}
}
答案 1 :(得分:3)
编辑/更新 Swift 4或更高版本:
import MediaPlayer
var nowPlayingInfo: [String: Any] = [:]
let playerItem = AVPlayerItem(url: url)
let metadataList = playerItem.asset.metadata
for item in metadataList {
switch item.commonKey {
case .commonKeyTitle?:
nowPlayingInfo[MPMediaItemPropertyTitle] = item.stringValue ?? ""
case .commonKeyType?:
nowPlayingInfo[MPMediaItemPropertyGenre] = item.stringValue ?? ""
case .commonKeyAlbumName?:
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = item.stringValue ?? ""
case .commonKeyArtist?:
nowPlayingInfo[MPMediaItemPropertyArtist] = item.stringValue ?? ""
case .commonKeyArtwork?:
if let data = item.dataValue,
let image = UIImage(data: data) {
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
}
case .none: break
default: break
}
}
let audioInfo = MPNowPlayingInfoCenter.default()
audioInfo.nowPlayingInfo = nowPlayingInfo
注意:您必须调用beginReceivingRemoteControlEvents(),否则它将无法在实际设备上运行。您还需要设置应用程序背景模式(音频和AirPlay)并将AVAudioSession类别设置为AVAudioSessionCategoryPlayback并将其设置为活动状态:
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay])
print("Playback OK")
try AVAudioSession.sharedInstance().setActive(true)
print("Session is Active")
} catch {
print(error)
}
答案 2 :(得分:0)
试试这个:
看来有时iOS 8在首次尝试获取此信息时返回nil:
if let audioCenter = MPNowPlayingInfoCenter.defaultCenter(){
if let audioInfo = audioCenter.nowPlayingInfo{
if let artwork = audioInfo[MPMediaItemPropertyArtwork] as? MPMediaItemArtwork
{
var image: UIImage? = artwork.imageWithSize(artwork.bounds.size)
if image == nil {
image = artwork.imageWithSize(artwork.bounds.size);
}
if image != nil{
println("image loaded")
}
}
}
}