1
0
mirror of git://jb55.com/damus synced 2024-09-30 00:40:45 +00:00

camera: add CameraPreview for displaying the view the camera is reading

This commit is contained in:
Suhail Saqan 2023-09-19 13:35:52 -07:00 committed by William Casarin
parent 88b3c6fe8d
commit 8a2e87718b
2 changed files with 107 additions and 0 deletions

View File

@ -383,6 +383,7 @@
501F8C822A0224EB001AFC1D /* KeychainStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501F8C812A0224EB001AFC1D /* KeychainStorageTests.swift */; };
504323A72A34915F006AE6DC /* RelayModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504323A62A34915F006AE6DC /* RelayModel.swift */; };
504323A92A3495B6006AE6DC /* RelayModelCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504323A82A3495B6006AE6DC /* RelayModelCache.swift */; };
BA3759972ABCCF360018D73B /* CameraPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA3759962ABCCF360018D73B /* CameraPreview.swift */; };
5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5053ACA62A56DF3B00851AE3 /* DeveloperSettingsView.swift */; };
50A16FFB2AA6C06600DFEC1F /* AVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFA2AA6C06600DFEC1F /* AVPlayerView.swift */; };
50A16FFD2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */; };
@ -940,6 +941,7 @@
4CA352A92A76BF3A003BB08B /* LocalNotificationNotify.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationNotify.swift; sourceTree = "<group>"; };
4CA352AB2A76C07F003BB08B /* NewUnmutesNotify.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewUnmutesNotify.swift; sourceTree = "<group>"; };
4CA352AD2A76C1AC003BB08B /* FollowedNotify.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedNotify.swift; sourceTree = "<group>"; };
BA3759962ABCCF360018D73B /* CameraPreview.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraPreview.swift; sourceTree = "<group>"; };
4CA3FA0F29F593D000FDB3C3 /* ZapTypePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZapTypePicker.swift; sourceTree = "<group>"; };
4CA5588229F33F5B00DC6A45 /* StringCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringCodable.swift; sourceTree = "<group>"; };
4CA9275C2A28FF630098A105 /* LongformView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongformView.swift; sourceTree = "<group>"; };
@ -1623,6 +1625,7 @@
4C75EFA227FA576C0006080F /* Views */ = {
isa = PBXGroup;
children = (
BA3759952ABCCF360018D73B /* Camera */,
F71694E82A66221E001F4053 /* Onboarding */,
4C190F232A547D1700027FD5 /* NostrScript */,
4C7D09692A0AEA0400943473 /* CodeScanner */,
@ -2268,6 +2271,14 @@
path = Camera;
sourceTree = "<group>";
};
BA3759952ABCCF360018D73B /* Camera */ = {
isa = PBXGroup;
children = (
BA3759962ABCCF360018D73B /* CameraPreview.swift */,
);
path = Camera;
sourceTree = "<group>";
};
F71694E82A66221E001F4053 /* Onboarding */ = {
isa = PBXGroup;
children = (
@ -2610,6 +2621,7 @@
4C32B9582A9AD44700DC3548 /* VeriferOptions.swift in Sources */,
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
4C30AC7629A5770900E2BD5A /* NotificationItemView.swift in Sources */,
BA3759972ABCCF360018D73B /* CameraPreview.swift in Sources */,
4C86F7C42A76C44C00EC0817 /* ZappingNotify.swift in Sources */,
4C363A8428233689006E126D /* Parser.swift in Sources */,
3AAA95CA298DF87B00F3D526 /* TranslationService.swift in Sources */,

View File

@ -0,0 +1,95 @@
//
// CameraPreview.swift
// damus
//
// Created by Suhail Saqan on 8/5/23.
//
import UIKit
import AVFoundation
import SwiftUI
public struct CameraPreview: UIViewRepresentable {
public class VideoPreviewView: UIView {
public override class var layerClass: AnyClass {
AVCaptureVideoPreviewLayer.self
}
var videoPreviewLayer: AVCaptureVideoPreviewLayer {
return layer as! AVCaptureVideoPreviewLayer
}
let focusView: UIView = {
let focusView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
focusView.layer.borderColor = UIColor.white.cgColor
focusView.layer.borderWidth = 1.5
focusView.layer.cornerRadius = 15
focusView.layer.opacity = 0
focusView.backgroundColor = .clear
return focusView
}()
@objc func focusAndExposeTap(gestureRecognizer: UITapGestureRecognizer) {
let layerPoint = gestureRecognizer.location(in: gestureRecognizer.view)
guard layerPoint.x >= 0 && layerPoint.x <= bounds.width &&
layerPoint.y >= 0 && layerPoint.y <= bounds.height else {
return
}
let devicePoint = videoPreviewLayer.captureDevicePointConverted(fromLayerPoint: layerPoint)
self.focusView.layer.frame = CGRect(origin: layerPoint, size: CGSize(width: 30, height: 30))
NotificationCenter.default.post(.init(name: .init("UserDidRequestNewFocusPoint"), object: nil, userInfo: ["devicePoint": devicePoint] as [AnyHashable: Any]))
UIView.animate(withDuration: 0.3, animations: {
self.focusView.layer.opacity = 1
}) { (completed) in
if completed {
UIView.animate(withDuration: 0.3) {
self.focusView.layer.opacity = 0
}
}
}
}
public override func layoutSubviews() {
super.layoutSubviews()
videoPreviewLayer.videoGravity = .resizeAspectFill
self.layer.addSublayer(focusView.layer)
let gRecognizer = UITapGestureRecognizer(target: self, action: #selector(VideoPreviewView.focusAndExposeTap(gestureRecognizer:)))
self.addGestureRecognizer(gRecognizer)
}
}
public let session: AVCaptureSession
public init(session: AVCaptureSession) {
self.session = session
}
public func makeUIView(context: Context) -> VideoPreviewView {
let viewFinder = VideoPreviewView()
viewFinder.backgroundColor = .black
viewFinder.videoPreviewLayer.cornerRadius = 20
viewFinder.videoPreviewLayer.session = session
viewFinder.videoPreviewLayer.connection?.videoOrientation = .portrait
return viewFinder
}
public func updateUIView(_ uiView: VideoPreviewView, context: Context) {
}
}
struct CameraPreview_Previews: PreviewProvider {
static var previews: some View {
CameraPreview(session: AVCaptureSession())
.frame(height: 300)
}
}