implement screen rotation for video calls

pull/560/head
Ryan Zhao 3 years ago
parent 795a541805
commit 782dd20ddd

@ -153,6 +153,7 @@
7BA68909272A27BE00EFC32F /* SessionCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA68908272A27BE00EFC32F /* SessionCall.swift */; };
7BA6890D27325CCC00EFC32F /* SessionCallManager+CXCallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA6890C27325CCC00EFC32F /* SessionCallManager+CXCallController.swift */; };
7BA6890F27325CE300EFC32F /* SessionCallManager+CXProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA6890E27325CE300EFC32F /* SessionCallManager+CXProvider.swift */; };
7BAADFCC27B0EF23007BCF92 /* RemoteVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAADFCB27B0EF23007BCF92 /* RemoteVideoView.swift */; };
7BAF54CE27ACCEEC003D12F8 /* Storage+RecentSearchResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54CB27ACCEEC003D12F8 /* Storage+RecentSearchResults.swift */; };
7BAF54CF27ACCEEC003D12F8 /* GlobalSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54CC27ACCEEC003D12F8 /* GlobalSearchViewController.swift */; };
7BAF54D027ACCEEC003D12F8 /* EmptySearchResultCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF54CD27ACCEEC003D12F8 /* EmptySearchResultCell.swift */; };
@ -1161,6 +1162,7 @@
7BA68908272A27BE00EFC32F /* SessionCall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionCall.swift; sourceTree = "<group>"; };
7BA6890C27325CCC00EFC32F /* SessionCallManager+CXCallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCallManager+CXCallController.swift"; sourceTree = "<group>"; };
7BA6890E27325CE300EFC32F /* SessionCallManager+CXProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionCallManager+CXProvider.swift"; sourceTree = "<group>"; };
7BAADFCB27B0EF23007BCF92 /* RemoteVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteVideoView.swift; sourceTree = "<group>"; };
7BAF54CB27ACCEEC003D12F8 /* Storage+RecentSearchResults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Storage+RecentSearchResults.swift"; sourceTree = "<group>"; };
7BAF54CC27ACCEEC003D12F8 /* GlobalSearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalSearchViewController.swift; sourceTree = "<group>"; };
7BAF54CD27ACCEEC003D12F8 /* EmptySearchResultCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptySearchResultCell.swift; sourceTree = "<group>"; };
@ -2111,6 +2113,7 @@
7B7CB18F270FB2150079FF93 /* MiniCallView.swift */,
7B1581E727210ECC00848B49 /* RenderView.swift */,
7B0EFDF52755CC5400FFAAE7 /* CallMissedTipsModal.swift */,
7BAADFCB27B0EF23007BCF92 /* RemoteVideoView.swift */,
);
path = "Views & Modals";
sourceTree = "<group>";
@ -5039,6 +5042,7 @@
45F32C222057297A00A300D5 /* MediaDetailViewController.m in Sources */,
B82149C125D605C6009C0F2A /* InfoBanner.swift in Sources */,
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */,
7BAADFCC27B0EF23007BCF92 /* RemoteVideoView.swift in Sources */,
B8CCF63F23975CFB0091D419 /* JoinOpenGroupVC.swift in Sources */,
34ABC0E421DD20C500ED9469 /* ConversationMessageMapping.swift in Sources */,
B85357C323A1BD1200AAF6CD /* SeedVC.swift in Sources */,

@ -7,7 +7,15 @@ extension CallVC : CameraManagerDelegate {
let rtcPixelBuffer = RTCCVPixelBuffer(pixelBuffer: pixelBuffer)
let timestamp = CMTimeGetSeconds(CMSampleBufferGetPresentationTimeStamp(sampleBuffer))
let timestampNs = Int64(timestamp * 1000000000)
let frame = RTCVideoFrame(buffer: rtcPixelBuffer, rotation: RTCVideoRotation._0, timeStampNs: timestampNs)
let rotation: RTCVideoRotation = {
switch UIDevice.current.orientation {
case .landscapeRight: return RTCVideoRotation._90
case .portraitUpsideDown: return RTCVideoRotation._180
case .landscapeLeft: return RTCVideoRotation._270
default: return RTCVideoRotation._0
}
}()
let frame = RTCVideoFrame(buffer: rtcPixelBuffer, rotation: rotation, timeStampNs: timestampNs)
frame.timeStamp = Int32(timestamp)
call.webRTCSession.handleLocalFrameCaptured(frame)
}

