how to read id3 tags / other metadata from an HLS stream in swift / AVKIT
This is how I achieved it:
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!)")
}
}
}
}
AVKit and ID3 metadata keys
There are two versions of tags: ID3 2.2's 3 byte tags, and 2.3+'s 4 byte tags. The constants declared in AVMetadataKey are the 4 byte tags.
If you're seeing the 3 byte tags as the key, then it must be a file tagged with the 21-year-old v2.2 tags and AVAsset is giving them to you as-is, so you'll just need to do the conversion yourself. There aren't that many tags, so you can easily make a conversion list yourself.
Using AAC with ID3 tags with AVPlayer
Every frame in an aac file starts with an ADTS header that contains its sample rate. And every frame is exactly 1024 samples. Hence every frame is sample_rate/1024 seconds long with the first frames starting at zero. From this, you can walk the file, and calculate every frames timestamp.
Related Topics
Swiftui Button Interact with Map
How to Set an Initial Value for @Nsmanaged Property Pfobject Subclass
Are Swift Constants Lazy by Default
Can a Condition Be Used to Determine the Type of a Generic
Add a Xib File to a Swift Package
Cannot Load Module Coredata as Coredata
Difference Between Optional Values in Swift
Spritekit: Howto Make Holes in Layer with Blendmode
How to Implement a 'Next' Property to a Caseiterable Enum in Swift
How to Edit Swift Error Breakpoint
Swift Tdd & Async Urlsession - How to Test
Swift: No Idea How to Get Back the Selected Value from a Popover to the Calling Controller
Swift Protocol as Generic Parameter
Tvos Remote Notification Replacement
Calling Stop() on Avaudioplayernode After Finished Playing Causes Crash
Gcdasyncsocket Multiple Connections Wont Accept Data from Multiple Sockets
Class with Non-Optional Property Conforming to Protocol with Optional Property