Video streaming improvements

This commit is contained in:
Ali 2022-02-27 01:45:31 +04:00
parent 0d424f1663
commit 87f9b5d861
4 changed files with 73 additions and 9 deletions

View File

@ -489,8 +489,12 @@ public final class MediaStreamComponent: CombinedComponent {
private(set) var displayUI: Bool = true
var dismissOffset: CGFloat = 0.0
var storedIsLandscape: Bool?
let isPictureInPictureSupported: Bool
private var scheduledDismissUITimer: SwiftSignalKit.Timer?
init(call: PresentationGroupCallImpl) {
self.call = call
@ -551,6 +555,26 @@ public final class MediaStreamComponent: CombinedComponent {
self.updated(transition: Transition(animation: .curve(duration: 0.4, curve: .easeInOut)))
}
func cancelScheduledDismissUI() {
self.scheduledDismissUITimer?.invalidate()
self.scheduledDismissUITimer = nil
}
func scheduleDismissUI() {
if self.scheduledDismissUITimer == nil {
self.scheduledDismissUITimer = SwiftSignalKit.Timer(timeout: 5.0, repeat: false, completion: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.scheduledDismissUITimer = nil
if strongSelf.displayUI {
strongSelf.toggleDisplayUI()
}
}, queue: .mainQueue())
self.scheduledDismissUITimer?.start()
}
}
func updateDismissOffset(value: CGFloat, interactive: Bool) {
self.dismissOffset = value
if interactive {
@ -575,7 +599,8 @@ public final class MediaStreamComponent: CombinedComponent {
return { context in
let environment = context.environment[ViewControllerComponentContainer.Environment.self].value
if !environment.isVisible {
if environment.isVisible {
} else {
context.state.dismissOffset = 0.0
}
@ -675,6 +700,14 @@ public final class MediaStreamComponent: CombinedComponent {
)
let isLandscape = context.availableSize.width > context.availableSize.height
if context.state.storedIsLandscape != isLandscape {
context.state.storedIsLandscape = isLandscape
if isLandscape {
context.state.scheduleDismissUI()
} else {
context.state.cancelScheduledDismissUI()
}
}
var infoItem: AnyComponent<Empty>?
if let originInfo = context.state.originInfo {
@ -815,6 +848,10 @@ public final class MediaStreamComponentController: ViewControllerComponentContai
self.onViewDidAppear?()
}
if let view = self.node.hostView.findTaggedView(tag: MediaStreamVideoComponent.View.Tag()) as? MediaStreamVideoComponent.View {
view.expandFromPictureInPicture()
}
self.view.layer.allowsGroupOpacity = true
self.view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { [weak self] _ in
guard let strongSelf = self else {

View File

@ -39,7 +39,10 @@ final class MediaStreamVideoComponent: Component {
return State()
}
public final class View: UIView, AVPictureInPictureControllerDelegate, AVPictureInPictureSampleBufferPlaybackDelegate {
public final class View: UIView, AVPictureInPictureControllerDelegate, AVPictureInPictureSampleBufferPlaybackDelegate, ComponentTaggedView {
public final class Tag {
}
private let videoRenderingContext = VideoRenderingContext()
private var videoView: VideoRenderingView?
private let blurTintView: UIView
@ -49,6 +52,7 @@ final class MediaStreamVideoComponent: Component {
private var pictureInPictureController: AVPictureInPictureController?
private var component: MediaStreamVideoComponent?
private var hadVideo: Bool = false
override init(frame: CGRect) {
self.blurTintView = UIView()
@ -66,6 +70,17 @@ final class MediaStreamVideoComponent: Component {
fatalError("init(coder:) has not been implemented")
}
public func matches(tag: Any) -> Bool {
if let _ = tag as? Tag {
return true
}
return false
}
func expandFromPictureInPicture() {
self.pictureInPictureController?.stopPictureInPicture()
}
func update(component: MediaStreamVideoComponent, availableSize: CGSize, state: State, transition: Transition) -> CGSize {
if component.hasVideo, self.videoView == nil {
if let input = component.call.video(endpointId: "unified") {
@ -80,11 +95,12 @@ final class MediaStreamVideoComponent: Component {
if #available(iOSApplicationExtension 15.0, iOS 15.0, *), AVPictureInPictureController.isPictureInPictureSupported(), let sampleBufferVideoView = videoView as? SampleBufferVideoRenderingView {
let pictureInPictureController = AVPictureInPictureController(contentSource: AVPictureInPictureController.ContentSource(sampleBufferDisplayLayer: sampleBufferVideoView.sampleBufferLayer, playbackDelegate: self))
self.pictureInPictureController = pictureInPictureController
pictureInPictureController.delegate = self
pictureInPictureController.canStartPictureInPictureAutomaticallyFromInline = true
pictureInPictureController.requiresLinearPlayback = true
pictureInPictureController.delegate = self
self.pictureInPictureController = pictureInPictureController
}
videoView.setOnOrientationUpdated { [weak state] _, _ in
@ -95,6 +111,7 @@ final class MediaStreamVideoComponent: Component {
return
}
strongSelf.hadVideo = true
strongSelf.activityIndicatorView?.removeFromSuperview()
strongSelf.activityIndicatorView = nil
@ -120,7 +137,9 @@ final class MediaStreamVideoComponent: Component {
videoBlurView.updateIsEnabled(true)
transition.withAnimation(.none).setFrame(view: videoBlurView, frame: CGRect(origin: CGPoint(x: floor((availableSize.width - blurredVideoSize.width) / 2.0), y: floor((availableSize.height - blurredVideoSize.height) / 2.0)), size: blurredVideoSize), completion: nil)
}
} else {
}
if !self.hadVideo {
var activityIndicatorTransition = transition
let activityIndicatorView: ComponentHostView<Empty>
if let current = self.activityIndicatorView {

View File

@ -78,12 +78,12 @@ open class ViewControllerComponentContainer: ViewController {
}
}
private final class Node: ViewControllerTracingNode {
final class Node: ViewControllerTracingNode {
private var presentationData: PresentationData
private weak var controller: ViewControllerComponentContainer?
private let component: AnyComponent<ViewControllerComponentContainer.Environment>
private let hostView: ComponentHostView<ViewControllerComponentContainer.Environment>
let hostView: ComponentHostView<ViewControllerComponentContainer.Environment>
private var currentIsVisible: Bool = false
private var currentLayout: ContainerViewLayout?
@ -137,7 +137,7 @@ open class ViewControllerComponentContainer: ViewController {
}
}
private var node: Node {
var node: Node {
return self.displayNode as! Node
}

View File

@ -1684,7 +1684,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.processMyAudioLevel(level: mappedLevel, hasVoice: myLevelHasVoice)
strongSelf.isSpeakingPromise.set(orignalMyLevelHasVoice)
if !missingSsrcs.isEmpty {
if !missingSsrcs.isEmpty && !strongSelf.isStream {
strongSelf.participantsContext?.ensureHaveParticipants(ssrcs: missingSsrcs)
}
}))
@ -2235,6 +2235,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
}
private func beginTone(tone: PresentationCallTone) {
if self.isStream {
switch tone {
case .groupJoined, .groupLeft:
return
default:
break
}
}
var completed: (() -> Void)?
let toneRenderer = PresentationCallToneRenderer(tone: tone, completed: {
completed?()