From b4c706b9a179c9951b72af612f3cfa6263455373 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 23 Mar 2023 19:50:46 +0400 Subject: [PATCH] Remove some unnecessary main thread load when playing video messages --- .../ContainedViewLayoutTransition.swift | 8 ++- ...MessageInstantVideoBubbleContentNode.swift | 6 -- ...atMessageInteractiveInstantVideoNode.swift | 6 +- .../Sources/PeerMessagesMediaPlaylist.swift | 58 ++++++++++--------- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/submodules/Display/Source/ContainedViewLayoutTransition.swift b/submodules/Display/Source/ContainedViewLayoutTransition.swift index ccd8868e4d..5686e645fb 100644 --- a/submodules/Display/Source/ContainedViewLayoutTransition.swift +++ b/submodules/Display/Source/ContainedViewLayoutTransition.swift @@ -1860,6 +1860,10 @@ final class ControlledTransitionProperty { let toValue: AnyValue private let completion: ((Bool) -> Void)? + private lazy var animationKey: String = { + return "MyCustomAnimation_\(Unmanaged.passUnretained(self).toOpaque())" + }() + init(layer: CALayer, path: String, fromValue: T, toValue: T, completion: ((Bool) -> Void)?) where T: AnyValueProviding { self.layer = layer self.path = path @@ -1871,7 +1875,7 @@ final class ControlledTransitionProperty { } deinit { - self.layer.removeAnimation(forKey: "MyCustomAnimation_\(Unmanaged.passUnretained(self).toOpaque())") + self.layer.removeAnimation(forKey: self.animationKey) } func update(at fraction: CGFloat) { @@ -1887,7 +1891,7 @@ final class ControlledTransitionProperty { animation.toValue = value.nsValue animation.timingFunction = CAMediaTimingFunction(name: .linear) animation.isRemovedOnCompletion = false - self.layer.add(animation, forKey: "MyCustomAnimation_\(Unmanaged.passUnretained(self).toOpaque())") + self.layer.add(animation, forKey: self.animationKey) } func complete(atEnd: Bool) { diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift index 3fdc0070e2..6e8a97de99 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoBubbleContentNode.swift @@ -70,7 +70,6 @@ class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode { self.maskForeground.masksToBounds = true self.maskLayer.addSublayer(self.maskForeground) - self.addSubnode(self.interactiveFileNode) self.addSubnode(self.interactiveVideoNode) self.interactiveVideoNode.requestUpdateLayout = { [weak self] _ in @@ -285,14 +284,9 @@ class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode { return (finalSize, { [weak self] animation, synchronousLoads, applyInfo in if let strongSelf = self { - let firstTime = strongSelf.item == nil strongSelf.item = item strongSelf.isExpanded = isExpanded - if firstTime { - strongSelf.interactiveFileNode.isHidden = true - } - strongSelf.bubbleBackgroundNode?.layer.mask = strongSelf.maskLayer if let bubbleBackdropNode = strongSelf.bubbleBackdropNode, bubbleBackdropNode.hasImage && strongSelf.backdropMaskForeground.superlayer == nil { strongSelf.bubbleBackdropNode?.overrideMask = true diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index afb9e176de..2beb1ff859 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -1601,7 +1601,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { let duration: Double = 0.2 node.alpha = 1.0 - node.isHidden = false + if node.supernode == nil { + self.supernode?.insertSubnode(node, belowSubnode: self) + } self.alpha = 0.0 self.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration) @@ -1715,7 +1717,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { node.alpha = 0.0 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) diff --git a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift index 8cc15ce477..ae8af31130 100644 --- a/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift +++ b/submodules/TelegramUI/Sources/PeerMessagesMediaPlaylist.swift @@ -60,7 +60,7 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem { return MessageMediaPlaylistItemStableId(stableId: message.stableId) } - var playbackData: SharedMediaPlaybackData? { + lazy var playbackData: SharedMediaPlaybackData? = { if let file = extractFileMedia(self.message) { let fileReference = FileMediaReference.message(message: MessageReference(self.message), media: file) let source = SharedMediaPlaybackDataSource.telegramFile(reference: fileReference, isCopyProtected: self.message.isCopyProtected()) @@ -93,9 +93,9 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem { } } return nil - } + }() - var displayData: SharedMediaPlaybackDisplayData? { + lazy var displayData: SharedMediaPlaybackDisplayData? = { if let file = extractFileMedia(self.message) { let text = self.message.text var entities: [MessageTextEntity] = [] @@ -108,40 +108,42 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem { for attribute in file.attributes { switch attribute { - case let .Audio(isVoice, duration, title, performer, _): - if isVoice { - return SharedMediaPlaybackDisplayData.voice(author: self.message.effectiveAuthor, peer: self.message.peers[self.message.id.peerId]) - } else { - var updatedTitle = title - let updatedPerformer = performer - 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 .Audio(isVoice, duration, title, performer, _): + let displayData: SharedMediaPlaybackDisplayData + if isVoice { + displayData = SharedMediaPlaybackDisplayData.voice(author: self.message.effectiveAuthor, peer: self.message.peers[self.message.id.peerId]) + } else { + var updatedTitle = title + let updatedPerformer = performer + if (title ?? "").isEmpty && (performer ?? "").isEmpty { + updatedTitle = file.fileName ?? "" } - 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) + + let albumArt: SharedMediaPlaybackAlbumArt? + if file.fileName?.lowercased().hasSuffix(".ogg") == true { + albumArt = nil } 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 nil - } + }() } private enum NavigatedMessageFromViewPosition {