Video playback improvements

This commit is contained in:
Isaac 2024-10-25 13:36:04 +02:00
parent 1fbc06611a
commit 3990889211
11 changed files with 79 additions and 6 deletions

View file

@ -44,6 +44,7 @@ public protocol UniversalVideoContentNode: AnyObject {
func setCanPlaybackWithoutHierarchy(_ canPlaybackWithoutHierarchy: Bool)
func enterNativePictureInPicture() -> Bool
func exitNativePictureInPicture()
func setNativePictureInPictureIsActive(_ value: Bool)
}
public protocol UniversalVideoContent {
@ -445,4 +446,12 @@ public final class UniversalVideoNode: ASDisplayNode {
}
})
}
public func setNativePictureInPictureIsActive(_ value: Bool) {
self.manager.withUniversalVideoContent(id: self.content.id, { contentNode in
if let contentNode = contentNode {
contentNode.setNativePictureInPictureIsActive(value)
}
})
}
}

View file

@ -957,7 +957,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, ASScroll
} else if media is TelegramMediaImage {
hasCaption = true
} else if let file = media as? TelegramMediaFile {
hasCaption = file.mimeType.hasPrefix("image/")
hasCaption = file.mimeType.hasPrefix("image/") || file.mimeType.hasPrefix("video/")
} else if media is TelegramMediaInvoice {
hasCaption = true
}

View file

@ -470,6 +470,10 @@ open class GalleryControllerNode: ASDisplayNode, ASScrollViewDelegate, ASGesture
let distanceFromEquilibrium = scrollView.contentOffset.y - scrollView.contentSize.height / 3.0
let minimalDismissDistance = scrollView.contentSize.height / 12.0
if abs(velocity.y) > 1.0 || abs(distanceFromEquilibrium) > minimalDismissDistance {
if distanceFromEquilibrium > 1.0, let centralItemNode = self.pager.centralItemNode(), centralItemNode.maybePerformActionForSwipeDismiss() {
return
}
if let backgroundColor = self.backgroundNode.backgroundColor {
self.backgroundNode.layer.animate(from: backgroundColor, to: UIColor(white: 0.0, alpha: 0.0).cgColor, keyPath: "backgroundColor", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.2, removeOnCompletion: false)
}

View file

@ -100,6 +100,10 @@ open class GalleryItemNode: ASDisplayNode {
open func animateOut(to node: (ASDisplayNode, CGRect, () -> (UIView?, UIView?)), addToTransitionSurface: (UIView) -> Void, completion: @escaping () -> Void) {
}
open func maybePerformActionForSwipeDismiss() -> Bool {
return false
}
open func contentSize() -> CGSize? {
return nil
}

View file

@ -1128,6 +1128,7 @@ private final class NativePictureInPictureContentImpl: NSObject, AVPictureInPict
private let node: UniversalVideoNode
private let willBegin: (NativePictureInPictureContentImpl) -> Void
private let didBegin: (NativePictureInPictureContentImpl) -> Void
private let didEnd: (NativePictureInPictureContentImpl) -> Void
private let expand: (@escaping () -> Void) -> Void
private var pictureInPictureTimer: SwiftSignalKit.Timer?
private var didExpand: Bool = false
@ -1138,7 +1139,7 @@ private final class NativePictureInPictureContentImpl: NSObject, AVPictureInPict
private var isNativePictureInPictureActiveDisposable: Disposable?
init(context: AccountContext, mediaManager: MediaManager, accountId: AccountRecordId, hiddenMedia: (MessageId, Media)?, videoNode: UniversalVideoNode, canSkip: Bool, willBegin: @escaping (NativePictureInPictureContentImpl) -> Void, didBegin: @escaping (NativePictureInPictureContentImpl) -> Void, expand: @escaping (@escaping () -> Void) -> Void) {
init(context: AccountContext, mediaManager: MediaManager, accountId: AccountRecordId, hiddenMedia: (MessageId, Media)?, videoNode: UniversalVideoNode, canSkip: Bool, willBegin: @escaping (NativePictureInPictureContentImpl) -> Void, didBegin: @escaping (NativePictureInPictureContentImpl) -> Void, didEnd: @escaping (NativePictureInPictureContentImpl) -> Void, expand: @escaping (@escaping () -> Void) -> Void) {
self.context = context
self.mediaManager = mediaManager
self.accountId = accountId
@ -1146,6 +1147,7 @@ private final class NativePictureInPictureContentImpl: NSObject, AVPictureInPict
self.node = videoNode
self.willBegin = willBegin
self.didBegin = didBegin
self.didEnd = didEnd
self.expand = expand
super.init()
@ -1255,6 +1257,7 @@ private final class NativePictureInPictureContentImpl: NSObject, AVPictureInPict
mediaManager.galleryHiddenMediaManager.removeSource(hiddenMediaManagerIndex)
self.hiddenMediaManagerIndex = nil
}
self.didEnd(self)
}
public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
@ -1683,8 +1686,6 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
isAdaptive = true
}
//TODO:release
//self.settingsBarButton.setContent(.image(generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/NavigationSettingsQAuto"), color: .white)))
let _ = isAdaptive
let dimensions = item.content.dimensions
@ -2701,6 +2702,20 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
})
}
override func maybePerformActionForSwipeDismiss() -> Bool {
if let data = self.context.currentAppConfiguration.with({ $0 }).data, let _ = data["ios_killswitch_disable_swipe_pip"] {
return false
}
if #available(iOS 15.0, *) {
if let nativePictureInPictureContent = self.nativePictureInPictureContent as? NativePictureInPictureContentImpl {
nativePictureInPictureContent.beginPictureInPicture()
return true
}
}
return false
}
override func title() -> Signal<String, NoError> {
return self._title.get()
}
@ -2874,6 +2889,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
if #available(iOS 15.0, *) {
var didExpand = false
let content = NativePictureInPictureContentImpl(context: self.context, mediaManager: self.context.sharedContext.mediaManager, accountId: self.context.account.id, hiddenMedia: hiddenMedia, videoNode: videoNode, canSkip: true, willBegin: { [weak self] content in
guard let self, let controller = self.galleryController(), let navigationController = self.baseNavigationController() else {
return
@ -2885,12 +2901,30 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
controller.view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { [weak self] _ in
self?.completeCustomDismiss(true)
})
if let videoNode = self.videoNode {
videoNode.setNativePictureInPictureIsActive(false)
}
didExpand = false
}, didBegin: { [weak self] _ in
guard let self else {
return
}
let _ = self
}, didEnd: { [weak self] _ in
guard let self else {
return
}
if let videoNode = self.videoNode {
videoNode.setNativePictureInPictureIsActive(false)
}
if !didExpand {
self.activePictureInPictureController = nil
self.activePictureInPictureNavigationController = nil
}
}, expand: { [weak self] completion in
didExpand = true
guard let self, let activePictureInPictureController = self.activePictureInPictureController, let activePictureInPictureNavigationController = self.activePictureInPictureNavigationController else {
completion()
return
@ -2904,9 +2938,10 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
})
activePictureInPictureController.view.alpha = 1.0
activePictureInPictureController.view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2, completion: { _ in
completion()
activePictureInPictureController.view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.35, completion: { _ in
})
completion()
})
self.nativePictureInPictureContent = content

