HLS 元数据 ID3 标签不起作用
HLS Metadata ID3 tag not working
我在 TableView 中有一个音频 URL 列表,所以每次我点击 didSelectRowAt
上的每个单元格时都会调用此方法
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Prepare Audio URL
let audioUrl = URL(string: (channelSelected.audioUrl?.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed))!)
let playerItem = AVPlayerItem(url: audioUrl!)
playerItem.addObserver(self, forKeyPath: "timedMetadata", options: .new, context: nil)
player = AVPlayer(playerItem: playerItem)
playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController, animated: true, completion: {
self.playerViewController.player?.play()
})
}
并且根据教程,我实现了观察值侦听器
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("keypath = \(keyPath!)")
let avPlayerItem: AVPlayerItem = object as! AVPlayerItem
if let timedMetadata = avPlayerItem.timedMetadata {
print("Timed metadata = \(timedMetadata)")
} else {
print("Timed metadata nil")
}
}
问题是 timedMetadata
总是 nil。帮助将不胜感激。
您的代码运行正常,出现此问题的原因是服务器端的问题。
您可以使用此工具mp3tag编辑音频文件 - 添加元数据标签并将其上传到服务器。
例如,您可以试试这些包含元数据标签的音频:
http://ice1.somafm.com/groovesalad-128-mp3
https://developer.jwplayer.com/jw-player/demos/basic/audio-metadata/assets/index.m3u8
确认一下,以上文件应该可以与您的代码一起正常工作。
这是另一种选择,因为我发现服务器没有使用 "timed metadata"。对于那些还没有找到答案的人,这是我们最终实施的方式。后端正在使用 Wowza 服务器。
let playerItem = AVPlayerItem(url: audioUrl!)
let adID = AVMetadataItem.identifier(forKey: "X-TITLE", keySpace: .hlsDateRange)
let metadataCollector = AVPlayerItemMetadataCollector(identifiers: [adID!.rawValue], classifyingLabels: nil)
metadataCollector.setDelegate(self, queue: DispatchQueue.main)
playerItem.add(metadataCollector)
然后声明 AVPlayerItemMetadataCollectorPushDelegate
的扩展
func metadataCollector(_ metadataCollector: AVPlayerItemMetadataCollector, didCollect metadataGroups: [AVDateRangeMetadataGroup], indexesOfNewGroups: IndexSet, indexesOfModifiedGroups: IndexSet) {
for metadataGroup in metadataGroups {
for metadata in metadataGroup.items {
}
}
}
我在 TableView 中有一个音频 URL 列表,所以每次我点击 didSelectRowAt
上的每个单元格时都会调用此方法
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Prepare Audio URL
let audioUrl = URL(string: (channelSelected.audioUrl?.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed))!)
let playerItem = AVPlayerItem(url: audioUrl!)
playerItem.addObserver(self, forKeyPath: "timedMetadata", options: .new, context: nil)
player = AVPlayer(playerItem: playerItem)
playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController, animated: true, completion: {
self.playerViewController.player?.play()
})
}
并且根据教程,我实现了观察值侦听器
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("keypath = \(keyPath!)")
let avPlayerItem: AVPlayerItem = object as! AVPlayerItem
if let timedMetadata = avPlayerItem.timedMetadata {
print("Timed metadata = \(timedMetadata)")
} else {
print("Timed metadata nil")
}
}
问题是 timedMetadata
总是 nil。帮助将不胜感激。
您的代码运行正常,出现此问题的原因是服务器端的问题。
您可以使用此工具mp3tag编辑音频文件 - 添加元数据标签并将其上传到服务器。
例如,您可以试试这些包含元数据标签的音频:
http://ice1.somafm.com/groovesalad-128-mp3
https://developer.jwplayer.com/jw-player/demos/basic/audio-metadata/assets/index.m3u8
确认一下,以上文件应该可以与您的代码一起正常工作。
这是另一种选择,因为我发现服务器没有使用 "timed metadata"。对于那些还没有找到答案的人,这是我们最终实施的方式。后端正在使用 Wowza 服务器。
let playerItem = AVPlayerItem(url: audioUrl!)
let adID = AVMetadataItem.identifier(forKey: "X-TITLE", keySpace: .hlsDateRange)
let metadataCollector = AVPlayerItemMetadataCollector(identifiers: [adID!.rawValue], classifyingLabels: nil)
metadataCollector.setDelegate(self, queue: DispatchQueue.main)
playerItem.add(metadataCollector)
然后声明 AVPlayerItemMetadataCollectorPushDelegate
func metadataCollector(_ metadataCollector: AVPlayerItemMetadataCollector, didCollect metadataGroups: [AVDateRangeMetadataGroup], indexesOfNewGroups: IndexSet, indexesOfModifiedGroups: IndexSet) {
for metadataGroup in metadataGroups {
for metadata in metadataGroup.items {
}
}
}