From 5f4a3c8a0aeb592a7ba991d15ec0f12d95726dc7 Mon Sep 17 00:00:00 2001 From: Kenneth Date: Sun, 28 Jul 2024 15:12:10 +0100 Subject: [PATCH] feat: add playback loading state --- .../xcschemes/InfinifiIOS.xcscheme | 78 +++++++++++++++++++ .../xcschemes/xcschememanagement.plist | 14 ---- InfinifiIOS/ContentView.swift | 3 + InfinifiIOS/PlaybackManager.swift | 39 +++++++--- 4 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 InfinifiIOS.xcodeproj/xcshareddata/xcschemes/InfinifiIOS.xcscheme delete mode 100644 InfinifiIOS.xcodeproj/xcuserdata/kennethng.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/InfinifiIOS.xcodeproj/xcshareddata/xcschemes/InfinifiIOS.xcscheme b/InfinifiIOS.xcodeproj/xcshareddata/xcschemes/InfinifiIOS.xcscheme new file mode 100644 index 0000000..098968e --- /dev/null +++ b/InfinifiIOS.xcodeproj/xcshareddata/xcschemes/InfinifiIOS.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/InfinifiIOS.xcodeproj/xcuserdata/kennethng.xcuserdatad/xcschemes/xcschememanagement.plist b/InfinifiIOS.xcodeproj/xcuserdata/kennethng.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 4b77bca..0000000 --- a/InfinifiIOS.xcodeproj/xcuserdata/kennethng.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - SchemeUserState - - InfinifiIOS.xcscheme_^#shared#^_ - - orderHint - 0 - - - - diff --git a/InfinifiIOS/ContentView.swift b/InfinifiIOS/ContentView.swift index df85abd..d887f64 100644 --- a/InfinifiIOS/ContentView.swift +++ b/InfinifiIOS/ContentView.swift @@ -10,6 +10,8 @@ struct ContentView: View { playbackManager.stop() case .paused: playbackManager.nextTrack() + default: + break } } @@ -17,6 +19,7 @@ struct ContentView: View { let buttonImageName = switch playbackManager.playbackState { case .paused: "play" case .playing: "pause" + case .loading: "dot.square" } VStack(alignment: .center) { diff --git a/InfinifiIOS/PlaybackManager.swift b/InfinifiIOS/PlaybackManager.swift index aa7a7d8..4b56ef4 100644 --- a/InfinifiIOS/PlaybackManager.swift +++ b/InfinifiIOS/PlaybackManager.swift @@ -4,8 +4,10 @@ import Foundation enum PlaybackState { case playing case paused + case loading } +@MainActor class PlaybackManager: ObservableObject { @Published var playbackState: PlaybackState = .paused @Published var hasError = false @@ -13,20 +15,37 @@ class PlaybackManager: ObservableObject { private var audioPlayer = AVPlayer() func nextTrack() { - let now = Date().timeIntervalSince1970 - // add timestamp to the url to prevent caching - let playerItem = AVPlayerItem(url: URL(string: "https://infinifi.cafe/current.mp3?t=\(now)")!) - NotificationCenter.default.addObserver(self, selector: #selector(playbackFinished), name: AVPlayerItem.didPlayToEndTimeNotification, object: playerItem) - - audioPlayer.replaceCurrentItem(with: playerItem) - audioPlayer.play() - - playbackState = .playing + playbackState = .loading + Task { + try await loadCurrentTrack() + playbackState = .playing + } } func stop() { - audioPlayer.pause() playbackState = .paused + audioPlayer.pause() + } + + private nonisolated func loadCurrentTrack() async throws { + let now = Date().timeIntervalSince1970 + guard let url = URL(string: "https://infinifi.cafe/current.mp3?t=\(now)") else { + return + } + + // add timestamp to the url to prevent caching + let asset = AVAsset(url: url) + let isPlayable = try await asset.load(.isPlayable) + guard isPlayable else { + return + } + + let playerItem = AVPlayerItem(asset: asset) + + NotificationCenter.default.addObserver(self, selector: #selector(playbackFinished), name: AVPlayerItem.didPlayToEndTimeNotification, object: playerItem) + + await audioPlayer.replaceCurrentItem(with: playerItem) + await audioPlayer.play() } @objc