mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Fade in/out on playback toggle
This commit is contained in:
@@ -123,6 +123,7 @@ private final class MediaPlayerContext {
|
||||
fileprivate let videoRenderer: VideoPlayerProxy
|
||||
|
||||
private var tickTimer: SwiftSignalKit.Timer?
|
||||
private var fadeTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private var lastStatusUpdateTimestamp: Double?
|
||||
private let playerStatus: Promise<MediaPlayerStatus>
|
||||
@@ -224,6 +225,7 @@ private final class MediaPlayerContext {
|
||||
deinit {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
self.fadeTimer?.invalidate()
|
||||
self.tickTimer?.invalidate()
|
||||
|
||||
if case let .seeking(_, _, _, disposable, _, _) = self.state {
|
||||
@@ -383,7 +385,7 @@ private final class MediaPlayerContext {
|
||||
if strongSelf.continuePlayingWithoutSoundOnLostAudioSession {
|
||||
strongSelf.continuePlayingWithoutSound()
|
||||
} else {
|
||||
strongSelf.pause(lostAudioSession: true)
|
||||
strongSelf.pause(lostAudioSession: true, faded: false)
|
||||
}
|
||||
} else {
|
||||
strongSelf.seek(timestamp: 0.0, action: .play)
|
||||
@@ -440,7 +442,7 @@ private final class MediaPlayerContext {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func play() {
|
||||
fileprivate func play(faded: Bool = false) {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
switch self.state {
|
||||
@@ -461,7 +463,7 @@ private final class MediaPlayerContext {
|
||||
if strongSelf.continuePlayingWithoutSoundOnLostAudioSession {
|
||||
strongSelf.continuePlayingWithoutSound()
|
||||
} else {
|
||||
strongSelf.pause(lostAudioSession: true)
|
||||
strongSelf.pause(lostAudioSession: true, faded: false)
|
||||
}
|
||||
} else {
|
||||
strongSelf.seek(timestamp: 0.0, action: .play)
|
||||
@@ -477,6 +479,26 @@ private final class MediaPlayerContext {
|
||||
self.state = .seeking(frameSource: frameSource, timestamp: timestamp, seekState: seekState, disposable: disposable, action: .play, enableSound: enableSound)
|
||||
self.lastStatusUpdateTimestamp = nil
|
||||
case let .paused(loadedState):
|
||||
if faded {
|
||||
self.fadeTimer?.invalidate()
|
||||
|
||||
var volume: Double = 0.0
|
||||
let fadeTimer = SwiftSignalKit.Timer(timeout: 0.025, repeat: true, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
volume += 0.1
|
||||
if volume < 1.0 {
|
||||
strongSelf.audioRenderer?.renderer.setVolume(volume)
|
||||
} else {
|
||||
strongSelf.audioRenderer?.renderer.setVolume(1.0)
|
||||
strongSelf.fadeTimer?.invalidate()
|
||||
strongSelf.fadeTimer = nil
|
||||
}
|
||||
}
|
||||
}, queue: self.queue)
|
||||
self.fadeTimer = fadeTimer
|
||||
fadeTimer.start()
|
||||
}
|
||||
|
||||
if loadedState.lostAudioSession {
|
||||
let timestamp = CMTimeGetSeconds(CMTimebaseGetTime(loadedState.controlTimebase.timebase))
|
||||
self.seek(timestamp: timestamp, action: .play)
|
||||
@@ -632,7 +654,7 @@ private final class MediaPlayerContext {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func pause(lostAudioSession: Bool) {
|
||||
fileprivate func pause(lostAudioSession: Bool, faded: Bool = false) {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
switch self.state {
|
||||
@@ -651,31 +673,52 @@ private final class MediaPlayerContext {
|
||||
}
|
||||
self.state = .paused(loadedState)
|
||||
self.lastStatusUpdateTimestamp = nil
|
||||
|
||||
if faded {
|
||||
self.fadeTimer?.invalidate()
|
||||
|
||||
var volume: Double = 1.0
|
||||
let fadeTimer = SwiftSignalKit.Timer(timeout: 0.025, repeat: true, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
volume -= 0.1
|
||||
if volume > 0 {
|
||||
strongSelf.audioRenderer?.renderer.setVolume(volume)
|
||||
} else {
|
||||
strongSelf.fadeTimer?.invalidate()
|
||||
strongSelf.fadeTimer = nil
|
||||
strongSelf.tick()
|
||||
}
|
||||
}
|
||||
}, queue: self.queue)
|
||||
self.fadeTimer = fadeTimer
|
||||
fadeTimer.start()
|
||||
}
|
||||
|
||||
self.tick()
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func togglePlayPause() {
|
||||
fileprivate func togglePlayPause(faded: Bool) {
|
||||
assert(self.queue.isCurrent())
|
||||
|
||||
switch self.state {
|
||||
case .empty:
|
||||
self.play()
|
||||
self.play(faded: false)
|
||||
case let .seeking(_, _, _, _, action, _):
|
||||
switch action {
|
||||
case .play:
|
||||
self.pause(lostAudioSession: false)
|
||||
self.pause(lostAudioSession: false, faded: faded)
|
||||
case .pause:
|
||||
self.play()
|
||||
self.play(faded: faded)
|
||||
}
|
||||
case .paused:
|
||||
if !self.enableSound {
|
||||
self.playOnceWithSound(playAndRecord: false, seek: .none)
|
||||
} else {
|
||||
self.play()
|
||||
self.play(faded: faded)
|
||||
}
|
||||
case .playing:
|
||||
self.pause(lostAudioSession: false)
|
||||
self.pause(lostAudioSession: false, faded: faded)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,7 +830,13 @@ private final class MediaPlayerContext {
|
||||
var bufferingProgress: Float?
|
||||
|
||||
if let worstStatus = worstStatus, case let .full(fullUntil) = worstStatus, fullUntil.isFinite {
|
||||
var playing = false
|
||||
if case .playing = self.state {
|
||||
playing = true
|
||||
} else if self.fadeTimer != nil {
|
||||
playing = true
|
||||
}
|
||||
if playing {
|
||||
rate = self.baseRate
|
||||
|
||||
let nextTickDelay = max(0.0, fullUntil - timestamp) / self.baseRate
|
||||
@@ -805,7 +854,13 @@ private final class MediaPlayerContext {
|
||||
rate = 0.0
|
||||
performActionAtEndNow = true
|
||||
} else {
|
||||
var playing = false
|
||||
if case .playing = self.state {
|
||||
playing = true
|
||||
} else if self.fadeTimer != nil {
|
||||
playing = true
|
||||
}
|
||||
if playing {
|
||||
rate = self.baseRate
|
||||
|
||||
let tickTimer = SwiftSignalKit.Timer(timeout: nextTickDelay, repeat: false, completion: { [weak self] in
|
||||
@@ -871,13 +926,18 @@ private final class MediaPlayerContext {
|
||||
var statusTimestamp = CACurrentMediaTime()
|
||||
let playbackStatus: MediaPlayerPlaybackStatus
|
||||
var isPlaying = false
|
||||
var isPaused = false
|
||||
if case .playing = self.state {
|
||||
isPlaying = true
|
||||
} else if case .paused = self.state {
|
||||
isPaused = true
|
||||
}
|
||||
if let bufferingProgress = bufferingProgress {
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: isPlaying, progress: Float(bufferingProgress), display: true)
|
||||
} else if !rate.isZero {
|
||||
if reportRate.isZero {
|
||||
if isPaused && self.fadeTimer != nil {
|
||||
playbackStatus = .paused
|
||||
} else if reportRate.isZero {
|
||||
//playbackStatus = .buffering(initial: false, whilePlaying: true)
|
||||
playbackStatus = .playing
|
||||
statusTimestamp = 0.0
|
||||
@@ -1076,10 +1136,10 @@ public final class MediaPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
public func togglePlayPause() {
|
||||
public func togglePlayPause(faded: Bool = false) {
|
||||
self.queue.async {
|
||||
if let context = self.contextRef?.takeUnretainedValue() {
|
||||
context.togglePlayPause()
|
||||
context.togglePlayPause(faded: faded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user