import SwiftUI
import UIKit
import AVFoundation
class CameraModel: NSObject, ObservableObject, AVCapturePhotoCaptureDelegate {
enum CameraDirection {
case front
case back
}
@Published var session:AVCaptureSession!
@Published var cameraDirection = AVCaptureDevice.Position.front
@Published var input: AVCaptureDeviceInput?
@Published var output = AVCapturePhotoOutput()
@Published var preview: AVCaptureVideoPreviewLayer!
override init() {
let lsession = AVCaptureSession()
preview = AVCaptureVideoPreviewLayer(session: lsession)
session = lsession
}
func Check() {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
print("authorized")
setup()
case .notDetermined:
print("not determined")
AVCaptureDevice.requestAccess(for: .video) { status in
if status {
self.setup()
}
}
default:
print("unknown")
}
}
let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes:
[.builtInTrueDepthCamera, .builtInDualCamera, .builtInWideAngleCamera],
mediaType: .video, position: .unspecified)
func bestDevice(in position: AVCaptureDevice.Position) -> AVCaptureDevice {
let devices = self.discoverySession.devices
guard !devices.isEmpty else { fatalError("Missing capture devices.")}
return devices.first(where: { device in device.position == position })!
}
private func getDevice(direction: AVCaptureDevice.Position) -> AVCaptureDevice? {
if let device = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: direction) {
return device
}
// Find the built-in Wide-Angle Camera, if it exists.
if let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: direction) {
return device
}
fatalError("Missing expected back camera device.")
//throw Error("No camera device")
}
func setup() {
do {
self.session.beginConfiguration()
let device = bestDevice(in: cameraDirection)
input = try AVCaptureDeviceInput(device: device)
if input != nil && self.session.canAddInput(input!) {
self.session.addInput(input!)
}
if self.session.canAddOutput(output) {
self.session.addOutput(output)
}
self.session.commitConfiguration()
}
catch {
print(error.localizedDescription)
}
}
}
struct CameraView: UIViewRepresentable {
@ObservedObject var camera: CameraModel
func makeUIView(context: Context) -> some UIView {
let view = UIView(frame: UIScreen.main.bounds)
camera.preview.frame = view.frame
camera.preview.videoGravity = .resizeAspectFill
view.layer.addSublayer(camera.preview)
DispatchQueue.global(qos: .background).async {
camera.session.startRunning()
}
return view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
struct MirrorView: View {
@StateObject var camera = CameraModel()
var body: some View {
ZStack {
CameraView(camera: camera)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
}
.onAppear {
camera.Check()
}
}
}
struct MirrorView_Previews: PreviewProvider {
static var previews: some View {
MirrorView()
}
}