Skip to content

Prepared video recording example #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions quickstart-ios-swift/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17126"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
Expand All @@ -23,21 +24,21 @@
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="uJd-FE-xhl">
<rect key="frame" x="0.0" y="692" width="414" height="102"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oM4-3a-Dc3">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oM4-3a-Dc3">
<rect key="frame" x="0.0" y="16" width="138" height="70"/>
<fontDescription key="fontDescription" name="Baskerville-Bold" family="Baskerville" pointSize="50"/>
<state key="normal" title="‹">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lGP-cD-zyV">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lGP-cD-zyV">
<rect key="frame" x="138" y="0.0" width="138" height="102"/>
<fontDescription key="fontDescription" type="system" pointSize="75"/>
<state key="normal" title="◉">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bex-8d-pBb">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bex-8d-pBb">
<rect key="frame" x="276" y="16" width="138" height="70"/>
<fontDescription key="fontDescription" name="Baskerville-Bold" family="Baskerville" pointSize="50"/>
<state key="normal" title="›">
Expand All @@ -49,21 +50,21 @@
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" spacing="40" translatesAutoresizingMaskIntoConstraints="NO" id="30S-Tc-ObG">
<rect key="frame" x="92" y="802" width="230" height="44"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lg4-1e-jvk">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lg4-1e-jvk">
<rect key="frame" x="0.0" y="0.0" width="49" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Masks">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wuh-Ua-YpK">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wuh-Ua-YpK">
<rect key="frame" x="89" y="0.0" width="54" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Effects">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rfH-fA-IsO">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rfH-fA-IsO">
<rect key="frame" x="183" y="0.0" width="47" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Filters">
Expand All @@ -76,24 +77,24 @@
</constraints>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" spacing="40" translatesAutoresizingMaskIntoConstraints="NO" id="zkT-19-D7n" userLabel="Recording Mode Stack View">
<rect key="frame" x="76" y="643" width="262" height="44"/>
<rect key="frame" x="105.5" y="643" width="203" height="44"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pFL-eO-IRm" userLabel="Photo">
<rect key="frame" x="0.0" y="0.0" width="46" height="44"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pFL-eO-IRm" userLabel="Photo">
<rect key="frame" x="0.0" y="0.0" width="45" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Photo">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mIr-ia-DAb" userLabel="Video">
<rect key="frame" x="86" y="0.0" width="44" height="44"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mIr-ia-DAb" userLabel="Prepared Video">
<rect key="frame" x="85" y="0.0" width="118" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Video">
<state key="normal" title="Prepared Video">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wtJ-rs-9IX" userLabel="LowQ Video">
<rect key="frame" x="170" y="0.0" width="92" height="44"/>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wtJ-rs-9IX" userLabel="LowQ Video">
<rect key="frame" x="203" y="0.0" width="0.0" height="44"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="LowQ Video">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
Expand All @@ -113,6 +114,7 @@
<state key="normal" image="SwitchCamera"/>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="aUr-fD-BmM" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="1pg-nk-plO"/>
Expand All @@ -133,7 +135,6 @@
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="30S-Tc-ObG" secondAttribute="bottom" constant="16" id="r70-XP-aDs"/>
<constraint firstItem="uJd-FE-xhl" firstAttribute="top" secondItem="zkT-19-D7n" secondAttribute="bottom" constant="5" id="tFD-mC-RHN"/>
</constraints>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
<connections>
<outlet property="arView" destination="aUr-fD-BmM" id="kOx-av-2Hv"/>
Expand Down
66 changes: 51 additions & 15 deletions quickstart-ios-swift/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ enum RecordingMode : String {
case lowQualityVideo
}

enum RecordingState : String {
case preparing
case ready
case recording
}

enum Masks: String, CaseIterable {
case none
case aviators
Expand Down Expand Up @@ -118,7 +124,13 @@ class ViewController: UIViewController {
}
}

private var isRecordingInProcess: Bool = false
private var currentRecordingState: RecordingState! {
didSet {
updateRecordingModeAppearance()
}
}

//private var isRecordingInProcess: Bool = false

// MARK: - Lifecycle -

Expand Down Expand Up @@ -161,6 +173,10 @@ class ViewController: UIViewController {
arView.initialize()

cameraController.startCamera()

// Set videoRecordingWarmupEnabled after initialization
arView.deepAR.videoRecordingWarmupEnabled = true;

}

private func addTargets() {
Expand All @@ -183,6 +199,14 @@ class ViewController: UIViewController {
button.isSelected = mode == currentMode
}
}
private func updateRecordingButton() {
if (currentRecordingState == RecordingState.preparing){
//disable record button while recording is preparing
recordActionButton.isEnabled = false;
} else {
recordActionButton.isEnabled = true;
}
}

private func updateRecordingModeAppearance() {
buttonRecordingModePairs.forEach { (button, recordingMode) in
Expand Down Expand Up @@ -229,21 +253,20 @@ class ViewController: UIViewController {
return
}

if (isRecordingInProcess) {
if (currentRecordingState == RecordingState.recording) {
arView.finishVideoRecording()
isRecordingInProcess = false
//finishVideoRecording will start preparing for next recording session if videoRecordingWarmupEnabled is true
currentRecordingState = RecordingState.preparing
return
}

let width: Int32 = Int32(arView.renderingResolution.width)
let height: Int32 = Int32(arView.renderingResolution.height)

if (currentRecordingMode == RecordingMode.video) {
arView.startVideoRecording(withOutputWidth: width, outputHeight: height)
isRecordingInProcess = true
if (currentRecordingMode == RecordingMode.video && currentRecordingState == RecordingState.ready) {
arView.resumeVideoRecording();
currentRecordingState = RecordingState.recording;
return
}

// Disabled in prepared recording mode
/*
if (currentRecordingMode == RecordingMode.lowQualityVideo) {
let videoQuality = 0.1
let bitrate = 1250000
Expand All @@ -257,6 +280,7 @@ class ViewController: UIViewController {
arView.startVideoRecording(withOutputWidth: width, outputHeight: height, subframe: frame, videoCompressionProperties: videoSettings, recordAudio: true)
isRecordingInProcess = true
}
*/

}

Expand Down Expand Up @@ -331,13 +355,11 @@ class ViewController: UIViewController {

// MARK: - ARViewDelegate -

extension ViewController: ARViewDelegate {
func didFinishPreparingForVideoRecording() { }

extension ViewController: DeepARDelegate {

func didStartVideoRecording() { }

func didFinishVideoRecording(_ videoFilePath: String!) {

let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let components = videoFilePath.components(separatedBy: "/")
guard let last = components.last else { return }
Expand Down Expand Up @@ -376,7 +398,21 @@ extension ViewController: ARViewDelegate {
}
}

func didInitialize() {}
func didInitialize() {
// Call startVideoRecording to prepare recording. Only needs to be called once when initialization is finished
// Must be called on main thread
DispatchQueue.main.async { [unowned self] in
let width: Int32 = Int32(arView.renderingResolution.width)
let height: Int32 = Int32(arView.renderingResolution.height)
arView.startVideoRecording(withOutputWidth: width, outputHeight: height);
currentRecordingState = RecordingState.preparing;
}
}

// Video recording is prepared, resumeVideoRecording can now be called
func didFinishPreparingForVideoRecording() {
currentRecordingState = RecordingState.ready;
}

func faceVisiblityDidChange(_ faceVisible: Bool) {}
}
Expand Down