mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.6 KiB
Swift
118 lines
3.6 KiB
Swift
//
|
|
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
class LocalVideoView: UIView {
|
|
private let localVideoCapturePreview = RTCCameraPreviewView()
|
|
|
|
var captureSession: AVCaptureSession? {
|
|
set { localVideoCapturePreview.captureSession = newValue }
|
|
get { localVideoCapturePreview.captureSession }
|
|
}
|
|
|
|
override var contentMode: UIView.ContentMode {
|
|
didSet { localVideoCapturePreview.contentMode = contentMode }
|
|
}
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: .zero)
|
|
|
|
addSubview(localVideoCapturePreview)
|
|
|
|
if Platform.isSimulator {
|
|
backgroundColor = .green
|
|
}
|
|
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(updateLocalVideoOrientation),
|
|
name: UIDevice.orientationDidChangeNotification,
|
|
object: nil
|
|
)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override var frame: CGRect {
|
|
didSet { updateLocalVideoOrientation() }
|
|
}
|
|
|
|
@objc
|
|
func updateLocalVideoOrientation() {
|
|
defer { localVideoCapturePreview.frame = bounds }
|
|
|
|
// iPad supports rotating this view controller directly,
|
|
// so we don't need to do anything here.
|
|
guard !UIDevice.current.isIPad else { return }
|
|
|
|
// We lock this view to portrait only on phones, but the
|
|
// local video capture will rotate with the device's
|
|
// orientation (so the remote party will render your video
|
|
// in the correct orientation). As such, we need to rotate
|
|
// the local video preview layer so it *looks* like we're
|
|
// also always capturing in portrait.
|
|
|
|
switch UIDevice.current.orientation {
|
|
case .portrait:
|
|
localVideoCapturePreview.transform = .identity
|
|
case .portraitUpsideDown:
|
|
localVideoCapturePreview.transform = .init(rotationAngle: .pi)
|
|
case .landscapeLeft:
|
|
localVideoCapturePreview.transform = .init(rotationAngle: .halfPi)
|
|
case .landscapeRight:
|
|
localVideoCapturePreview.transform = .init(rotationAngle: .pi + .halfPi)
|
|
case .faceUp, .faceDown, .unknown:
|
|
break
|
|
@unknown default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
extension RTCCameraPreviewView {
|
|
var previewLayer: AVCaptureVideoPreviewLayer? {
|
|
return layer as? AVCaptureVideoPreviewLayer
|
|
}
|
|
|
|
open override var contentMode: UIView.ContentMode {
|
|
set {
|
|
guard let previewLayer = previewLayer else {
|
|
return owsFailDebug("missing preview layer")
|
|
}
|
|
|
|
switch newValue {
|
|
case .scaleAspectFill:
|
|
previewLayer.videoGravity = .resizeAspectFill
|
|
case .scaleAspectFit:
|
|
previewLayer.videoGravity = .resizeAspect
|
|
case .scaleToFill:
|
|
previewLayer.videoGravity = .resize
|
|
default:
|
|
owsFailDebug("Unexpected contentMode")
|
|
}
|
|
}
|
|
get {
|
|
guard let previewLayer = previewLayer else {
|
|
owsFailDebug("missing preview layer")
|
|
return .scaleToFill
|
|
}
|
|
|
|
switch previewLayer.videoGravity {
|
|
case .resizeAspectFill:
|
|
return .scaleAspectFill
|
|
case .resizeAspect:
|
|
return .scaleAspectFit
|
|
case .resize:
|
|
return .scaleToFill
|
|
default:
|
|
owsFailDebug("Unexpected contentMode")
|
|
return .scaleToFill
|
|
}
|
|
}
|
|
}
|
|
}
|