【问题标题】:Get AVPlayerItem track title with SwiftUI使用 SwiftUI 获取 AVPlayerItem 曲目标题
【发布时间】:2020-08-05 20:25:14
【问题描述】:

我正在尝试创建一个广播应用程序,它通过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 中未弃用的方法获取曲目标题?

谢谢!

【问题讨论】:

    标签: ios swift iphone swiftui avplayer


    【解决方案1】:

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

    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"
            }
        }
    }
    

    【讨论】:

    • 谢谢。我似乎已经做到了这一点,委托函数metadataOutput 似乎从来没有被我调用过。我在我的标识符中传递 nil 来捕获任何东西。然后我想也许该流没有任何元数据,但是尽管更改为其他一些流,但仍然没有调用此函数。这些也有可能没有任何元数据,但我认为这 5 个中至少有 1 个会有一些元数据。知道可能出了什么问题,或者可能共享一个包含元数据的 url 吗?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多