是否可以使用iPhone SDK中的HTTP实时流媒体读取元数据

mik*_*ker 10 iphone metadata objective-c audio-streaming

使用HTTP Live Streaming方法播放实时流时,是否可以读取当前元数据(例如标题和艺术家)?这是一个iPhone收音机应用程序.

m8l*_*abs 21

不确定这个问题对于作者来说是否仍然存在,但可能对某些人有帮助.经过两天的痛苦,我调查了它很简单.这是适合我的代码:

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];
Run Code Online (Sandbox Code Playgroud)

然后:

- (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);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

而已.我不知道为什么Apple没有在AVPlayerItem的文档中提供这个样本来访问流的"标题",这是现实世界流式音频的关键特性.在"AV基础框架参考"中,他们告诉"timedMetadata"无处需要.Matt的样本不适用于所有流(但AVPlayer会这样做).


Pab*_*uan 5

在 swift 2.0 中获取元数据信息音乐流:

PlayerItem.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)
Run Code Online (Sandbox Code Playgroud)

添加此方法:

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


}
Run Code Online (Sandbox Code Playgroud)


Mos*_*she 0

确实如此,但这并不容易。马特·加拉格尔 (Matt Gallagher)在他的博客上发表了一篇关于流音频的精彩文章。引用他关于这个问题的话:

最简单的元数据来源来自 HTTP 标头。在handleReadFromStream:eventType:方法中,使用CFReadStreamCopyProperty从CFReadStreamRef复制kCFStreamPropertyHTTPResponseHeader属性,然后您可以使用CFHTTPMessageCopyAllHeaderFields从响应中复制标头字段。对于许多流音频服务器,流名称是这些字段之一。

更难的元数据来源是 ID3 标签。ID3v1 始终位于文件末尾(因此在流式传输时无用)。ID3v2 位于开头,因此可能更容易访问。

我从未读过 ID3 标签,但我怀疑如果您在加载文件时将文件的前几百 KB 缓存在某处,请使用 AudioFileOpenWithCallbacks 打开该缓存,然后使用 AudioFileGetProperty 读取 kAudioFilePropertyID3Tag,您也许能够读取 ID3 数据(如果存在的话)。就像我说的:我从来没有真正这样做过,所以我不确定它是否会起作用。