fix: slider jumping after drag issue. Fix player can not play again issue

This commit is contained in:
CMK 2021-03-09 18:54:21 +08:00
parent 2b02b8deb6
commit fd4e99907b
2 changed files with 27 additions and 14 deletions

View File

@ -20,7 +20,6 @@ class AudioContainerViewModel {
audioView.playButton.publisher(for: .touchUpInside)
.sink { _ in
if audioAttachment === AudioPlayer.shared.attachment {
if AudioPlayer.shared.isPlaying() {
AudioPlayer.shared.pause()
@ -53,16 +52,26 @@ class AudioContainerViewModel {
audioAttachment: Attachment
) {
let audioView = cell.statusView.audioView
var lastCurrentTimeSubject: TimeInterval?
AudioPlayer.shared.currentTimeSubject
.receive(on: DispatchQueue.main)
.filter { _ in
audioAttachment === AudioPlayer.shared.attachment
}
.sink(receiveValue: { time in
audioView.timeLabel.text = time.asString(style: .positional)
if let duration = audioAttachment.meta?.original?.duration, !audioView.slider.isTracking {
audioView.slider.setValue(Float(time / duration), animated: true)
.throttle(for: 0.33, scheduler: DispatchQueue.main, latest: true)
.compactMap { time -> (TimeInterval, Float)? in
defer {
lastCurrentTimeSubject = time
}
guard audioAttachment === AudioPlayer.shared.attachment else { return nil }
guard let duration = audioAttachment.meta?.original?.duration else { return nil }
if let lastCurrentTimeSubject = lastCurrentTimeSubject, time != 0.0 {
guard abs(time - lastCurrentTimeSubject) < 0.5 else { return nil } // debounce
}
guard !audioView.slider.isTracking else { return nil }
return (time, Float(time / duration))
}
.sink(receiveValue: { time, progress in
audioView.timeLabel.text = time.asString(style: .positional)
audioView.slider.setValue(progress, animated: true)
})
.store(in: &cell.disposeBag)
AudioPlayer.shared.playbackState

View File

@ -18,14 +18,16 @@ final class AudioPlayer: NSObject {
var timeObserver: Any?
var statusObserver: Any?
var attachment: Attachment?
var currentURL: URL?
let session = AVAudioSession.sharedInstance()
let playbackState = CurrentValueSubject<PlaybackState, Never>(PlaybackState.unknown)
// MARK: - singleton
public static let shared = AudioPlayer()
let currentTimeSubject = CurrentValueSubject<TimeInterval, Never>(0)
override init() {
private override init() {
super.init()
addObserver()
}
@ -45,7 +47,7 @@ extension AudioPlayer {
if audioAttachment == attachment {
if self.playbackState.value == .stopped {
self.seekToTime(time: 0)
self.seekToTime(time: .zero)
}
player.play()
self.playbackState.value = .playing
@ -97,12 +99,14 @@ extension AudioPlayer {
case .unknown:
self.playbackState.value = .unknown
@unknown default:
fatalError()
assertionFailure()
}
})
.store(in: &disposeBag)
NotificationCenter.default.publisher(for: .AVPlayerItemDidPlayToEndTime, object: nil)
.sink { _ in
.sink { [weak self] _ in
guard let self = self else { return }
self.player.seek(to: .zero)
self.playbackState.value = .stopped
self.currentTimeSubject.value = 0
}