fix: GIF may cause background audio session pause issue
This commit is contained in:
parent
4318e3c9d1
commit
777534c82d
|
@ -37,6 +37,7 @@ final class VideoPlayerViewModel {
|
||||||
|
|
||||||
private var timeControlStatusObservation: NSKeyValueObservation?
|
private var timeControlStatusObservation: NSKeyValueObservation?
|
||||||
let timeControlStatus = CurrentValueSubject<AVPlayer.TimeControlStatus, Never>(.paused)
|
let timeControlStatus = CurrentValueSubject<AVPlayer.TimeControlStatus, Never>(.paused)
|
||||||
|
let playbackState = CurrentValueSubject<PlaybackState, Never>(PlaybackState.unknown)
|
||||||
|
|
||||||
init(previewImageURL: URL?, videoURL: URL, videoSize: CGSize, videoKind: VideoPlayerViewModel.Kind) {
|
init(previewImageURL: URL?, videoURL: URL, videoSize: CGSize, videoKind: VideoPlayerViewModel.Kind) {
|
||||||
self.previewImageURL = previewImageURL
|
self.previewImageURL = previewImageURL
|
||||||
|
@ -59,18 +60,41 @@ final class VideoPlayerViewModel {
|
||||||
self.timeControlStatus.value = player.timeControlStatus
|
self.timeControlStatus.value = player.timeControlStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
// update audio session category for user interactive event stream
|
player.publisher(for: \.status, options: [.initial, .new])
|
||||||
|
.sink(receiveValue: { [weak self] status in
|
||||||
|
guard let self = self else { return }
|
||||||
|
switch status {
|
||||||
|
case .failed:
|
||||||
|
self.playbackState.value = .failed
|
||||||
|
case .readyToPlay:
|
||||||
|
self.playbackState.value = .readyToPlay
|
||||||
|
case .unknown:
|
||||||
|
self.playbackState.value = .unknown
|
||||||
|
@unknown default:
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
timeControlStatus
|
timeControlStatus
|
||||||
.sink { [weak self] timeControlStatus in
|
.sink { [weak self] timeControlStatus in
|
||||||
guard let _ = self else { return }
|
guard let self = self else { return }
|
||||||
guard timeControlStatus == .playing else { return }
|
|
||||||
NotificationCenter.default.post(name: VideoPlayerViewModel.appWillPlayVideoNotification, object: nil)
|
// emit playing event
|
||||||
switch videoKind {
|
if timeControlStatus == .playing {
|
||||||
case .gif:
|
NotificationCenter.default.post(name: VideoPlayerViewModel.appWillPlayVideoNotification, object: nil)
|
||||||
break
|
}
|
||||||
case .video:
|
|
||||||
break
|
switch timeControlStatus {
|
||||||
// try? AVAudioSession.sharedInstance().setCategory(.soloAmbient, mode: .default)
|
case .paused:
|
||||||
|
self.playbackState.value = .paused
|
||||||
|
case .waitingToPlayAtSpecifiedRate:
|
||||||
|
self.playbackState.value = .buffering
|
||||||
|
case .playing:
|
||||||
|
self.playbackState.value = .playing
|
||||||
|
@unknown default:
|
||||||
|
assertionFailure()
|
||||||
|
self.playbackState.value = .unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
|
@ -82,6 +106,27 @@ final class VideoPlayerViewModel {
|
||||||
isPlay ? self.play() : self.pause()
|
isPlay ? self.play() : self.pause()
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
|
let sessionName = videoKind == .gif ? "GIF" : "Video"
|
||||||
|
playbackState
|
||||||
|
.receive(on: RunLoop.main)
|
||||||
|
.sink { [weak self] status in
|
||||||
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: %s status: %s", ((#file as NSString).lastPathComponent), #line, #function, sessionName, status.description)
|
||||||
|
guard let self = self else { return }
|
||||||
|
// only update audio session for video
|
||||||
|
guard self.videoKind == .video else { return }
|
||||||
|
switch status {
|
||||||
|
case .unknown, .buffering, .readyToPlay:
|
||||||
|
break
|
||||||
|
case .playing:
|
||||||
|
try? AVAudioSession.sharedInstance().setCategory(.soloAmbient)
|
||||||
|
try? AVAudioSession.sharedInstance().setActive(true)
|
||||||
|
case .paused, .stopped, .failed:
|
||||||
|
try? AVAudioSession.sharedInstance().setCategory(.ambient)
|
||||||
|
try? AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
|
Loading…
Reference in New Issue