mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Buffering status
This commit is contained in:
parent
7fc078d315
commit
082e77a8d5
@ -626,7 +626,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
case .playing:
|
||||
isPaused = false
|
||||
playing = true
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
initialBuffering = true
|
||||
isPaused = !whilePlaying
|
||||
var isStreaming = false
|
||||
|
@ -292,12 +292,12 @@ private final class MediaPlayerContext {
|
||||
duration = max(duration, CMTimeGetSeconds(audioTrackFrameBuffer.duration))
|
||||
}
|
||||
loadedDuration = duration
|
||||
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play), soundEnabled: self.enableSound)
|
||||
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play, progress: 0.0), soundEnabled: self.enableSound)
|
||||
self.playerStatus.set(.single(status))
|
||||
let _ = self.playerStatusValue.swap(status)
|
||||
} else {
|
||||
let duration = seekState?.duration ?? 0.0
|
||||
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play), soundEnabled: self.enableSound)
|
||||
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play, progress: 0.0), soundEnabled: self.enableSound)
|
||||
self.playerStatus.set(.single(status))
|
||||
let _ = self.playerStatusValue.swap(status)
|
||||
}
|
||||
@ -778,7 +778,7 @@ private final class MediaPlayerContext {
|
||||
}
|
||||
|
||||
var rate: Double
|
||||
var buffering = false
|
||||
var bufferingProgress: Float?
|
||||
|
||||
if let worstStatus = worstStatus, case let .full(fullUntil) = worstStatus, fullUntil.isFinite {
|
||||
if case .playing = self.state {
|
||||
@ -811,8 +811,18 @@ private final class MediaPlayerContext {
|
||||
rate = 0.0
|
||||
}
|
||||
}
|
||||
} else if case let .buffering(progress) = worstStatus {
|
||||
bufferingProgress = Float(progress)
|
||||
rate = 0.0
|
||||
print("bufferingProgress = \(progress)")
|
||||
|
||||
let tickTimer = SwiftSignalKit.Timer(timeout: 0.1, repeat: false, completion: { [weak self] in
|
||||
self?.tick()
|
||||
}, queue: self.queue)
|
||||
self.tickTimer = tickTimer
|
||||
tickTimer.start()
|
||||
} else {
|
||||
buffering = true
|
||||
bufferingProgress = 0.0
|
||||
rate = 0.0
|
||||
}
|
||||
|
||||
@ -854,12 +864,12 @@ private final class MediaPlayerContext {
|
||||
|
||||
var statusTimestamp = CACurrentMediaTime()
|
||||
let playbackStatus: MediaPlayerPlaybackStatus
|
||||
if buffering {
|
||||
if let bufferingProgress = bufferingProgress {
|
||||
var whilePlaying = false
|
||||
if case .playing = self.state {
|
||||
whilePlaying = true
|
||||
}
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: whilePlaying)
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: whilePlaying, progress: Float(bufferingProgress))
|
||||
} else if !rate.isZero {
|
||||
if reportRate.isZero {
|
||||
//playbackStatus = .buffering(initial: false, whilePlaying: true)
|
||||
@ -910,7 +920,7 @@ private final class MediaPlayerContext {
|
||||
public enum MediaPlayerPlaybackStatus: Equatable {
|
||||
case playing
|
||||
case paused
|
||||
case buffering(initial: Bool, whilePlaying: Bool)
|
||||
case buffering(initial: Bool, whilePlaying: Bool, progress: Float)
|
||||
|
||||
public static func ==(lhs: MediaPlayerPlaybackStatus, rhs: MediaPlayerPlaybackStatus) -> Bool {
|
||||
switch lhs {
|
||||
@ -926,8 +936,8 @@ public enum MediaPlayerPlaybackStatus: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .buffering(initial, whilePlaying):
|
||||
if case .buffering(initial, whilePlaying) = rhs {
|
||||
case let .buffering(initial, whilePlaying, progress):
|
||||
if case .buffering(initial, whilePlaying, progress) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
@ -781,7 +781,7 @@ public final class MediaPlayerScrubbingNode: ASDisplayNode {
|
||||
default:
|
||||
break
|
||||
}
|
||||
if case .buffering(true, _) = statusValue.status {
|
||||
if case .buffering(true, _, _) = statusValue.status {
|
||||
//initialBuffering = true
|
||||
} else if Double(0.0).isLess(than: statusValue.duration) {
|
||||
if let scrubbingTimestampValue = self.scrubbingTimestampValue {
|
||||
|
@ -3,7 +3,7 @@ import SwiftSignalKit
|
||||
import CoreMedia
|
||||
|
||||
public enum MediaTrackFrameBufferStatus {
|
||||
case buffering
|
||||
case buffering(progress: Double)
|
||||
case full(until: Double)
|
||||
case finished(at: Double)
|
||||
}
|
||||
@ -123,7 +123,12 @@ public final class MediaTrackFrameBuffer {
|
||||
if traceEvents {
|
||||
print("buffered duration: \(bufferedDuration), requesting until \(timestamp) + \(self.highWaterDuration - bufferedDuration)")
|
||||
}
|
||||
self.frameSource.generateFrames(until: timestamp + self.highWaterDuration)
|
||||
let delayIncrement = 0.3
|
||||
var generateUntil = timestamp + delayIncrement
|
||||
while generateUntil < timestamp + self.highWaterDuration {
|
||||
self.frameSource.generateFrames(until: min(timestamp + self.highWaterDuration, generateUntil))
|
||||
generateUntil += delayIncrement
|
||||
}
|
||||
|
||||
if bufferedDuration > self.stallDuration {
|
||||
if traceEvents {
|
||||
@ -131,7 +136,7 @@ public final class MediaTrackFrameBuffer {
|
||||
}
|
||||
return .full(until: timestamp + self.highWaterDuration)
|
||||
} else {
|
||||
return .buffering
|
||||
return .buffering(progress: max(0.0, bufferedDuration / self.stallDuration))
|
||||
}
|
||||
} else {
|
||||
if traceEvents {
|
||||
|
@ -331,7 +331,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
switch status {
|
||||
case .paused:
|
||||
paused = true
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
paused = !whilePlaying
|
||||
case .playing:
|
||||
paused = false
|
||||
|
@ -176,7 +176,7 @@ final class ChatRecordingPreviewInputPanelNode: ChatInputPanelNode {
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
switch status.status {
|
||||
case .playing, .buffering(_, true):
|
||||
case .playing, .buffering(_, true, _):
|
||||
strongSelf.playButton.isHidden = true
|
||||
default:
|
||||
strongSelf.playButton.isHidden = false
|
||||
|
@ -60,7 +60,7 @@ func messageFileMediaResourceStatus(context: AccountContext, file: TelegramMedia
|
||||
mediaStatus = .playbackStatus(.playing)
|
||||
case .paused:
|
||||
mediaStatus = .playbackStatus(.paused)
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
if whilePlaying {
|
||||
mediaStatus = .playbackStatus(.playing)
|
||||
} else {
|
||||
@ -84,7 +84,7 @@ func messageFileMediaResourceStatus(context: AccountContext, file: TelegramMedia
|
||||
mediaStatus = .playbackStatus(.playing)
|
||||
case .paused:
|
||||
mediaStatus = .playbackStatus(.paused)
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
if whilePlaying {
|
||||
mediaStatus = .playbackStatus(.playing)
|
||||
} else {
|
||||
|
@ -149,7 +149,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
switch value.status.status {
|
||||
case .playing:
|
||||
isPlaying = true
|
||||
case .buffering(_, true):
|
||||
case .buffering(_, true, _):
|
||||
isPlaying = true
|
||||
default:
|
||||
break
|
||||
@ -229,7 +229,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
updatedGlobalControlOptions.insert(.next)
|
||||
updatedGlobalControlOptions.insert(.seek)
|
||||
switch state.status.status {
|
||||
case .playing, .buffering(_, true):
|
||||
case .playing, .buffering(_, true, _):
|
||||
updatedGlobalControlOptions.insert(.pause)
|
||||
default:
|
||||
updatedGlobalControlOptions.insert(.play)
|
||||
@ -383,7 +383,7 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|
||||
switch state.status.status {
|
||||
case .playing:
|
||||
isPlaying = true
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
isPlaying = whilePlaying
|
||||
default:
|
||||
break
|
||||
|
@ -304,7 +304,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
||||
isPaused = false
|
||||
case .paused:
|
||||
isPaused = true
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
isPaused = !whilePlaying
|
||||
}
|
||||
if strongSelf.currentIsPaused != isPaused {
|
||||
|
@ -14,7 +14,7 @@ final class GenericEmbedImplementation: WebEmbedImplementation {
|
||||
|
||||
init(url: String) {
|
||||
self.url = url
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true, progress: 0.0), soundEnabled: true)
|
||||
}
|
||||
|
||||
func setup(_ webView: WKWebView, userContentController: WKUserContentController, evaluateJavaScript: @escaping (String, ((Any?) -> Void)?) -> Void, updateStatus: @escaping (MediaPlayerStatus) -> Void, onPlaybackStarted: @escaping () -> Void) {
|
||||
|
@ -37,7 +37,7 @@ final class PictureInPictureVideoControlsNode: ASDisplayNode {
|
||||
case .playing:
|
||||
self.playButton.isHidden = true
|
||||
self.pauseButton.isHidden = false
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
if whilePlaying {
|
||||
self.playButton.isHidden = true
|
||||
self.pauseButton.isHidden = false
|
||||
|
@ -315,7 +315,7 @@ private final class PlatformVideoContentNode: ASDisplayNode, UniversalVideoConte
|
||||
self.isBuffering = false
|
||||
}
|
||||
if self.isBuffering {
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying)
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying, progress: 0.0)
|
||||
} else {
|
||||
status = isPlaying ? .playing : .paused
|
||||
}
|
||||
@ -326,7 +326,7 @@ private final class PlatformVideoContentNode: ASDisplayNode, UniversalVideoConte
|
||||
let status: MediaPlayerPlaybackStatus
|
||||
self.isBuffering = true
|
||||
if self.isBuffering {
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying)
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying, progress: 0.0)
|
||||
} else {
|
||||
status = isPlaying ? .playing : .paused
|
||||
}
|
||||
@ -337,7 +337,7 @@ private final class PlatformVideoContentNode: ASDisplayNode, UniversalVideoConte
|
||||
let status: MediaPlayerPlaybackStatus
|
||||
self.isBuffering = false
|
||||
if self.isBuffering {
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying)
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying, progress: 0.0)
|
||||
} else {
|
||||
status = isPlaying ? .playing : .paused
|
||||
}
|
||||
@ -381,7 +381,7 @@ private final class PlatformVideoContentNode: ASDisplayNode, UniversalVideoConte
|
||||
func play() {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
if !self.initializedStatus {
|
||||
self._status.set(MediaPlayerStatus(generationTimestamp: 0.0, duration: Double(self.approximateDuration), dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true))
|
||||
self._status.set(MediaPlayerStatus(generationTimestamp: 0.0, duration: Double(self.approximateDuration), dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true, progress: 0.0), soundEnabled: true))
|
||||
}
|
||||
if !self.hasAudioSession {
|
||||
self.audioSessionDisposable.set(self.audioSessionManager.push(audioSessionType: .play, activate: { [weak self] _ in
|
||||
|
@ -44,7 +44,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
private let playbackCompletedListeners = Bag<() -> Void>()
|
||||
|
||||
private var initializedStatus = false
|
||||
private var statusValue = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: false), soundEnabled: true)
|
||||
private var statusValue = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: false, progress: 0.0), soundEnabled: true)
|
||||
private var isBuffering = true
|
||||
private let _status = ValuePromise<MediaPlayerStatus>()
|
||||
var status: Signal<MediaPlayerStatus, NoError> {
|
||||
@ -169,7 +169,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
let isPlaying = !self.player.rate.isZero
|
||||
let status: MediaPlayerPlaybackStatus
|
||||
if self.isBuffering {
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying)
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying, progress: 0.0)
|
||||
} else {
|
||||
status = isPlaying ? .playing : .paused
|
||||
}
|
||||
@ -180,7 +180,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
let status: MediaPlayerPlaybackStatus
|
||||
self.isBuffering = true
|
||||
if self.isBuffering {
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying)
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying, progress: 0.0)
|
||||
} else {
|
||||
status = isPlaying ? .playing : .paused
|
||||
}
|
||||
@ -191,7 +191,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
let status: MediaPlayerPlaybackStatus
|
||||
self.isBuffering = false
|
||||
if self.isBuffering {
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying)
|
||||
status = .buffering(initial: false, whilePlaying: isPlaying, progress: 0.0)
|
||||
} else {
|
||||
status = isPlaying ? .playing : .paused
|
||||
}
|
||||
@ -219,7 +219,7 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
func play() {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
if !self.initializedStatus {
|
||||
self._status.set(MediaPlayerStatus(generationTimestamp: 0.0, duration: Double(self.approximateDuration), dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: self.seekId, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true))
|
||||
self._status.set(MediaPlayerStatus(generationTimestamp: 0.0, duration: Double(self.approximateDuration), dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: self.seekId, status: .buffering(initial: true, whilePlaying: true, progress: 0.0), soundEnabled: true))
|
||||
}
|
||||
if !self.hasAudioSession {
|
||||
self.audioSessionDisposable.set(self.audioSessionManager.push(audioSessionType: .play, activate: { [weak self] _ in
|
||||
|
@ -20,7 +20,7 @@ final class TwitchEmbedImplementation: WebEmbedImplementation {
|
||||
|
||||
init(url: String) {
|
||||
self.url = url
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true, progress: 0.0), soundEnabled: true)
|
||||
}
|
||||
|
||||
func setup(_ webView: WKWebView, userContentController: WKUserContentController, evaluateJavaScript: @escaping (String, ((Any?) -> Void)?) -> Void, updateStatus: @escaping (MediaPlayerStatus) -> Void, onPlaybackStarted: @escaping () -> Void) {
|
||||
|
@ -97,7 +97,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
init(videoId: String, timestamp: Int = 0) {
|
||||
self.videoId = videoId
|
||||
self.timestamp = timestamp
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: Double(timestamp), baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: Double(timestamp), baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true, progress: 0.0), soundEnabled: true)
|
||||
}
|
||||
|
||||
func setup(_ webView: WKWebView, userContentController: WKUserContentController, evaluateJavaScript: @escaping (String, ((Any?) -> Void)?) -> Void, updateStatus: @escaping (MediaPlayerStatus) -> Void, onPlaybackStarted: @escaping () -> Void) {
|
||||
@ -221,7 +221,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
playbackStatus = .paused
|
||||
newTimestamp = 0.0
|
||||
default:
|
||||
playbackStatus = .buffering(initial: true, whilePlaying: false)
|
||||
playbackStatus = .buffering(initial: true, whilePlaying: false, progress: 0.0)
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: Double(duration), dimensions: self.status.dimensions, timestamp: newTimestamp, baseRate: 1.0, seekId: self.status.seekId, status: playbackStatus, soundEnabled: true)
|
||||
|
@ -121,7 +121,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
if self.timestamp > 0 {
|
||||
self.ignoreEarlierTimestamps = true
|
||||
}
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: Double(timestamp), baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: Double(timestamp), baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true, progress: 0.0), soundEnabled: true)
|
||||
|
||||
self.benchmarkStartTime = CFAbsoluteTimeGetCurrent()
|
||||
}
|
||||
@ -286,16 +286,16 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
playbackStatus = .paused
|
||||
newTimestamp = 0.0
|
||||
} else {
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: true)
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: true, progress: 0.0)
|
||||
}
|
||||
case 1:
|
||||
playbackStatus = .playing
|
||||
case 2:
|
||||
playbackStatus = .paused
|
||||
case 3:
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: true)
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: true, progress: 0.0)
|
||||
default:
|
||||
playbackStatus = .buffering(initial: true, whilePlaying: false)
|
||||
playbackStatus = .buffering(initial: true, whilePlaying: false, progress: 0.0)
|
||||
}
|
||||
|
||||
if case .playing = playbackStatus, !self.started {
|
||||
|
@ -198,7 +198,7 @@ final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
switch value.status {
|
||||
case .playing:
|
||||
isPaused = false
|
||||
case let .buffering(_, whilePlaying):
|
||||
case let .buffering(_, whilePlaying, _):
|
||||
initialBuffering = true
|
||||
isPaused = !whilePlaying
|
||||
var isStreaming = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user