iOS: Random Album Radio plays whole albums in random order, loading each next album lazily
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a4c870251c
commit
3e832e3125
3 files changed
+45
-13
No files matched your search
@@ -201,7 +201,41 @@ final class PlaybackManager: StemEngineListener, @unchecked Sendable {
|
||||
messageListeners[id] = f
|
||||
return id
|
||||
}
|
||||
private func changed() { listeners.values.forEach { $0() } }
|
||||
private func changed() {
|
||||
listeners.values.forEach { $0() }
|
||||
topUpRadio()
|
||||
}
|
||||
|
||||
/// Album radio: every album in the library in random order, each played whole and in track order.
|
||||
/// Only the next album is fetched, once the queue is nearly played out.
|
||||
@ObservationIgnored private var radioDeck: [Album]?
|
||||
@ObservationIgnored private var radioBusy = false
|
||||
|
||||
func startAlbumRadio() async throws {
|
||||
var deck = try await plex.albums().shuffled()
|
||||
var first: [Track] = []
|
||||
while first.isEmpty, !deck.isEmpty { first = (try? await plex.albumTracks(deck.removeLast().ratingKey)) ?? [] }
|
||||
if first.isEmpty { return }
|
||||
playTracks(first)
|
||||
radioDeck = deck
|
||||
}
|
||||
|
||||
private func topUpRadio() {
|
||||
guard radioDeck != nil, !radioBusy, queue.count - index < 3 else { return }
|
||||
radioBusy = true
|
||||
Task { @MainActor in
|
||||
defer { radioBusy = false }
|
||||
while var deck = radioDeck, !deck.isEmpty {
|
||||
let album = deck.removeLast()
|
||||
radioDeck = deck
|
||||
if let t = try? await plex.albumTracks(album.ratingKey), !t.isEmpty, radioDeck != nil {
|
||||
addToQueue(t)
|
||||
return
|
||||
}
|
||||
}
|
||||
if radioDeck != nil, let all = try? await plex.albums(), !all.isEmpty { radioDeck = all.shuffled() }
|
||||
}
|
||||
}
|
||||
|
||||
func positionMs() -> Int64 {
|
||||
let snap = engine.snapshot
|
||||
@@ -229,6 +263,7 @@ final class PlaybackManager: StemEngineListener, @unchecked Sendable {
|
||||
|
||||
func playTracks(_ tracks: [Track], mixes: [[String: StemSetting]]? = nil, start: Int = 0, shuffle doShuffle: Bool = false) {
|
||||
if tracks.isEmpty { return }
|
||||
radioDeck = nil
|
||||
let items = items(tracks, mixes)
|
||||
if doShuffle {
|
||||
unshuffled = items
|
||||
|
||||
Reference in new issue
Block a user