显示 .MP3 文件的作品

Displaying Artwork for .MP3 file

我正在尝试在 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 的 "get info" 部分中确实可以看到专辑插图。我还在我的 iTunes 中打开了 .mp3 以确保并确认在 "get info" 部分以及 "artwork" 选项卡下有艺术作品。

但是,当尝试使用 commonKey 将图像分配给我的 imageView 时,我发现 "artwork" 没有 commonKey。

谢谢

edit/update 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)
}

试试这个:

似乎有时 iOS 8 returns 第一次尝试获取此信息时为零:

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")
                }
            }
        }
    }

将你的代码片段改成这个(我已经测试过了):

I added println lines commented in places of interest, Feel free to uncomment in order to see what is happening.

   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
                }
            }
        }
    }

UPDATE: A bit of clean up of this code

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
   }
}

UPDATE: For 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
   }
}