@ -23,17 +23,19 @@ final class CallVC : UIViewController, VideoPreviewDelegate {
private lazy var localVideoView: RTCMTLVideoView = {
let result = RTCMTLVideoView()
result.isHidden = !call.isVideoEnabled
result.contentMode = .scaleAspectFill
result.videoContentMode = .scaleAspectFit
result.rotationOverride = NSNumber(value: RTCVideoRotation._0.rawValue)
result.set(.width, to: 80)
result.set(.height, to: 173)
result.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture)))
return result
}()
private lazy var remoteVideoView: RTCMTLVideoView = {
let result = RTCMTLVideoView()
private lazy var remoteVideoView: RemoteVideoView = {
let result = RemoteVideoView()
result.alpha = 0
result.contentMode = .scaleAspectFill
result.videoContentMode = .scaleAspectFit
result.backgroundColor = .black
result.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleRemoteVieioViewTapped)))
return result
}()

@ -4,9 +4,10 @@ import WebRTC
final class MiniCallView: UIView {
var callVC: CallVC
private lazy var remoteVideoView: RTCMTLVideoView = {
let result = RTCMTLVideoView()
result.contentMode = .scaleAspectFill
private lazy var remoteVideoView: RemoteVideoView = {
let result = RemoteVideoView()
result.videoContentMode = .scaleAspectFit
result.backgroundColor = .black
return result
}()
@ -31,8 +32,8 @@ final class MiniCallView: UIView {
}
private func setUpViewHierarchy() {
self.set(.width, to: 80)
self.set(.height, to: 173)
self.set(.width, to: 160)
self.set(.height, to: 160)
self.layer.masksToBounds = true
// Background
let background = getBackgroudView()

@ -0,0 +1,40 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import WebRTC
import Foundation
class RemoteVideoView: RTCMTLVideoView {
override func renderFrame(_ frame: RTCVideoFrame?) {
super.renderFrame(frame)
guard let frame = frame else { return }
DispatchMainThreadSafe {
let frameRotation = frame.rotation
let deviceRotation = UIDevice.current.orientation
switch deviceRotation {
case .portrait, .portraitUpsideDown:
// We don't have to do anything, the renderer will automatically make sure it's right-side-up.
self.rotationOverride = nil
case .landscapeLeft:
switch frameRotation {
case RTCVideoRotation._0: self.rotationOverride = NSNumber(value: RTCVideoRotation._90.rawValue) // Landscape left
case RTCVideoRotation._90: self.rotationOverride = NSNumber(value: RTCVideoRotation._180.rawValue) // Portrait
case RTCVideoRotation._180: self.rotationOverride = NSNumber(value: RTCVideoRotation._270.rawValue) // Landscape right
case RTCVideoRotation._270: self.rotationOverride = NSNumber(value: RTCVideoRotation._0.rawValue) // Portrait upside-down
default: self.rotationOverride = nil
}
case .landscapeRight:
switch frameRotation {
case RTCVideoRotation._0: self.rotationOverride = NSNumber(value: RTCVideoRotation._270.rawValue) // Landscape left
case RTCVideoRotation._90: self.rotationOverride = NSNumber(value: RTCVideoRotation._0.rawValue) // Portrait
case RTCVideoRotation._180: self.rotationOverride = NSNumber(value: RTCVideoRotation._90.rawValue) // Landscape right
case RTCVideoRotation._270: self.rotationOverride = NSNumber(value: RTCVideoRotation._180.rawValue) // Portrait upside-down
default: self.rotationOverride = nil
}
default:
// Do nothing if we're face down, up, etc.
// Assume we're already setup for the correct orientation.
break
}
}
}
}
Loading…
Cancel
Save