如何从swift/AVKIT中的HLS流读取id3标记/其他元数据

如何从swift/AVKIT中的HLS流读取id3标记/其他元数据,swift,avplayer,http-live-streaming,id3,m3u8,Swift,Avplayer,Http Live Streaming,Id3,M3u8,我试图收集一些关于如何在iOS应用程序中从HLS流读取元数据的知识。 下面的HLS流有一些我想读取的ID3标记: 在Safari的web inspector中,我可以在控制台中看到许多数据对象,每个对象都有元数据: 在web inspector的“网络”选项卡中,我可以读取播放列表文件: #EXTM3U #EXT-X-VERSION:5 #EXT-X-MEDIA-SEQUENCE:89147 #EXT-X-TARGETDURATION:20 #EXT-X-PROGRAM-DATE-TIME:

我试图收集一些关于如何在iOS应用程序中从HLS流读取元数据的知识。 下面的HLS流有一些我想读取的ID3标记:

在Safari的web inspector中,我可以在控制台中看到许多数据对象,每个对象都有元数据:

在web inspector的“网络”选项卡中,我可以读取播放列表文件:

#EXTM3U
#EXT-X-VERSION:5
#EXT-X-MEDIA-SEQUENCE:89147
#EXT-X-TARGETDURATION:20
#EXT-X-PROGRAM-DATE-TIME:2019-09-25T11:35:23.401Z
#EXTINF:19.970,
05-20190925T113523Z.aac
#EXTINF:19.970,
05-20190925T113543Z.aac
#EXTINF:19.970,
05-20190925T113603Z.aac
#EXTINF:19.970,
05-20190925T113623Z.aac
#EXTINF:19.970,
05-20190925T113643Z.aac
#EXTINF:19.970,
05-20190925T113703Z.aac
到目前为止,我已经实现了一个类,它使用一个
AVPlayer
实例来播放这个流。它工作正常

我将
AVPlayer
AVPlayerItem
中的各种属性打印到Xcode控制台。 但是,我能解释的唯一属性是
AVPlayerItem.currentTime
,它给出了播放列表文件中
EXT-X-PROGRAM-DATE-TIME
的值。 所有其他属性似乎与我在播放列表和id3标签中看到的信息无关

有没有办法读取每个id3标记中包含的元数据? 如何从播放列表中读取
EXT-X-TARGETDURATION


我阅读了有关AVPlayerItemMetadataCollector的内容,但我不明白它应该做什么,以及这是否有助于我读取HLS流中的元数据

我就是这样做到的:

import UIKit
import AVKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController{

    let player = AVPlayer()
    var playerItem: AVPlayerItem!
    let asset = AVAsset(url: URL(string: "https://db2.indexcom.com/bucket/ram/00/05/05.m3u8")!)

    override func viewDidLoad() {
        prepareToPlay()
        player.play()
    }

    func prepareToPlay() {
        playerItem = AVPlayerItem(asset: asset)
        playerItem.addObserver(self, forKeyPath: "timedMetadata", options: [], context: nil)
        player.replaceCurrentItem(with: playerItem)
        printTimeStamp()
    }

    func printTimeStamp() {
        print("▼⎺▼⎺▼⎺▼⎺▼⎺▼⎺▼⎺▼")
        print("PROGRAM-DATE-TIME: ")
        print(playerItem.currentDate() ?? "No timeStamp")
        print("▲_▲_▲_▲_▲_▲_▲_▲\n\n")
    }

    override func observeValue(forKeyPath: String?, of: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if forKeyPath != "timedMetadata" { return }

        printTimeStamp()

        let data: AVPlayerItem = of as! AVPlayerItem

        guard let timedMetadata = data.timedMetadata else { return }

        for item in timedMetadata {
            switch item.commonKey {

            case .commonKeyAlbumName?:
                print("AlbumName: \(item.value!)")
            case .commonKeyArtist?:
                print("Artist: \(item.value!)")
            case .commonKeyArtwork?:
                print("Artwork: \(item.value!)")
            case .commonKeyAuthor?:
                print("Author: \(item.value!)")
            case .commonKeyContributor?:
                print("Contributor: \(item.value!)")
            case .commonKeyCopyrights?:
                print("Copyrights: \(item.value!)")
            case .commonKeyCreationDate?:
                print("CreationDate: \(item.value!)")
            case .commonKeyCreator?:
                print("creator: \(item.value!)")
            case .commonKeyDescription?:
                print("Description: \(item.value!)")
            case .commonKeyFormat?:
                print("Format: \(item.value!)")
            case .commonKeyIdentifier?:
                print("Identifier: \(item.value!)")
            case .commonKeyLanguage?:
                print("Language: \(item.value!)")
            case .commonKeyMake?:
                print("Make: \(item.value!)")
            case .commonKeyModel?:
                print("Model: \(item.value!)")
            case .commonKeyPublisher?:
                print("Publisher: \(item.value!)")
            case .commonKeyRelation?:
                print("Relation: \(item.value!)")
            case .commonKeySoftware?:
                print("Software: \(item.value!)")
            case .commonKeySubject?:
                print("Subject: \(item.value!)")
            case .commonKeyTitle?:
                print("Title: \(item.value!)")
            case .commonKeyType?:
                print("Type: \(item.value!)")

            case .id3MetadataKeyAlbumTitle?:
                print("id3MetadataKeyAlbumTitle: \(item.value!)")

            default:
                print("other data: \(item.value!)")
            }
        }
    }
}
我们就是这样做的:-欢迎您复制或使用我们的库:-)