mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Video avatar fixes
This commit is contained in:
parent
bc78f7f7fe
commit
a911b403ca
@ -1356,7 +1356,7 @@ static CGFloat progressOfSampleBufferInTimeRange(CMSampleBufferRef sampleBuffer,
|
||||
return 2000;
|
||||
|
||||
case TGMediaVideoConversionPresetProfileVeryHigh:
|
||||
return 2500;
|
||||
return 2300;
|
||||
|
||||
default:
|
||||
return 900;
|
||||
|
@ -147,7 +147,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
let imageSize = layoutConstants.instantVideo.dimensions
|
||||
let imageSize = CGSize(width: 212.0, height: 212.0)
|
||||
|
||||
let (labelLayout, apply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: attributedString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: constrainedSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
@ -222,7 +222,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
if let image = image, let video = image.videoRepresentations.last, let id = image.id?.id {
|
||||
let videoFileReference = FileMediaReference.standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: image.representations, videoThumbnails: [], immediateThumbnailData: image.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [])]))
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, "action"), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, autoFetchFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, "action"), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
if videoContent.id != strongSelf.videoContent?.id {
|
||||
let mediaManager = item.context.sharedContext.mediaManager
|
||||
let videoNode = UniversalVideoNode(postbox: item.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: videoContent, priority: .secondaryOverlay)
|
||||
|
@ -519,7 +519,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
var isBuffering: Bool?
|
||||
if let message = self.item?.message, let media = self.media, let size = media.size, (isMediaStreamable(message: message, media: media) || size <= 256 * 1024) && (self.automaticDownload ?? false) {
|
||||
if let message = self.item?.message, let media = self.media, isMediaStreamable(message: message, media: media) && (self.automaticDownload ?? false) {
|
||||
if let playerStatus = self.playerStatus, case .buffering = playerStatus.status {
|
||||
isBuffering = true
|
||||
} else {
|
||||
|
@ -198,8 +198,13 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
private var videoNode: UniversalVideoNode?
|
||||
private var videoContent: NativeVideoContent?
|
||||
private var videoStartTimestamp: Double?
|
||||
private let playbackStatusDisposable = MetaDisposable()
|
||||
private let playbackStartDisposable = MetaDisposable()
|
||||
private let statusDisposable = MetaDisposable()
|
||||
private let preloadDisposable = MetaDisposable()
|
||||
private var statusNode: RadialStatusNode?
|
||||
|
||||
private var fetchStatus: MediaResourceStatus?
|
||||
private var playerStatus: MediaPlayerStatus?
|
||||
|
||||
let isReady = Promise<Bool>()
|
||||
private var didSetReady: Bool = false
|
||||
@ -229,7 +234,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
self.preloadDisposable.set(nil)
|
||||
} else {
|
||||
if let videoNode = self.videoNode {
|
||||
self.playbackStatusDisposable.set(nil)
|
||||
self.playbackStartDisposable.set(nil)
|
||||
self.statusPromise.set(.single(nil))
|
||||
self.videoNode = nil
|
||||
if self.delayCentralityLose {
|
||||
@ -262,10 +267,76 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.playbackStatusDisposable.dispose()
|
||||
self.statusDisposable.dispose()
|
||||
self.playbackStartDisposable.dispose()
|
||||
self.preloadDisposable.dispose()
|
||||
}
|
||||
|
||||
private func updateStatus() {
|
||||
guard let videoContent = self.videoContent, let fetchStatus = self.fetchStatus else {
|
||||
return
|
||||
}
|
||||
|
||||
var isBuffering: Bool?
|
||||
var isPlaying = false
|
||||
if isMediaStreamable(resource: videoContent.fileReference.media.resource) {
|
||||
if let playerStatus = self.playerStatus {
|
||||
if case .buffering = playerStatus.status {
|
||||
isBuffering = true
|
||||
} else if case .playing = playerStatus.status {
|
||||
isPlaying = true
|
||||
}
|
||||
} else {
|
||||
isBuffering = false
|
||||
}
|
||||
}
|
||||
|
||||
var progressRequired = false
|
||||
if case .Local = fetchStatus {
|
||||
} else if isBuffering ?? false {
|
||||
progressRequired = true
|
||||
} else if case .Fetching = fetchStatus, !isPlaying {
|
||||
progressRequired = true
|
||||
} else if case .Remote = fetchStatus, !isPlaying {
|
||||
progressRequired = true
|
||||
}
|
||||
|
||||
if progressRequired {
|
||||
if self.statusNode == nil {
|
||||
let statusNode = RadialStatusNode(backgroundNodeColor: UIColor(rgb: 0x000000, alpha: 0.3))
|
||||
statusNode.isUserInteractionEnabled = false
|
||||
statusNode.frame = CGRect(origin: CGPoint(x: floor((self.frame.size.width - 50.0) / 2.0), y: floor((self.frame.size.height - 50.0) / 2.0)), size: CGSize(width: 50.0, height: 50.0))
|
||||
self.statusNode = statusNode
|
||||
self.addSubnode(statusNode)
|
||||
}
|
||||
} else {
|
||||
if let statusNode = self.statusNode {
|
||||
statusNode.transitionToState(.none, completion: { [weak statusNode] in
|
||||
statusNode?.removeFromSupernode()
|
||||
})
|
||||
self.statusNode = nil
|
||||
}
|
||||
}
|
||||
|
||||
var state: RadialStatusNodeState
|
||||
if progressRequired {
|
||||
state = .progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false)
|
||||
} else {
|
||||
state = .none
|
||||
}
|
||||
|
||||
if let statusNode = self.statusNode {
|
||||
if state == .none {
|
||||
self.statusNode = nil
|
||||
}
|
||||
statusNode.transitionToState(state, completion: { [weak statusNode] in
|
||||
if state == .none {
|
||||
statusNode?.removeFromSupernode()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func updateTransitionFraction(_ fraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
if let videoNode = self.videoNode {
|
||||
if case .immediate = transition, fraction == 1.0 {
|
||||
@ -287,7 +358,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
videoNode.isHidden = true
|
||||
|
||||
if let _ = self.videoStartTimestamp {
|
||||
self.playbackStatusDisposable.set((videoNode.status
|
||||
self.playbackStartDisposable.set((videoNode.status
|
||||
|> map { status -> Bool in
|
||||
if let status = status, case .playing = status.status {
|
||||
return true
|
||||
@ -307,7 +378,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
self.playbackStatusDisposable.set(nil)
|
||||
self.playbackStartDisposable.set(nil)
|
||||
videoNode.isHidden = false
|
||||
}
|
||||
videoNode.play()
|
||||
@ -316,6 +387,17 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
let videoStartTimestamp = self.videoStartTimestamp
|
||||
self.statusPromise.set(videoNode.status |> map { ($0, videoStartTimestamp) })
|
||||
|
||||
self.statusDisposable.set((combineLatest(self.mediaStatus, self.context.account.postbox.mediaBox.resourceStatus(videoContent.fileReference.media.resource))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] mediaStatus, fetchStatus in
|
||||
if let strongSelf = self {
|
||||
if let mediaStatusAndStartTimestamp = mediaStatus {
|
||||
strongSelf.playerStatus = mediaStatusAndStartTimestamp.0
|
||||
}
|
||||
strongSelf.fetchStatus = fetchStatus
|
||||
strongSelf.updateStatus()
|
||||
}
|
||||
}))
|
||||
|
||||
self.addSubnode(videoNode)
|
||||
|
||||
self.isReady.set(videoNode.ready |> map { return true })
|
||||
@ -369,6 +451,8 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
|
||||
self.statusPromise.set(.single(nil))
|
||||
|
||||
self.statusDisposable.set(nil)
|
||||
|
||||
self.imageNode.imageUpdated = { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -1186,7 +1270,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
private var isFirstAvatarLoading = true
|
||||
var item: PeerInfoAvatarListItem?
|
||||
|
||||
private let playbackStatusDisposable = MetaDisposable()
|
||||
private let playbackStartDisposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext) {
|
||||
self.context = context
|
||||
@ -1202,7 +1286,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.playbackStatusDisposable.dispose()
|
||||
self.playbackStartDisposable.dispose()
|
||||
}
|
||||
|
||||
@objc private func tapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
@ -1289,7 +1373,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
|
||||
if let startTimestamp = video.representation.startTimestamp {
|
||||
self.videoStartTimestamp = startTimestamp
|
||||
self.playbackStatusDisposable.set((videoNode.status
|
||||
self.playbackStartDisposable.set((videoNode.status
|
||||
|> map { status -> Bool in
|
||||
if let status = status, case .playing = status.status {
|
||||
return true
|
||||
@ -1310,7 +1394,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
}))
|
||||
} else {
|
||||
self.videoStartTimestamp = nil
|
||||
self.playbackStatusDisposable.set(nil)
|
||||
self.playbackStartDisposable.set(nil)
|
||||
videoNode.isHidden = false
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user