2011-01-14 32 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 
        } 
       } 
      } 
     } 
    } 


} 
相关问题