Skip to content

Commit

Permalink
fixed bug in camera view controller related to force unwrap of AVCapt…
Browse files Browse the repository at this point in the history
…ureDeviceInput
  • Loading branch information
Oliver K. Ernst committed Dec 3, 2020
1 parent b2950d6 commit e65966c
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 45 deletions.
8 changes: 4 additions & 4 deletions TheMaskedManual.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -449,15 +449,15 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 5QC8WP9VB5;
INFOPLIST_FILE = TheMaskedManual/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.1;
MARKETING_VERSION = 1.1;
PRODUCT_BUNDLE_IDENTIFIER = oliverkernst.TheMaskedManual;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -471,15 +471,15 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 5QC8WP9VB5;
INFOPLIST_FILE = TheMaskedManual/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.6;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.1;
MARKETING_VERSION = 1.1;
PRODUCT_BUNDLE_IDENTIFIER = oliverkernst.TheMaskedManual;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand Down
2 changes: 1 addition & 1 deletion TheMaskedManual/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
Expand Down
132 changes: 95 additions & 37 deletions TheMaskedManual/ViewControllers/CameraViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
var is_search_in_progress : Bool = false

var session = AVCaptureSession()
var deviceInput : AVCaptureInput? = nil
var deviceOutput : AVCaptureOutput? = nil
var requests = [VNRequest]()

private var screenshot_mode = false
Expand All @@ -73,12 +75,7 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
// Company
let companyNib = UINib.init(nibName: "CompanyTableViewCell", bundle: Bundle.main)
tableView.register(companyNib, forCellReuseIdentifier: "companyTableViewCell")

if !screenshot_mode {
// Setup video once
setup_live_video()
}


if screenshot_mode {
imageView.image = UIImage(named: "toy_image")

Expand All @@ -92,26 +89,43 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff

// Background color
tableView.backgroundColor = UIColor(red: 174.0/256.0, green: 174.0/256.0, blue: 178.0/256.0, alpha: 1.0)

// Setup image once
setup_image_once()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

start_up()
}

private func start_up() {
if !screenshot_mode {
startLiveVideo()
startTextDetection()
let success = setup_live_video()

if success {
startLiveVideo()
startTextDetection()
}
}
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

private func shut_down() {
if !screenshot_mode {
stopLiveVideo()
stopTextDetection()

break_down_live_video()
}
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

shut_down()
}

override func viewDidLayoutSubviews() {
// Fix the fact that view is not finished in viewDidAppear
imageView.layer.sublayers?[0].frame = imageView.bounds
Expand All @@ -124,19 +138,19 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
print("No result")
return
}

// Highlight
DispatchQueue.main.async() {
self.imageView.layer.sublayers?.removeSubrange(1...)
for rg in observations {
self.highlightWord(box: rg)
}
}

// Only search if not currently searching
if !is_search_in_progress {
is_search_in_progress = true


// Highlight
DispatchQueue.main.async() {
self.imageView.layer.sublayers?.removeSubrange(1...)
for rg in observations {
self.highlightWord(box: rg)
}
}

var raw_observed_texts : [String] = []

for observation in observations {
Expand Down Expand Up @@ -238,7 +252,11 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
}

func stopLiveVideo() {
session.stopRunning()
print("Stopping live video...")
if session.isRunning {
session.stopRunning()
}
print("Stopped live video.")
}

func startTextDetection() {
Expand All @@ -254,25 +272,60 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
self.requests = [textRequest]
}

func setup_live_video() {
func setup_live_video() -> Bool {
print("setup live video start...")

// Init capture session
session.sessionPreset = AVCaptureSession.Preset.photo
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)

guard let captureDevice = AVCaptureDevice.default(for: AVMediaType.video) else {
print("No camera device")
return false
}

// Setup
let deviceInput = try! AVCaptureDeviceInput(device: captureDevice!)
let deviceOutput = AVCaptureVideoDataOutput()
deviceOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
deviceOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
session.addInput(deviceInput)
session.addOutput(deviceOutput)

do {
let deviceInput_ = try AVCaptureDeviceInput(device: captureDevice)
session.addInput(deviceInput_)
deviceInput = deviceInput_
} catch {
print("Error: ", error.localizedDescription)
return false
}

let deviceOutput_ = AVCaptureVideoDataOutput()
deviceOutput_.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
deviceOutput_.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
session.addOutput(deviceOutput_)
deviceOutput = deviceOutput_

print("setup live video.")

return true
}

private func setup_image_once() {
// Set image
let imageLayer = AVCaptureVideoPreviewLayer(session: session)
imageLayer.bounds = imageView.bounds
imageLayer.frame = imageView.bounds
imageView.layer.addSublayer(imageLayer)
}

func break_down_live_video() {
print("Breaking down live video...")

// Remove IO
if let deviceInput = deviceInput {
session.removeInput(deviceInput)
}
if let deviceOutput = deviceOutput {
session.removeOutput(deviceOutput)
}
deviceOutput = nil
deviceInput = nil

print("Broke down live video.")
}

func startLiveVideo() {
session.startRunning()
}
Expand Down Expand Up @@ -315,8 +368,15 @@ class CameraViewController: UIViewController, AVCaptureVideoDataOutputSampleBuff
alert.definesPresentationContext = true
alert.modalPresentationStyle = UIModalPresentationStyle.overFullScreen
alert.modalTransitionStyle = UIModalTransitionStyle.coverVertical

alert.completion_on_close = {
// Start live video and recognition again
self.start_up()
}

DispatchQueue.main.async {
// Stop live video and recognition
self.shut_down()

self.present(alert, animated: true, completion: nil)
}
}
Expand Down Expand Up @@ -477,8 +537,7 @@ extension CameraViewController : UITableViewDataSource, UITableViewDelegate {
alert.mask_ui = mask.get_mask_ui()
alert.completion_on_close = {
// Start live video and recognition again
self.startLiveVideo()
self.startTextDetection()
self.start_up()
}
alert.providesPresentationContextTransitionStyle = true
alert.definesPresentationContext = true
Expand All @@ -487,8 +546,7 @@ extension CameraViewController : UITableViewDataSource, UITableViewDelegate {

DispatchQueue.main.async {
// Stop live video and recognition
self.stopLiveVideo()
self.stopTextDetection()
self.shut_down()

// Show
self.present(alert, animated: true, completion: nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class MaskNotFoundViewController: UIViewController {
@IBOutlet weak var central_view: UIView!
@IBOutlet weak var first_text_view: UITextView!
@IBOutlet weak var second_text_view: UITextView!

var completion_on_close : () -> Void = {}

override func viewDidLoad() {
super.viewDidLoad()

Expand Down Expand Up @@ -64,7 +65,7 @@ class MaskNotFoundViewController: UIViewController {
}

@IBAction func close_button_pressed(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
self.dismiss(animated: true, completion: completion_on_close)
}

/*
Expand Down
5 changes: 4 additions & 1 deletion TheMaskedManual/ViewControllers/TabBarController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class TabBarController: UITabBarController {

override func viewDidLoad() {
super.viewDidLoad()

print("Tab bar viewDidLoad starting...")

// Load masks
LoadMasks.load_masks_and_companies { (masks, companies) in

Expand Down Expand Up @@ -67,6 +68,8 @@ class TabBarController: UITabBarController {
DispatchQueue.main.async {
self.present(alert, animated: false, completion: nil)
}

print("Tab bar viewDidLoad.")
}

override func viewWillAppear(_ animated: Bool) {
Expand Down

0 comments on commit e65966c

Please sign in to comment.