Получите название дорожки AVPlayerItem с SwiftUI - PullRequest
1 голос
/ 22 апреля 2020

Я пытаюсь создать радио-приложение, которое передает аудио из потоковой передачи 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?

Спасибо!

1 Ответ

1 голос
/ 22 апреля 2020

Это тот случай, когда ссылочный тип является более предпочтительным. Итак, вот упрощенная демонстрация возможного подхода

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