diff --git a/Source/Engine/AudioStreamEngine.swift b/Source/Engine/AudioStreamEngine.swift index 26642ed..101c7a2 100644 --- a/Source/Engine/AudioStreamEngine.swift +++ b/Source/Engine/AudioStreamEngine.swift @@ -121,7 +121,11 @@ class AudioStreamEngine: AudioEngine { let s = predictedStreamDurationDebounceHelper if d/DEBOUNCING_BUFFER_TIME != s/DEBOUNCING_BUFFER_TIME { predictedStreamDurationDebounceHelper = predictedStreamDuration - duration = predictedStreamDuration + if AudioDataManager.shared.currentStreamFinished { + duration = AudioDataManager.shared.currentStreamFinishedWithDuration + } else { + duration = predictedStreamDuration + } } } } @@ -245,7 +249,12 @@ class AudioStreamEngine: AudioEngine { let range = converter.pollNetworkAudioAvailabilityRange() isPlayable = (numberOfBuffersScheduledInTotal >= MIN_BUFFERS_TO_BE_PLAYABLE && range.1 > 0) && predictedStreamDuration > 0 Log.debug("loaded \(range), numberOfBuffersScheduledInTotal: \(numberOfBuffersScheduledInTotal), isPlayable: \(isPlayable)") - bufferedSeconds = SAAudioAvailabilityRange(startingNeedle: range.0, durationLoadedByNetwork: range.1, predictedDurationToLoad: predictedStreamDuration, isPlayable: isPlayable) + if AudioDataManager.shared.currentStreamFinished { + AudioDataManager.shared.updateDuration(d: range.1); + bufferedSeconds = SAAudioAvailabilityRange(startingNeedle: range.0, durationLoadedByNetwork: range.1, predictedDurationToLoad: range.1, isPlayable: isPlayable) + } else { + bufferedSeconds = SAAudioAvailabilityRange(startingNeedle: range.0, durationLoadedByNetwork: range.1, predictedDurationToLoad: predictedStreamDuration, isPlayable: isPlayable) + } } private func updateNeedle() { @@ -268,8 +277,13 @@ class AudioStreamEngine: AudioEngine { private func updateDuration() { if let d = converter.pollPredictedDuration() { - self.predictedStreamDuration = d - } + self.predictedStreamDuration = d + if AudioDataManager.shared.currentStreamFinished { + self.predictedStreamDuration = AudioDataManager.shared.currentStreamFinishedWithDuration + } else { + self.predictedStreamDuration = d + } + } } diff --git a/Source/Model/AudioDataManager.swift b/Source/Model/AudioDataManager.swift index d2f2714..e8ad3e4 100644 --- a/Source/Model/AudioDataManager.swift +++ b/Source/Model/AudioDataManager.swift @@ -26,6 +26,8 @@ import Foundation protocol AudioDataManagable { + var currentStreamFinished: Bool { get } + var currentStreamFinishedWithDuration: Duration { get } var numberOfQueued: Int { get } var numberOfActive: Int { get } @@ -38,6 +40,7 @@ protocol AudioDataManagable { func setDownloadDirectory(_ dir: FileManager.SearchPathDirectory) func clear() + func updateDuration(d: Duration) //Director pattern func attach(callback: @escaping (_ id: ID, _ progress: Double)->()) @@ -55,8 +58,13 @@ protocol AudioDataManagable { } class AudioDataManager: AudioDataManagable { + var currentStreamFinishedWithDuration: Duration = 0 + var allowCellular: Bool = true var downloadDirectory: FileManager.SearchPathDirectory = .documentDirectory + + public var currentStreamFinished = false + public var totalStreamedDuration = 0 static let shared: AudioDataManagable = AudioDataManager() @@ -95,6 +103,10 @@ class AudioDataManager: AudioDataManagable { progressCallback: streamProgressListener, doneCallback: streamDoneListener) } + + func updateDuration(d: Duration) { + currentStreamFinishedWithDuration = d + } func clear() { streamingCallbacks = [] @@ -125,6 +137,7 @@ class AudioDataManager: AudioDataManagable { // MARK:- Streaming extension AudioDataManager { func startStream(withRemoteURL url: AudioURL, callback: @escaping (StreamProgressPTO) -> ()) { + currentStreamFinished = false if let data = FileStorage.Audio.read(url.key) { let dto = StreamProgressDTO.init(progress: 1.0, data: data, totalBytesExpected: Int64(data.count)) callback(StreamProgressPTO(dto: dto)) @@ -154,10 +167,12 @@ extension AudioDataManager { streamWorker.resume(withId: url.key) } func seekStream(withRemoteURL url: AudioURL, toByteOffset offset: UInt64) { + currentStreamFinished = false streamWorker.seek(withId: url.key, withByteOffset: offset) } func deleteStream(withRemoteURL url: AudioURL) { + currentStreamFinished = false streamWorker.stop(withId: url.key) streamingCallbacks.removeAll { (cb: (ID, (StreamProgressPTO) -> ())) -> Bool in return cb.0 == url.key @@ -230,7 +245,7 @@ extension AudioDataManager { if error != nil { return false } - + currentStreamFinished = true downloadWorker.resumeAllActive() return false }