Swiftgram/submodules/TelegramUI/Sources/OverlayInstantVideoNode.swift
2023-06-16 22:42:48 +03:00

150 lines
4.2 KiB
Swift

import Foundation
import UIKit
import AsyncDisplayKit
import SwiftSignalKit
import Display
import TelegramCore
import Postbox
import TelegramPresentationData
import UniversalMediaPlayer
import TelegramUIPreferences
import TelegramAudio
import AccountContext
final class OverlayInstantVideoNode: OverlayMediaItemNode {
private let content: UniversalVideoContent
private let videoNode: UniversalVideoNode
private let decoration: OverlayInstantVideoDecoration
private let close: () -> Void
private var validLayoutSize: CGSize?
override var group: OverlayMediaItemNodeGroup? {
return OverlayMediaItemNodeGroup(rawValue: 1)
}
override var isMinimizeable: Bool {
return false
}
var canAttachContent: Bool = true {
didSet {
self.videoNode.canAttachContent = self.canAttachContent
}
}
var status: Signal<MediaPlayerStatus?, NoError> {
return self.videoNode.status
}
var playbackEnded: (() -> Void)?
init(postbox: Postbox, audioSession: ManagedAudioSession, manager: UniversalVideoManager, content: UniversalVideoContent, close: @escaping () -> Void) {
self.close = close
self.content = content
var togglePlayPauseImpl: (() -> Void)?
let decoration = OverlayInstantVideoDecoration(tapped: {
togglePlayPauseImpl?()
})
self.videoNode = UniversalVideoNode(postbox: postbox, audioSession: audioSession, manager: manager, decoration: decoration, content: content, priority: .secondaryOverlay, snapshotContentWhenGone: true)
self.decoration = decoration
super.init()
togglePlayPauseImpl = { [weak self] in
self?.videoNode.togglePlayPause()
}
self.addSubnode(self.videoNode)
self.videoNode.ownsContentNodeUpdated = { [weak self] value in
if let strongSelf = self {
let previous = strongSelf.hasAttachedContext
strongSelf.hasAttachedContext = value
if previous != value {
strongSelf.hasAttachedContextUpdated?(value)
}
}
}
self.videoNode.playbackCompleted = { [weak self] in
self?.playbackEnded?()
}
self.videoNode.canAttachContent = true
}
override func didLoad() {
super.didLoad()
}
override func layout() {
self.updateLayout(self.bounds.size)
}
override func preferredSizeForOverlayDisplay(boundingSize: CGSize) -> CGSize {
if min(boundingSize.width, boundingSize.height) > 320.0 {
return CGSize(width: 150.0, height: 150.0)
} else {
return CGSize(width: 120.0, height: 120.0)
}
}
override func dismiss() {
self.close()
}
override func updateLayout(_ size: CGSize) {
if size != self.validLayoutSize {
self.updateLayoutImpl(size)
}
}
private func updateLayoutImpl(_ size: CGSize) {
self.validLayoutSize = size
self.videoNode.frame = CGRect(origin: CGPoint(), size: size)
self.videoNode.updateLayout(size: size, transition: .immediate)
}
func play() {
self.videoNode.play()
}
func playOnceWithSound(playAndRecord: Bool) {
self.videoNode.playOnceWithSound(playAndRecord: playAndRecord)
}
func continueWithOverridingAmbientMode() {
}
func pause() {
self.videoNode.pause()
}
func togglePlayPause() {
self.videoNode.togglePlayPause()
}
func seek(_ timestamp: Double) {
self.videoNode.seek(timestamp)
}
func setSoundEnabled(_ soundEnabled: Bool) {
if soundEnabled {
self.videoNode.playOnceWithSound(playAndRecord: true)
} else {
self.videoNode.continuePlayingWithoutSound()
self.videoNode.setBaseRate(1.0)
}
}
func setBaseRate(_ baseRate: Double) {
self.videoNode.setBaseRate(baseRate)
}
func setForceAudioToSpeaker(_ forceAudioToSpeaker: Bool) {
self.videoNode.setForceAudioToSpeaker(forceAudioToSpeaker)
}
}