使用 SwiftUI 获取 AVPlayerItem 曲目标题

Get AVPlayerItem track title with SwiftUI

我正在尝试创建一个广播应用程序,它从 http 流式传输音频。

我正在尝试从流式传输中获取当前正在播放的曲目标题,但我只能找到已弃用的方法。

我的模型是这样的:

struct RadioStreamer {
    let streamingURL: URL

    private let player: AVPlayer?
    private let playerItem: AVPlayerItem?

    init(streamingURL: URL) {
        self.streamingURL = streamingURL

        self.playerItem = AVPlayerItem(url: self.streamingURL)
        self.player = AVPlayer(playerItem: self.playerItem)

    }

    public func playStreaming() { self.player?.play() }
}

我的 contentView 看起来像这样:

let streamer = RadioStreamer(streamingURL: URL(string: "MY-STREAMING-URL")!)

var body: some View {
    VStack {
        Text("HERE I WANT THE TRACK TITLE")

        Button(action: {
            self.streamer.playStreaming()
        }) {
            Text("Play")
        }
    }
}

如何使用 SwiftUI 中的 non-deprecated 方法获取曲目标题?

谢谢!

这是引用类型更可取的情况。所以这里是可能方法的简化演示

import AVKit
import Combine

class RadioStreamer: NSObject, ObservableObject {
    @Published var itemTitle: String = "Unknown"

    let streamingURL: URL

    private let player: AVPlayer?
    private let playerItem: AVPlayerItem?

    init(streamingURL: URL) {
        self.streamingURL = streamingURL
        self.playerItem = AVPlayerItem(url: self.streamingURL)
        self.player = AVPlayer(playerItem: self.playerItem)

        super.init()

        // setup output for player item metadata
        let metaOutput = AVPlayerItemMetadataOutput(identifiers: [ // nil, for all
            // specify needed meta to be output, 
            AVMetadataIdentifier.commonIdentifierTitle.rawValue     
        ])
        metaOutput.setDelegate(self, queue: DispatchQueue.main)
        self.playerItem?.add(metaOutput)
    }

    public func playStreaming() { self.player?.play() }
}

extension RadioStreamer: AVPlayerItemMetadataOutputPushDelegate {
    func metadataOutput(_ output: AVPlayerItemMetadataOutput, didOutputTimedMetadataGroups groups: [AVTimedMetadataGroup], from track: AVPlayerItemTrack?) {

        // simplest demo, in common case iterate all groups and all items in group
        // to find what you need if you requested many metadata
        if let group = groups.first,
            let item = group.items.first {
            self.itemTitle = item.stringValue ?? "Unknown"
        }
    }
}