Remove some unnecessary main thread load when playing video messages

This commit is contained in:
Ilya Laktyushin 2023-03-23 19:50:46 +04:00
parent c8e861a3d4
commit b4c706b9a1
4 changed files with 40 additions and 38 deletions

View File

@ -1860,6 +1860,10 @@ final class ControlledTransitionProperty {
let toValue: AnyValue let toValue: AnyValue
private let completion: ((Bool) -> Void)? private let completion: ((Bool) -> Void)?
private lazy var animationKey: String = {
return "MyCustomAnimation_\(Unmanaged.passUnretained(self).toOpaque())"
}()
init<T: Equatable>(layer: CALayer, path: String, fromValue: T, toValue: T, completion: ((Bool) -> Void)?) where T: AnyValueProviding { init<T: Equatable>(layer: CALayer, path: String, fromValue: T, toValue: T, completion: ((Bool) -> Void)?) where T: AnyValueProviding {
self.layer = layer self.layer = layer
self.path = path self.path = path
@ -1871,7 +1875,7 @@ final class ControlledTransitionProperty {
} }
deinit { deinit {
self.layer.removeAnimation(forKey: "MyCustomAnimation_\(Unmanaged.passUnretained(self).toOpaque())") self.layer.removeAnimation(forKey: self.animationKey)
} }
func update(at fraction: CGFloat) { func update(at fraction: CGFloat) {
@ -1887,7 +1891,7 @@ final class ControlledTransitionProperty {
animation.toValue = value.nsValue animation.toValue = value.nsValue
animation.timingFunction = CAMediaTimingFunction(name: .linear) animation.timingFunction = CAMediaTimingFunction(name: .linear)
animation.isRemovedOnCompletion = false animation.isRemovedOnCompletion = false
self.layer.add(animation, forKey: "MyCustomAnimation_\(Unmanaged.passUnretained(self).toOpaque())") self.layer.add(animation, forKey: self.animationKey)
} }
func complete(atEnd: Bool) { func complete(atEnd: Bool) {

View File

@ -70,7 +70,6 @@ class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode {
self.maskForeground.masksToBounds = true self.maskForeground.masksToBounds = true
self.maskLayer.addSublayer(self.maskForeground) self.maskLayer.addSublayer(self.maskForeground)
self.addSubnode(self.interactiveFileNode)
self.addSubnode(self.interactiveVideoNode) self.addSubnode(self.interactiveVideoNode)
self.interactiveVideoNode.requestUpdateLayout = { [weak self] _ in self.interactiveVideoNode.requestUpdateLayout = { [weak self] _ in
@ -285,14 +284,9 @@ class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode {
return (finalSize, { [weak self] animation, synchronousLoads, applyInfo in return (finalSize, { [weak self] animation, synchronousLoads, applyInfo in
if let strongSelf = self { if let strongSelf = self {
let firstTime = strongSelf.item == nil
strongSelf.item = item strongSelf.item = item
strongSelf.isExpanded = isExpanded strongSelf.isExpanded = isExpanded
if firstTime {
strongSelf.interactiveFileNode.isHidden = true
}
strongSelf.bubbleBackgroundNode?.layer.mask = strongSelf.maskLayer strongSelf.bubbleBackgroundNode?.layer.mask = strongSelf.maskLayer
if let bubbleBackdropNode = strongSelf.bubbleBackdropNode, bubbleBackdropNode.hasImage && strongSelf.backdropMaskForeground.superlayer == nil { if let bubbleBackdropNode = strongSelf.bubbleBackdropNode, bubbleBackdropNode.hasImage && strongSelf.backdropMaskForeground.superlayer == nil {
strongSelf.bubbleBackdropNode?.overrideMask = true strongSelf.bubbleBackdropNode?.overrideMask = true

View File

@ -1601,7 +1601,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
let duration: Double = 0.2 let duration: Double = 0.2
node.alpha = 1.0 node.alpha = 1.0
node.isHidden = false if node.supernode == nil {
self.supernode?.insertSubnode(node, belowSubnode: self)
}
self.alpha = 0.0 self.alpha = 0.0
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration) self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration)
@ -1715,7 +1717,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
node.alpha = 0.0 node.alpha = 0.0
node.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, completion: { _ in node.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration, completion: { _ in
node.isHidden = true node.removeFromSupernode()
}) })
node.waveformView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration) node.waveformView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration)

View File

@ -60,7 +60,7 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem {
return MessageMediaPlaylistItemStableId(stableId: message.stableId) return MessageMediaPlaylistItemStableId(stableId: message.stableId)
} }
var playbackData: SharedMediaPlaybackData? { lazy var playbackData: SharedMediaPlaybackData? = {
if let file = extractFileMedia(self.message) { if let file = extractFileMedia(self.message) {
let fileReference = FileMediaReference.message(message: MessageReference(self.message), media: file) let fileReference = FileMediaReference.message(message: MessageReference(self.message), media: file)
let source = SharedMediaPlaybackDataSource.telegramFile(reference: fileReference, isCopyProtected: self.message.isCopyProtected()) let source = SharedMediaPlaybackDataSource.telegramFile(reference: fileReference, isCopyProtected: self.message.isCopyProtected())
@ -93,9 +93,9 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem {
} }
} }
return nil return nil
} }()
var displayData: SharedMediaPlaybackDisplayData? { lazy var displayData: SharedMediaPlaybackDisplayData? = {
if let file = extractFileMedia(self.message) { if let file = extractFileMedia(self.message) {
let text = self.message.text let text = self.message.text
var entities: [MessageTextEntity] = [] var entities: [MessageTextEntity] = []
@ -108,40 +108,42 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem {
for attribute in file.attributes { for attribute in file.attributes {
switch attribute { switch attribute {
case let .Audio(isVoice, duration, title, performer, _): case let .Audio(isVoice, duration, title, performer, _):
if isVoice { let displayData: SharedMediaPlaybackDisplayData
return SharedMediaPlaybackDisplayData.voice(author: self.message.effectiveAuthor, peer: self.message.peers[self.message.id.peerId]) if isVoice {
} else { displayData = SharedMediaPlaybackDisplayData.voice(author: self.message.effectiveAuthor, peer: self.message.peers[self.message.id.peerId])
var updatedTitle = title } else {
let updatedPerformer = performer var updatedTitle = title
if (title ?? "").isEmpty && (performer ?? "").isEmpty { let updatedPerformer = performer
updatedTitle = file.fileName ?? "" if (title ?? "").isEmpty && (performer ?? "").isEmpty {
} updatedTitle = file.fileName ?? ""
let albumArt: SharedMediaPlaybackAlbumArt?
if file.fileName?.lowercased().hasSuffix(".ogg") == true {
albumArt = nil
} else {
albumArt = SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(self.message), media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(self.message), media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: false))
}
return SharedMediaPlaybackDisplayData.music(title: updatedTitle, performer: updatedPerformer, albumArt: albumArt, long: CGFloat(duration) > 10.0 * 60.0, caption: caption)
} }
case let .Video(_, _, flags):
if flags.contains(.instantRoundVideo) { let albumArt: SharedMediaPlaybackAlbumArt?
return SharedMediaPlaybackDisplayData.instantVideo(author: self.message.effectiveAuthor, peer: self.message.peers[self.message.id.peerId], timestamp: self.message.timestamp) if file.fileName?.lowercased().hasSuffix(".ogg") == true {
albumArt = nil
} else { } else {
return nil albumArt = SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(self.message), media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(self.message), media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: false))
} }
default:
break displayData = SharedMediaPlaybackDisplayData.music(title: updatedTitle, performer: updatedPerformer, albumArt: albumArt, long: CGFloat(duration) > 10.0 * 60.0, caption: caption)
}
return displayData
case let .Video(_, _, flags):
if flags.contains(.instantRoundVideo) {
return SharedMediaPlaybackDisplayData.instantVideo(author: self.message.effectiveAuthor, peer: self.message.peers[self.message.id.peerId], timestamp: self.message.timestamp)
} else {
return nil
}
default:
break
} }
} }
return SharedMediaPlaybackDisplayData.music(title: file.fileName ?? "", performer: self.message.effectiveAuthor?.debugDisplayTitle ?? "", albumArt: nil, long: false, caption: caption) return SharedMediaPlaybackDisplayData.music(title: file.fileName ?? "", performer: self.message.effectiveAuthor?.debugDisplayTitle ?? "", albumArt: nil, long: false, caption: caption)
} }
return nil return nil
} }()
} }
private enum NavigatedMessageFromViewPosition { private enum NavigatedMessageFromViewPosition {