Last active
April 18, 2020 05:36
-
-
Save leechanwoo/9e6485bb5336af9c0666b24b20a7093a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import AVFoundation | |
import SwiftUI | |
// Image Extraction | |
protocol FrameExtractorDelegate: class { | |
func captured(image: UIImage) | |
} | |
struct ContentView: View { | |
var body: some View { | |
VStack { | |
DemoVideoStreaming() | |
//Text("Hello, World!") | |
Button(action: { | |
Wrapper().test_wrapper() | |
}) { | |
Text("C++ invoke test") | |
} | |
} | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} | |
// For camera streaming | |
struct DemoVideoStreaming: View { | |
var body: some View { | |
VStack { | |
PreviewHolder() | |
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center) | |
} | |
} | |
struct PreviewHolder: UIViewRepresentable { | |
func makeUIView(context: UIViewRepresentableContext<PreviewHolder>) -> PreviewView { | |
PreviewView() | |
} | |
func updateUIView(_ uiView: PreviewView, context: UIViewRepresentableContext<PreviewHolder>) { | |
} | |
typealias UIViewType = PreviewView | |
} | |
class PreviewView: UIView, AVCaptureVideoDataOutputSampleBufferDelegate { | |
private var captureSession: AVCaptureSession? | |
private let position = AVCaptureDevice.Position.front | |
init() { | |
super.init(frame: .zero) | |
var allowedAccess = false | |
let blocker = DispatchGroup() | |
blocker.enter() | |
AVCaptureDevice.requestAccess(for: .video) { flag in | |
allowedAccess = flag | |
blocker.leave() | |
} | |
blocker.wait() | |
if !allowedAccess { | |
print("!!! NO ACCESS TO CAMERA") | |
return | |
} | |
// setup session | |
// Step 3. AVCaptureSession | |
let session = AVCaptureSession() | |
session.beginConfiguration() | |
let videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, | |
for : .video, position: .front) //alternate AVCaptureDevice.default(for: .video) | |
guard videoDevice != nil, let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice!), session.canAddInput(videoDeviceInput) else { | |
print("!!! NO CAMERA DETECTED") | |
return | |
} | |
session.addInput(videoDeviceInput) | |
let videoOutput = AVCaptureVideoDataOutput() | |
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "sample buffer")) | |
guard session.canAddOutput(videoOutput) else { return } | |
session.addOutput(videoOutput) | |
guard let connection = videoOutput.connection(with: AVFoundation.AVMediaType.video) else { return } | |
guard connection.isVideoOrientationSupported else { return } | |
guard connection.isVideoMirroringSupported else { return } | |
connection.videoOrientation = .portrait | |
connection.isVideoMirrored = position == .front | |
session.commitConfiguration() | |
self.captureSession = session | |
} | |
override class var layerClass: AnyClass { | |
AVCaptureVideoPreviewLayer.self | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
var videoPreviewLayer: AVCaptureVideoPreviewLayer { | |
return layer as! AVCaptureVideoPreviewLayer | |
} | |
// wrapping dispatch | |
override func didMoveToSuperview() { | |
super.didMoveToSuperview() | |
if nil != self.superview { | |
self.videoPreviewLayer.session = self.captureSession | |
self.videoPreviewLayer.videoGravity = .resizeAspect | |
self.captureSession?.startRunning() | |
} else { | |
self.captureSession?.stopRunning() | |
} | |
} | |
// MARK: AVCaptureVideoDataOutputSampleBufferDelegate | |
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { | |
print("Got a frame!!") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment