fix: slider jumping after drag issue. Fix player can not play again issue
This commit is contained in:
parent
2b02b8deb6
commit
fd4e99907b
|
@ -20,7 +20,6 @@ class AudioContainerViewModel {
|
||||||
|
|
||||||
audioView.playButton.publisher(for: .touchUpInside)
|
audioView.playButton.publisher(for: .touchUpInside)
|
||||||
.sink { _ in
|
.sink { _ in
|
||||||
|
|
||||||
if audioAttachment === AudioPlayer.shared.attachment {
|
if audioAttachment === AudioPlayer.shared.attachment {
|
||||||
if AudioPlayer.shared.isPlaying() {
|
if AudioPlayer.shared.isPlaying() {
|
||||||
AudioPlayer.shared.pause()
|
AudioPlayer.shared.pause()
|
||||||
|
@ -53,16 +52,26 @@ class AudioContainerViewModel {
|
||||||
audioAttachment: Attachment
|
audioAttachment: Attachment
|
||||||
) {
|
) {
|
||||||
let audioView = cell.statusView.audioView
|
let audioView = cell.statusView.audioView
|
||||||
|
var lastCurrentTimeSubject: TimeInterval?
|
||||||
AudioPlayer.shared.currentTimeSubject
|
AudioPlayer.shared.currentTimeSubject
|
||||||
.receive(on: DispatchQueue.main)
|
.throttle(for: 0.33, scheduler: DispatchQueue.main, latest: true)
|
||||||
.filter { _ in
|
.compactMap { time -> (TimeInterval, Float)? in
|
||||||
audioAttachment === AudioPlayer.shared.attachment
|
defer {
|
||||||
}
|
lastCurrentTimeSubject = time
|
||||||
.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)
|
|
||||||
}
|
}
|
||||||
|
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)
|
.store(in: &cell.disposeBag)
|
||||||
AudioPlayer.shared.playbackState
|
AudioPlayer.shared.playbackState
|
||||||
|
|
|
@ -18,14 +18,16 @@ final class AudioPlayer: NSObject {
|
||||||
var timeObserver: Any?
|
var timeObserver: Any?
|
||||||
var statusObserver: Any?
|
var statusObserver: Any?
|
||||||
var attachment: Attachment?
|
var attachment: Attachment?
|
||||||
var currentURL: URL?
|
|
||||||
let session = AVAudioSession.sharedInstance()
|
let session = AVAudioSession.sharedInstance()
|
||||||
let playbackState = CurrentValueSubject<PlaybackState, Never>(PlaybackState.unknown)
|
let playbackState = CurrentValueSubject<PlaybackState, Never>(PlaybackState.unknown)
|
||||||
|
|
||||||
|
// MARK: - singleton
|
||||||
public static let shared = AudioPlayer()
|
public static let shared = AudioPlayer()
|
||||||
|
|
||||||
let currentTimeSubject = CurrentValueSubject<TimeInterval, Never>(0)
|
let currentTimeSubject = CurrentValueSubject<TimeInterval, Never>(0)
|
||||||
|
|
||||||
override init() {
|
private override init() {
|
||||||
super.init()
|
super.init()
|
||||||
addObserver()
|
addObserver()
|
||||||
}
|
}
|
||||||
|
@ -45,7 +47,7 @@ extension AudioPlayer {
|
||||||
|
|
||||||
if audioAttachment == attachment {
|
if audioAttachment == attachment {
|
||||||
if self.playbackState.value == .stopped {
|
if self.playbackState.value == .stopped {
|
||||||
self.seekToTime(time: 0)
|
self.seekToTime(time: .zero)
|
||||||
}
|
}
|
||||||
player.play()
|
player.play()
|
||||||
self.playbackState.value = .playing
|
self.playbackState.value = .playing
|
||||||
|
@ -97,12 +99,14 @@ extension AudioPlayer {
|
||||||
case .unknown:
|
case .unknown:
|
||||||
self.playbackState.value = .unknown
|
self.playbackState.value = .unknown
|
||||||
@unknown default:
|
@unknown default:
|
||||||
fatalError()
|
assertionFailure()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
NotificationCenter.default.publisher(for: .AVPlayerItemDidPlayToEndTime, object: nil)
|
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.playbackState.value = .stopped
|
||||||
self.currentTimeSubject.value = 0
|
self.currentTimeSubject.value = 0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue