2015-05-14 23 views
5

Sto tentando di visualizzare attualmente la grafica dell'album per una traccia .MP3 memorizzata localmente in un ImageView. Qualcuno sa come recuperare questa grafica in Swift per realizzare questo?Visualizzazione grafica per file .MP3

Ho trovato questa soluzione (iOS AVFoundation: How do I fetch artwork from an mp3 file?) ma il codice è scritto nell'obiettivo C. Voglio semplicemente catturare l'immagine incorporata nel mio MP3 e visualizzarla nel mio ImageView.

Ho esaminato la documentazione API per MPMediaItemArtwork e ho trovato un esempio che realizza anche quello che sto cercando di realizzare anche in Objective C (http://www.codeitive.com/0zHjkUjUWX/not-able-to-get-the-uiimage-from-mpmediaitempropertyartwork.html) ma non riesco a trovare una soluzione. Il mio codice è il seguente:

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


} 

Ecco una schermata del mio esempio di file .mp3. Come puoi vedere, in effetti è visibile la copertina dell'album nella sezione "Ottieni informazioni" di Finder. Ho anche aperto la .mp3 nel mio iTunes per assicurarmi e ho confermato che ci sono delle illustrazioni nella sezione "Ottieni informazioni" e nella scheda "Grafica".

Tuttavia, quando si tenta di utilizzare commonKey per assegnare l'immagine al mio imageView, trovo che non esiste commonkey per "artwork".

sample MP3 data

Grazie

risposta

6

Cambia il tuo frammento di codice in questo (io già tes ted it):

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

Perfetto! Questa è stata la soluzione che ha funzionato per me! Grazie per l'aiuto. Quindi era corretto usare .metadata invece di .commonmetadata? È una copertura solo più approfondita dei metadati rispetto agli altri? Complimenti e saluti! – Unconquered82

3

Prova in questo modo:

let audioInfo = MPNowPlayingInfoCenter.defaultCenter() 
var nowPlayingInfo:[String:AnyObject] = [:] 
let playerItem = AVPlayerItem(URL: url) 
let metadataList = playerItem.asset.metadata 
for item in metadataList { 
    if item.commonKey != nil && item.value != nil { 
     if item.commonKey == "title" { 
      println(item.stringValue) 
      nowPlayingInfo[MPMediaItemPropertyTitle] = item.stringValue 
     } 
     if item.commonKey == "type" { 
      println(item.stringValue) 
      nowPlayingInfo[MPMediaItemPropertyGenre] = item.stringValue 
     } 
     if item.commonKey == "albumName" { 
      println(item.stringValue) 
      nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = item.stringValue 
     } 
     if item.commonKey == "artist" { 
      println(item.stringValue) 
      nowPlayingInfo[MPMediaItemPropertyArtist] = item.stringValue 
     } 
     if item.commonKey == "artwork" { 
      if let image = UIImage(data: item.dataValue) { 
       nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(image: image) 
       println(image.description) 
      } 
     } 
    } 
} 

audioInfo.nowPlayingInfo = nowPlayingInfo 

Nota: Si dovrà richiamare beginReceivingRemoteControlEvents() altrimenti non funzionerà sul dispositivo vero e proprio. Sarà inoltre necessario impostare le modalità di app in background (audio e AirPlay) e impostare la vostra categoria AVAudioSession per AVAudioSessionCategoryPlayback e impostarlo attiva:

do { 
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback) 
    print("AVAudioSession Category Playback OK") 
    do { 
     try AVAudioSession.sharedInstance().setActive(true) 
     print("AVAudioSession is Active") 
    } catch let error as NSError { 
     print(error.localizedDescription) 
    } 
} catch let error as NSError { 
    print(error.localizedDescription) 
} 

enter image description here

+0

ho provato il codice precedente precedente già, tuttavia non v'è commonKey per "artwork" elencati modo l'immagine deve essere memorizzando altrove nel file. Quando ho println miei oggetti commonKey tutto ciò che mostra è [titolo tipo copyright albumName artista] Se "Ottieni informazioni" sul file posso vedere chiaramente opere d'arte per l'mp3 sia nella sezione Anteprima, nonché opere d'arte sotto la scheda "opere d'arte" in iTunes. Tuttavia, non esiste una commonkey "grafica" che può essere utilizzata per catturare questo. – Unconquered82

+0

Sta estraendo le informazioni dal file, probabilmente la tua canzone non ha alcuna grafica. Assicurati che il tuo file MP3 abbia un disegno incorporato –

+0

Ho aggiornato la mia domanda per includere una schermata delle informazioni dei brani.Come puoi vedere, c'è un'opera d'arte incorporata in .mp3. Non ho scattato una seconda schermata della scheda "Grafica" in iTunes, ma anche l'opera d'arte appare lì. – Unconquered82

0

Prova questa:

Sembra che a volte iOS 8 restituisce zero al primo tentativo di ottenere queste informazioni:

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