Files
audioserver/GrooveAudio (iOS)/Audio/StreamPlayer.swift
T

68 lines
1.8 KiB
Swift

import AVFoundation
import Combine
final class StreamPlayer: ObservableObject {
static let shared = StreamPlayer()
private var player: AVPlayer
private var cancellables = Set<AnyCancellable>()
@Published var isPlaying = false
@Published var connectionStatus: ConnectionStatus = .disconnected
enum ConnectionStatus {
case connected, disconnected, error(String)
}
private init() {
self.player = AVPlayer()
setupNotifications()
}
func playStream(host: String, password: String) {
guard let url = URL(string: "http://\(host):8000/stream.flac") else {
connectionStatus = .error("Invalid URL")
return
}
let credentials = "listener:\(password)"
let encoded = Data(credentials.utf8).base64EncodedString()
let headers: [String: String] = ["Authorization": "Basic \(encoded)"]
let asset = AVURLAsset(url: url, options: [
AVURLAssetHTTPHeaderFieldsKey: headers
])
let item = AVPlayerItem(asset: asset)
item.preferredForwardBufferDuration = 10
player.replaceCurrentItem(with: item)
player.play()
isPlaying = true
connectionStatus = .connected
}
func pause() {
player.pause()
isPlaying = false
}
func resume() {
player.play()
isPlaying = true
}
func reconnect(host: String, password: String) {
pause()
connectionStatus = .disconnected
playStream(host: host, password: password)
}
private func setupNotifications() {
NotificationCenter.default.publisher(for: .AVPlayerItemFailedToPlayToEndTime)
.sink { [weak self] _ in
self?.connectionStatus = .error("Stream failed")
}
.store(in: &cancellables)
}
}