2011-01-14 39 views

回答

0

這是,但並不容易。 Matt Gallagher有關於流音頻的nice post on his blog。引用他的話題:

最簡單的元數據來源是來自HTTP標頭的 。裏面的 handleReadFromStream:事件類型: 方法,使用CFReadStreamCopyProperty 到 kCFStreamPropertyHTTPResponseHeader 酒店需要從CFReadStreamRef複製, 那麼你可以使用 CFHTTPMessageCopyAllHeaderFields到 複製頭字段出 響應。對於許多流式音頻服務器,流名稱是 這些字段之一。

元數據的相當困難的來源是ID3標籤。 ID3v1總是在 的文件末尾(因此在流式傳輸時 無用)。 ID3v2的位置是 ,因此可能更容易訪問 。

我從來沒有讀過ID3標籤,但我 懷疑,如果緩存第一 幾百千字節的文件 的地方它加載的,打開緩存 與AudioFileOpenWithCallbacks和 然後讀取kAudioFilePropertyID3Tag 與AudioFileGetProperty您可能是 能夠讀取ID3數據(如果它存在 )。就像我說的那樣:我已經 從來沒有這樣做過,所以我不知道 肯定會起作用。

+0

如果你得到這個工作,讓我知道。 – Moshe 2011-01-14 13:17:32

+0

是的,在iTunes中,當.m3u文件正在流式傳輸時,歌曲和藝術家信息會自動更新。也許ID3v2會在每首歌曲的開始處流傳 - 就像你說的那樣。所以也許這只是一個事件監聽器等待元數據的問題 - 我會繼續尋找。 – miketucker 2011-01-16 10:46:14

20

不確定這個問題對於作者來說還是實際的,但可能會對某人有幫助。經過兩天的痛苦,我調查了這很簡單。下面是對我的作品的代碼:

AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:<here your http stream url>]]; 

[playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:nil]; 

AVPlayer* player = [[AVPlayer playerWithPlayerItem:playerItem] retain]; 
[player play]; 

然後:

- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object 
         change:(NSDictionary*)change context:(void*)context { 

    if ([keyPath isEqualToString:@"timedMetadata"]) 
    { 
     AVPlayerItem* playerItem = object; 

     for (AVMetadataItem* metadata in playerItem.timedMetadata) 
     { 
     NSLog(@"\nkey: %@\nkeySpace: %@\ncommonKey: %@\nvalue: %@", [metadata.key description], metadata.keySpace, metadata.commonKey, metadata.stringValue); 
     } 
    } 
} 

就是這樣。我不知道爲什麼Apple沒有在AVPlayerItem的文檔中提供這個樣本來訪問流的「標題」,這是真實世界流式音頻的關鍵特性。在「AV基礎架構參考」中,他們在需要的地方無處告訴「timedMetadata」。而馬特的樣本不適用於所有流(但AVPlayer)。

3

在迅速獲得2.0元數據信息音樂流:

PlayerItem.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil) 

添加這個方法:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 

    //Atualiza Nome Musica 
    if keyPath == "timedMetadata" { 
     if let meta = PlayerItem.timedMetadata { 
      print("Novo Metadata \(meta)") 
      for metadata in meta { 
       if let nomemusica = metadata.valueForKey("value") as? String{ 
        LB_NomeMusica.text = nomemusica 
        if NSClassFromString("MPNowPlayingInfoCenter") != nil { 
         let image:UIImage = UIImage(named: "logo.gif")! 
         let albumArt = MPMediaItemArtwork(image: image) 
         var songInfo: [String:AnyObject] = [ 
          MPMediaItemPropertyTitle: nomemusica, 
          MPMediaItemPropertyArtist: "Ao Vivo", 
          MPMediaItemPropertyArtwork: albumArt 
         ] 
         MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = songInfo 
        } 
       } 
      } 
     } 
    } 


} 
相關問題