mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 07:34:32 +00:00
Working LIVE indicator
This commit is contained in:
parent
b053c4ca33
commit
fa1bd97d84
5 changed files with 255 additions and 58 deletions
|
|
@ -44,11 +44,17 @@ class MusicManager: ObservableObject {
|
|||
@Published var playbackRate: Double = 1
|
||||
@Published var isShuffled: Bool = false
|
||||
@Published var repeatMode: RepeatMode = .off
|
||||
@Published var isLiveStream: Bool = false
|
||||
@ObservedObject var coordinator = DynamicIslandViewCoordinator.shared
|
||||
@Published var usingAppIconForArtwork: Bool = false
|
||||
|
||||
private var artworkData: Data? = nil
|
||||
|
||||
private var liveStreamUnknownDurationCount: Int = 0
|
||||
private var liveStreamEdgeObservationCount: Int = 0
|
||||
private var liveStreamCompletionObservationCount: Int = 0
|
||||
private var liveStreamCompletionReleaseCount: Int = 0
|
||||
|
||||
// Store last values at the time artwork was changed
|
||||
private var lastArtworkTitle: String = "I'm Handsome"
|
||||
private var lastArtworkArtist: String = "Me"
|
||||
|
|
@ -262,6 +268,7 @@ class MusicManager: ObservableObject {
|
|||
self.repeatMode = state.repeatMode
|
||||
}
|
||||
|
||||
updateLiveStreamState(with: state)
|
||||
self.timestampDate = state.lastUpdated
|
||||
}
|
||||
|
||||
|
|
@ -271,6 +278,76 @@ class MusicManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
private func updateLiveStreamState(with state: PlaybackState) {
|
||||
let duration = state.duration
|
||||
let current = max(state.currentTime, elapsedTime)
|
||||
let hasKnownDuration = duration.isFinite && duration > 0
|
||||
let isPlaying = state.isPlaying
|
||||
|
||||
if hasKnownDuration {
|
||||
liveStreamUnknownDurationCount = 0
|
||||
|
||||
let remaining = duration - current
|
||||
let clampedDuration = max(duration, 0)
|
||||
let clampedCurrent = clampedDuration > 0
|
||||
? max(0, min(current, clampedDuration))
|
||||
: max(0, current)
|
||||
let progress = clampedDuration > 0 ? clampedCurrent / clampedDuration : 0
|
||||
let sliderAppearsComplete = isPlaying && clampedDuration > 0 && progress >= 0.999
|
||||
let nearDurationEdge = isPlaying && remaining.isFinite && remaining <= 1.0 && clampedCurrent >= 10
|
||||
|
||||
if sliderAppearsComplete {
|
||||
liveStreamCompletionObservationCount = min(liveStreamCompletionObservationCount + 1, 8)
|
||||
liveStreamCompletionReleaseCount = 0
|
||||
} else {
|
||||
liveStreamCompletionReleaseCount = min(liveStreamCompletionReleaseCount + 1, 8)
|
||||
if liveStreamCompletionObservationCount > 0 {
|
||||
liveStreamCompletionObservationCount = max(liveStreamCompletionObservationCount - 1, 0)
|
||||
}
|
||||
}
|
||||
|
||||
if nearDurationEdge || sliderAppearsComplete {
|
||||
liveStreamEdgeObservationCount = min(liveStreamEdgeObservationCount + 1, 12)
|
||||
} else if liveStreamEdgeObservationCount > 0 {
|
||||
liveStreamEdgeObservationCount = max(liveStreamEdgeObservationCount - 1, 0)
|
||||
}
|
||||
|
||||
if !isLiveStream {
|
||||
if liveStreamCompletionObservationCount >= 3 || liveStreamEdgeObservationCount >= 5 {
|
||||
isLiveStream = true
|
||||
}
|
||||
} else {
|
||||
let shouldClearForKnownDuration =
|
||||
!isPlaying
|
||||
|| (duration > 10 && remaining > 5)
|
||||
|| (liveStreamCompletionObservationCount == 0
|
||||
&& liveStreamEdgeObservationCount == 0
|
||||
&& liveStreamCompletionReleaseCount >= 4)
|
||||
|
||||
if shouldClearForKnownDuration {
|
||||
isLiveStream = false
|
||||
}
|
||||
}
|
||||
} else if isPlaying {
|
||||
liveStreamEdgeObservationCount = max(liveStreamEdgeObservationCount - 1, 0)
|
||||
liveStreamCompletionObservationCount = max(liveStreamCompletionObservationCount - 1, 0)
|
||||
liveStreamCompletionReleaseCount = 0
|
||||
|
||||
liveStreamUnknownDurationCount = min(liveStreamUnknownDurationCount + 1, 8)
|
||||
if liveStreamUnknownDurationCount >= 3 && !isLiveStream {
|
||||
isLiveStream = true
|
||||
}
|
||||
} else {
|
||||
liveStreamUnknownDurationCount = 0
|
||||
liveStreamEdgeObservationCount = 0
|
||||
liveStreamCompletionObservationCount = 0
|
||||
liveStreamCompletionReleaseCount = 0
|
||||
if !hasKnownDuration && isLiveStream {
|
||||
isLiveStream = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateArtwork(_ artworkData: Data) {
|
||||
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue