繁体   English   中英

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

[英]is it possible to read metadata using HTTP live streaming in the iPhone SDK

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

不确定这个问题对其作者来说是否仍然是实际的,但可能会对某人有所帮助。 经过两天的痛苦,我调查了这很简单。 这是对我有用的代码:

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

就是这样。 我不知道为什么苹果没有在 AVPlayerItem 的文档中提供这个示例来访问流的“标题”,这是现实世界流音频的关键特性。 在“AV Foundation Framework Reference”中,他们在任何需要的地方都没有提到“timedMetadata”。 并且 Matt 的示例不适用于所有流(但 AVPlayer 可以)。

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


}

迅捷的解决方案。 这是一个简单的流式音频播放器示例。 您可以在委托 AVPlayerItemMetadataOutputPushDelegate 的方法中读取元数据。

import UIKit
import AVFoundation

class PlayerViewController: UIViewController {
    var player = AVPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        configurePlayer()
        player.play()
    }

    private func configurePlayer() {
        guard let url = URL(string: "Your stream URL") else { return }
        let asset = AVAsset(url: url)
        let playerItem = AVPlayerItem(asset: asset)
        let metadataOutput = AVPlayerItemMetadataOutput(identifiers: nil)
        metadataOutput.setDelegate(self, queue: DispatchQueue.main)
        playerItem.add(metadataOutput)
        player = AVPlayer(playerItem: playerItem)
    }
}

extension PlayerViewController: AVPlayerItemMetadataOutputPushDelegate {
    func metadataOutput(_ output: AVPlayerItemMetadataOutput, didOutputTimedMetadataGroups groups: [AVTimedMetadataGroup], from track: AVPlayerItemTrack?) {
        let item = groups.first?.items.first
        item?.value(forKeyPath: "value")
        print(item!.value(forKeyPath: "value")!)
    }
}

是的,但这并不容易。 Matt Gallagher 在他的博客上有一篇关于流式音频的好文章 在这个问题上引用他的话:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM