mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Merge pull request #1201 from omnivore-app/fix/ios-tts-player-feedback
Update UI after seeking, dont try to detect end of stream using currentTime
This commit is contained in:
commit
9059d6d500
4 changed files with 33 additions and 24 deletions
|
|
@ -402,15 +402,24 @@ public struct MiniPlayer: View {
|
|||
}
|
||||
}
|
||||
|
||||
var scrubbing: Bool {
|
||||
switch audioController.scrubState {
|
||||
case .scrubStarted:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func onDragChanged(value: DragGesture.Value) {
|
||||
if value.translation.height > 0, expanded {
|
||||
if value.translation.height > 0, expanded, !scrubbing {
|
||||
offset = value.translation.height
|
||||
}
|
||||
}
|
||||
|
||||
func onDragEnded(value: DragGesture.Value) {
|
||||
withAnimation(.interactiveSpring()) {
|
||||
if value.translation.height > minExpandedHeight {
|
||||
if value.translation.height > minExpandedHeight, !scrubbing {
|
||||
expanded = false
|
||||
}
|
||||
offset = 0
|
||||
|
|
|
|||
|
|
@ -204,15 +204,17 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate
|
|||
if let playerItem = player?.currentItem as? SpeechPlayerItem {
|
||||
if playerItem.speechItem.audioIdx == foundIdx {
|
||||
playerItem.seek(to: CMTimeMakeWithSeconds(remainder, preferredTimescale: 600), completionHandler: nil)
|
||||
scrubState = .reset
|
||||
fireTimer()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Move the playback to the found index, we should also seek a bit
|
||||
// within this index, but this is probably accurate enough for now.
|
||||
// Move the playback to the found index, we also seek by the remainder amount
|
||||
// before moving we pause the player so playback doesnt jump to a previous spot
|
||||
player?.pause()
|
||||
player?.removeAllItems()
|
||||
synthesizeFrom(start: foundIdx, playWhenReady: state == .playing, atOffset: remainder)
|
||||
return
|
||||
} else {
|
||||
// There was no foundIdx, so we are probably trying to seek past the end, so
|
||||
// just seek to the last possible duration.
|
||||
|
|
@ -221,6 +223,9 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate
|
|||
synthesizeFrom(start: durations.count - 1, playWhenReady: state == .playing, atOffset: last)
|
||||
}
|
||||
}
|
||||
|
||||
scrubState = .reset
|
||||
fireTimer()
|
||||
}
|
||||
|
||||
@AppStorage(UserDefaultKey.textToSpeechPlaybackRate.rawValue) public var playbackRate = 1.0 {
|
||||
|
|
@ -299,8 +304,7 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate
|
|||
if state == .reachedEnd {
|
||||
return false
|
||||
}
|
||||
return
|
||||
itemAudioProperties?.itemID == itemID &&
|
||||
return itemAudioProperties?.itemID == itemID &&
|
||||
(state == .loading || player?.currentItem == nil || player?.currentItem?.status == .unknown)
|
||||
}
|
||||
|
||||
|
|
@ -431,7 +435,6 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate
|
|||
|
||||
func startTimer() {
|
||||
if timer == nil {
|
||||
// Update every 100ms
|
||||
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(fireTimer), userInfo: nil, repeats: true)
|
||||
timer?.fire()
|
||||
}
|
||||
|
|
@ -445,13 +448,6 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate
|
|||
stop()
|
||||
}
|
||||
|
||||
if player.items().count == 1, let currentTime = player.currentItem?.currentTime(), let duration = player.currentItem?.duration {
|
||||
if currentTime >= duration {
|
||||
pause()
|
||||
state = .reachedEnd
|
||||
}
|
||||
}
|
||||
|
||||
if let durations = durations {
|
||||
duration = durations.reduce(0, +)
|
||||
durationString = formatTimeInterval(duration)
|
||||
|
|
@ -465,17 +461,23 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate
|
|||
let itemElapsed = playerItem.status == .readyToPlay ? CMTimeGetSeconds(playerItem.currentTime()) : 0
|
||||
timeElapsed = durationBefore(playerIndex: playerItem.speechItem.audioIdx) + itemElapsed
|
||||
timeElapsedString = formatTimeInterval(timeElapsed)
|
||||
|
||||
if var nowPlaying = MPNowPlayingInfoCenter.default().nowPlayingInfo {
|
||||
nowPlaying[MPMediaItemPropertyPlaybackDuration] = NSNumber(value: duration)
|
||||
nowPlaying[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: timeElapsed)
|
||||
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlaying
|
||||
}
|
||||
}
|
||||
case .scrubStarted:
|
||||
break
|
||||
case let .scrubEnded(seekTime):
|
||||
timeElapsed = seekTime
|
||||
timeElapsedString = formatTimeInterval(timeElapsed)
|
||||
if var nowPlaying = MPNowPlayingInfoCenter.default().nowPlayingInfo {
|
||||
nowPlaying[MPMediaItemPropertyPlaybackDuration] = NSNumber(value: duration)
|
||||
nowPlaying[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: timeElapsed)
|
||||
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlaying
|
||||
}
|
||||
case .scrubStarted:
|
||||
break
|
||||
case let .scrubEnded(seekTime):
|
||||
scrubState = .reset
|
||||
timeElapsed = seekTime
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ func fetchUtterance(appEnvironment: AppEnvironment,
|
|||
|
||||
if let ssml = try utterance.toSSML(document: document) {
|
||||
request.httpBody = ssml
|
||||
print("FETCHING: ", String(decoding: ssml, as: UTF8.self))
|
||||
}
|
||||
|
||||
for (header, value) in networker.defaultHeaders {
|
||||
|
|
@ -219,7 +218,6 @@ func fetchUtterance(appEnvironment: AppEnvironment,
|
|||
try audioData.write(to: tempPath)
|
||||
try? FileManager.default.removeItem(at: audioPath)
|
||||
try FileManager.default.moveItem(at: tempPath, to: audioPath)
|
||||
print("wrote", audioData.count, "bytes to", audioPath)
|
||||
} catch {
|
||||
let errorMessage = "audioFetch failed. could not write MP3 data to disk"
|
||||
throw BasicError.message(messageText: errorMessage)
|
||||
|
|
|
|||
|
|
@ -74,10 +74,10 @@ public struct FeedCard: View {
|
|||
Spacer()
|
||||
}
|
||||
}
|
||||
.padding(.top, 8)
|
||||
.padding(.top, 0)
|
||||
}
|
||||
}
|
||||
.padding(.top, 10)
|
||||
.padding(.top, 0)
|
||||
.padding(.bottom, 8)
|
||||
.frame(
|
||||
minWidth: nil,
|
||||
|
|
|
|||
Loading…
Reference in a new issue