View file

@ -1600,6 +1600,7 @@ final class HLSVideoJSNativeContentNode: ASDisplayNode, UniversalVideoContentNod
}
func setCanPlaybackWithoutHierarchy(_ canPlaybackWithoutHierarchy: Bool) {
self.playerNode.setCanPlaybackWithoutHierarchy(canPlaybackWithoutHierarchy)
}
func enterNativePictureInPicture() -> Bool {
@ -1608,6 +1609,10 @@ final class HLSVideoJSNativeContentNode: ASDisplayNode, UniversalVideoContentNod
func exitNativePictureInPicture() {
}
func setNativePictureInPictureIsActive(_ value: Bool) {
self.imageNode.isHidden = !value
}
}
private func serializeRanges(_ ranges: RangeSet<Double>) -> [Double] {

View file

@ -716,4 +716,8 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent
func exitNativePictureInPicture() {
}
func setNativePictureInPictureIsActive(_ value: Bool) {
self.imageNode.isHidden = value
}
}

View file

@ -482,4 +482,7 @@ private final class PlatformVideoContentNode: ASDisplayNode, UniversalVideoConte
func exitNativePictureInPicture() {
}
func setNativePictureInPictureIsActive(_ value: Bool) {
}
}

View file

@ -319,5 +319,8 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
func exitNativePictureInPicture() {
}
func setNativePictureInPictureIsActive(_ value: Bool) {
}
}

View file

@ -234,4 +234,7 @@ final class WebEmbedPlayerNode: ASDisplayNode, WKNavigationDelegate {
func exitNativePictureInPicture() {
}
func setNativePictureInPictureIsActive(_ value: Bool) {
}
}

View file

@ -218,4 +218,7 @@ final class WebEmbedVideoContentNode: ASDisplayNode, UniversalVideoContentNode {
func exitNativePictureInPicture() {
}
func setNativePictureInPictureIsActive(_ value: Bool) {
}
}