Compare commits
13 Commits
952e4a93e1
...
eyenov/chu
Author | SHA1 | Date | |
---|---|---|---|
|
b006b1e744 | ||
|
694d9cfa8c | ||
|
91767e71c8 | ||
|
9f2c7906e5 | ||
|
621bfe333c | ||
|
20f8fa2937 | ||
|
b03f9ea423 | ||
|
98d90a6442 | ||
|
0a43d7a160 | ||
|
a2ce4df663 | ||
|
89ecb35616 | ||
|
d9a1287b68 | ||
|
23459b2635 |
@@ -11,7 +11,7 @@ import AVFoundation
|
||||
// MARK: - CameraView + AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate
|
||||
|
||||
extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate {
|
||||
func startRecording(options: NSDictionary, callback jsCallback: @escaping RCTResponseSenderBlock) {
|
||||
func startRecording(options: NSDictionary, filePath: String, callback jsCallback: @escaping RCTResponseSenderBlock) {
|
||||
// Type-safety
|
||||
let callback = Callback(jsCallback)
|
||||
|
||||
@@ -21,6 +21,7 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
||||
// Start Recording with success and error callbacks
|
||||
cameraSession.startRecording(
|
||||
options: options,
|
||||
filePath: filePath,
|
||||
onVideoRecorded: { video in
|
||||
callback.resolve(video.toJSValue())
|
||||
},
|
||||
|
@@ -62,6 +62,8 @@ public final class CameraView: UIView, CameraSessionDelegate {
|
||||
@objc var onStarted: RCTDirectEventBlock?
|
||||
@objc var onStopped: RCTDirectEventBlock?
|
||||
@objc var onViewReady: RCTDirectEventBlock?
|
||||
@objc var onInitReady: RCTDirectEventBlock?
|
||||
@objc var onVideoChunkReady: RCTDirectEventBlock?
|
||||
@objc var onCodeScanned: RCTDirectEventBlock?
|
||||
// zoom
|
||||
@objc var enableZoomGesture = false {
|
||||
@@ -335,6 +337,31 @@ public final class CameraView: UIView, CameraSessionDelegate {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
func onVideoChunkReady(chunk: ChunkedRecorder.Chunk) {
|
||||
ReactLogger.log(level: .info, message: "Chunk ready: \(chunk)")
|
||||
|
||||
guard let onVideoChunkReady, let onInitReady else {
|
||||
ReactLogger.log(level: .warning, message: "Either onInitReady or onVideoChunkReady are not valid!")
|
||||
return
|
||||
}
|
||||
|
||||
switch chunk.type {
|
||||
case .initialization:
|
||||
onInitReady([
|
||||
"filepath": chunk.url.path,
|
||||
])
|
||||
case let .data(index: index, duration: duration):
|
||||
var data: [String: Any] = [
|
||||
"filepath": chunk.url.path,
|
||||
"index": index,
|
||||
]
|
||||
if let duration {
|
||||
data["duration"] = duration.seconds
|
||||
}
|
||||
onVideoChunkReady(data)
|
||||
}
|
||||
}
|
||||
|
||||
func onCodeScanned(codes: [CameraSession.Code], scannerFrame: CameraSession.CodeScannerFrame) {
|
||||
guard let onCodeScanned = onCodeScanned else {
|
||||
|
@@ -55,6 +55,8 @@ RCT_EXPORT_VIEW_PROPERTY(onInitialized, RCTDirectEventBlock);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onStarted, RCTDirectEventBlock);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onStopped, RCTDirectEventBlock);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onViewReady, RCTDirectEventBlock);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onInitReady, RCTDirectEventBlock);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onVideoChunkReady, RCTDirectEventBlock);
|
||||
// Code Scanner
|
||||
RCT_EXPORT_VIEW_PROPERTY(codeScannerOptions, NSDictionary);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onCodeScanned, RCTDirectEventBlock);
|
||||
@@ -62,7 +64,8 @@ RCT_EXPORT_VIEW_PROPERTY(onCodeScanned, RCTDirectEventBlock);
|
||||
// Camera View Functions
|
||||
RCT_EXTERN_METHOD(startRecording
|
||||
: (nonnull NSNumber*)node options
|
||||
: (NSDictionary*)options onRecordCallback
|
||||
: (NSDictionary*)options filePath
|
||||
: (NSString*)filePath onRecordCallback
|
||||
: (RCTResponseSenderBlock)onRecordCallback);
|
||||
RCT_EXTERN_METHOD(pauseRecording
|
||||
: (nonnull NSNumber*)node resolve
|
||||
|
@@ -43,9 +43,9 @@ final class CameraViewManager: RCTViewManager {
|
||||
// This means that any errors that occur in this function have to be delegated through
|
||||
// the callback, but I'd prefer for them to throw for the original function instead.
|
||||
@objc
|
||||
final func startRecording(_ node: NSNumber, options: NSDictionary, onRecordCallback: @escaping RCTResponseSenderBlock) {
|
||||
final func startRecording(_ node: NSNumber, options: NSDictionary, filePath: NSString, onRecordCallback: @escaping RCTResponseSenderBlock) {
|
||||
let component = getCameraView(withTag: node)
|
||||
component.startRecording(options: options, callback: onRecordCallback)
|
||||
component.startRecording(options: options, filePath: filePath as String, callback: onRecordCallback)
|
||||
}
|
||||
|
||||
@objc
|
||||
|
@@ -176,6 +176,7 @@ enum CaptureError {
|
||||
case noRecordingInProgress
|
||||
case fileError
|
||||
case createTempFileError(message: String? = nil)
|
||||
case createRecordingDirectoryError(message: String? = nil)
|
||||
case createRecorderError(message: String? = nil)
|
||||
case videoNotEnabled
|
||||
case photoNotEnabled
|
||||
@@ -193,6 +194,8 @@ enum CaptureError {
|
||||
return "file-io-error"
|
||||
case .createTempFileError:
|
||||
return "create-temp-file-error"
|
||||
case .createRecordingDirectoryError:
|
||||
return "create-recording-directory-error"
|
||||
case .createRecorderError:
|
||||
return "create-recorder-error"
|
||||
case .videoNotEnabled:
|
||||
@@ -218,6 +221,8 @@ enum CaptureError {
|
||||
return "An unexpected File IO error occured!"
|
||||
case let .createTempFileError(message: message):
|
||||
return "Failed to create a temporary file! \(message ?? "(no additional message)")"
|
||||
case let .createRecordingDirectoryError(message: message):
|
||||
return "Failed to create a recording directory! \(message ?? "(no additional message)")"
|
||||
case let .createRecorderError(message: message):
|
||||
return "Failed to create the AVAssetWriter (Recorder)! \(message ?? "(no additional message)")"
|
||||
case .videoNotEnabled:
|
||||
|
@@ -15,6 +15,7 @@ extension CameraSession {
|
||||
Starts a video + audio recording with a custom Asset Writer.
|
||||
*/
|
||||
func startRecording(options: RecordVideoOptions,
|
||||
filePath: String,
|
||||
onVideoRecorded: @escaping (_ video: Video) -> Void,
|
||||
onError: @escaping (_ error: CameraError) -> Void) {
|
||||
// Run on Camera Queue
|
||||
@@ -33,6 +34,14 @@ extension CameraSession {
|
||||
}
|
||||
|
||||
let enableAudio = self.configuration?.audio != .disabled
|
||||
|
||||
// Callback for when new chunks are ready
|
||||
let onChunkReady: (ChunkedRecorder.Chunk) -> Void = { chunk in
|
||||
guard let delegate = self.delegate else {
|
||||
return
|
||||
}
|
||||
delegate.onVideoChunkReady(chunk: chunk)
|
||||
}
|
||||
|
||||
// Callback for when the recording ends
|
||||
let onFinish = { (recordingSession: RecordingSession, status: AVAssetWriter.Status, error: Error?) in
|
||||
@@ -62,7 +71,7 @@ extension CameraSession {
|
||||
} else {
|
||||
if status == .completed {
|
||||
// Recording was successfully saved
|
||||
let video = Video(path: recordingSession.url.absoluteString,
|
||||
let video = Video(path: recordingSession.outputDiretory.absoluteString,
|
||||
duration: recordingSession.duration,
|
||||
size: recordingSession.size ?? CGSize.zero)
|
||||
onVideoRecorded(video)
|
||||
@@ -73,22 +82,22 @@ extension CameraSession {
|
||||
}
|
||||
}
|
||||
|
||||
// Create temporary file
|
||||
let errorPointer = ErrorPointer(nilLiteral: ())
|
||||
let fileExtension = options.fileType.descriptor ?? "mov"
|
||||
guard let tempFilePath = RCTTempFilePath(fileExtension, errorPointer) else {
|
||||
let message = errorPointer?.pointee?.description
|
||||
onError(.capture(.createTempFileError(message: message)))
|
||||
return
|
||||
if !FileManager.default.fileExists(atPath: filePath) {
|
||||
do {
|
||||
try FileManager.default.createDirectory(atPath: filePath, withIntermediateDirectories: true)
|
||||
} catch {
|
||||
onError(.capture(.createRecordingDirectoryError(message: error.localizedDescription)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ReactLogger.log(level: .info, message: "Will record to temporary file: \(tempFilePath)")
|
||||
let tempURL = URL(string: "file://\(tempFilePath)")!
|
||||
ReactLogger.log(level: .info, message: "Will record to temporary file: \(filePath)")
|
||||
|
||||
do {
|
||||
// Create RecordingSession for the temp file
|
||||
let recordingSession = try RecordingSession(url: tempURL,
|
||||
let recordingSession = try RecordingSession(outputDiretory: filePath,
|
||||
fileType: options.fileType,
|
||||
onChunkReady: onChunkReady,
|
||||
completion: onFinish)
|
||||
|
||||
// Init Audio + Activate Audio Session (optional)
|
||||
|
@@ -33,6 +33,10 @@ protocol CameraSessionDelegate: AnyObject {
|
||||
Called for every frame (if video or frameProcessor is enabled)
|
||||
*/
|
||||
func onFrame(sampleBuffer: CMSampleBuffer)
|
||||
/**
|
||||
Called whenever a new video chunk is available
|
||||
*/
|
||||
func onVideoChunkReady(chunk: ChunkedRecorder.Chunk)
|
||||
/**
|
||||
Called whenever a QR/Barcode has been scanned. Only if the CodeScanner Output is enabled
|
||||
*/
|
||||
|
88
package/ios/Core/ChunkedRecorder.swift
Normal file
88
package/ios/Core/ChunkedRecorder.swift
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// ChunkedRecorder.swift
|
||||
// VisionCamera
|
||||
//
|
||||
// Created by Rafael Bastos on 12/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AVFoundation
|
||||
|
||||
|
||||
class ChunkedRecorder: NSObject {
|
||||
|
||||
enum ChunkType {
|
||||
case initialization
|
||||
case data(index: UInt64, duration: CMTime?)
|
||||
}
|
||||
|
||||
struct Chunk {
|
||||
let url: URL
|
||||
let type: ChunkType
|
||||
}
|
||||
|
||||
let outputURL: URL
|
||||
let onChunkReady: ((Chunk) -> Void)
|
||||
|
||||
private var chunkIndex: UInt64 = 0
|
||||
|
||||
init(outputURL: URL, onChunkReady: @escaping ((Chunk) -> Void)) throws {
|
||||
self.outputURL = outputURL
|
||||
self.onChunkReady = onChunkReady
|
||||
guard FileManager.default.fileExists(atPath: outputURL.path) else {
|
||||
throw CameraError.unknown(message: "output directory does not exist at: \(outputURL.path)", cause: nil)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ChunkedRecorder: AVAssetWriterDelegate {
|
||||
|
||||
func assetWriter(_ writer: AVAssetWriter,
|
||||
didOutputSegmentData segmentData: Data,
|
||||
segmentType: AVAssetSegmentType,
|
||||
segmentReport: AVAssetSegmentReport?) {
|
||||
|
||||
switch segmentType {
|
||||
case .initialization:
|
||||
saveInitSegment(segmentData)
|
||||
case .separable:
|
||||
saveSegment(segmentData, report: segmentReport)
|
||||
@unknown default:
|
||||
fatalError("Unknown AVAssetSegmentType!")
|
||||
}
|
||||
}
|
||||
|
||||
private func saveInitSegment(_ data: Data) {
|
||||
let url = outputURL.appendingPathComponent("init.mp4")
|
||||
save(data: data, url: url)
|
||||
onChunkReady(url: url, type: .initialization)
|
||||
}
|
||||
|
||||
private func saveSegment(_ data: Data, report: AVAssetSegmentReport?) {
|
||||
let name = "\(chunkIndex).mp4"
|
||||
let url = outputURL.appendingPathComponent(name)
|
||||
save(data: data, url: url)
|
||||
let duration = report?
|
||||
.trackReports
|
||||
.filter { $0.mediaType == .video }
|
||||
.first?
|
||||
.duration
|
||||
onChunkReady(url: url, type: .data(index: chunkIndex, duration: duration))
|
||||
chunkIndex += 1
|
||||
}
|
||||
|
||||
private func save(data: Data, url: URL) {
|
||||
do {
|
||||
try data.write(to: url)
|
||||
} catch {
|
||||
ReactLogger.log(level: .error, message: "Unable to write \(url): \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
private func onChunkReady(url: URL, type: ChunkType) {
|
||||
onChunkReady(Chunk(url: url, type: type))
|
||||
}
|
||||
|
||||
}
|
@@ -29,6 +29,7 @@ class RecordingSession {
|
||||
private let assetWriter: AVAssetWriter
|
||||
private var audioWriter: AVAssetWriterInput?
|
||||
private var videoWriter: AVAssetWriterInput?
|
||||
private let recorder: ChunkedRecorder
|
||||
private let completionHandler: (RecordingSession, AVAssetWriter.Status, Error?) -> Void
|
||||
|
||||
private var startTimestamp: CMTime?
|
||||
@@ -48,8 +49,8 @@ class RecordingSession {
|
||||
/**
|
||||
Gets the file URL of the recorded video.
|
||||
*/
|
||||
var url: URL {
|
||||
return assetWriter.outputURL
|
||||
var outputDiretory: URL {
|
||||
return recorder.outputURL
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,14 +71,32 @@ class RecordingSession {
|
||||
return (lastWrittenTimestamp - startTimestamp).seconds
|
||||
}
|
||||
|
||||
init(url: URL,
|
||||
init(outputDiretory: String,
|
||||
fileType: AVFileType,
|
||||
onChunkReady: @escaping ((ChunkedRecorder.Chunk) -> Void),
|
||||
completion: @escaping (RecordingSession, AVAssetWriter.Status, Error?) -> Void) throws {
|
||||
completionHandler = completion
|
||||
|
||||
do {
|
||||
assetWriter = try AVAssetWriter(outputURL: url, fileType: fileType)
|
||||
let outputURL = URL(fileURLWithPath: outputDiretory)
|
||||
recorder = try ChunkedRecorder(outputURL: outputURL, onChunkReady: onChunkReady)
|
||||
assetWriter = AVAssetWriter(contentType: UTType(fileType.rawValue)!)
|
||||
assetWriter.shouldOptimizeForNetworkUse = false
|
||||
assetWriter.outputFileTypeProfile = .mpeg4AppleHLS
|
||||
assetWriter.preferredOutputSegmentInterval = CMTime(seconds: 6, preferredTimescale: 1)
|
||||
|
||||
/*
|
||||
Apple HLS fMP4 does not have an Edit List Box ('elst') in an initialization segment to remove
|
||||
audio priming duration which advanced audio formats like AAC have, since the sample tables
|
||||
are empty. As a result, if the output PTS of the first non-fully trimmed audio sample buffer is
|
||||
kCMTimeZero, the audio samples’ presentation time in segment files may be pushed forward by the
|
||||
audio priming duration. This may cause audio and video to be out of sync. You should add a time
|
||||
offset to all samples to avoid this situation.
|
||||
*/
|
||||
let startTimeOffset = CMTime(value: 10, timescale: 1)
|
||||
assetWriter.initialSegmentStartTime = startTimeOffset
|
||||
|
||||
assetWriter.delegate = recorder
|
||||
} catch let error as NSError {
|
||||
throw CameraError.capture(.createRecorderError(message: error.description))
|
||||
}
|
||||
|
37
package/ios/TestRecorder/AppDelegate.swift
Normal file
37
package/ios/TestRecorder/AppDelegate.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// TestRecorder
|
||||
//
|
||||
// Created by Rafael Bastos on 11/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: UISceneSession Lifecycle
|
||||
|
||||
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
// Called when a new scene session is being created.
|
||||
// Use this method to select a configuration to create the new scene with.
|
||||
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
|
||||
// Called when the user discards a scene session.
|
||||
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
||||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
6
package/ios/TestRecorder/Assets.xcassets/Contents.json
Normal file
6
package/ios/TestRecorder/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
25
package/ios/TestRecorder/Base.lproj/LaunchScreen.storyboard
Normal file
25
package/ios/TestRecorder/Base.lproj/LaunchScreen.storyboard
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
51
package/ios/TestRecorder/Base.lproj/Main.storyboard
Normal file
51
package/ios/TestRecorder/Base.lproj/Main.storyboard
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
|
||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="TestRecorder" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VWP-nN-U6K">
|
||||
<rect key="frame" x="157.33333333333334" y="722.66666666666663" width="78.333333333333343" height="34.333333333333371"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" title="Record"/>
|
||||
<buttonConfiguration key="configuration" style="filled" title="Record"/>
|
||||
<connections>
|
||||
<action selector="toggleRecord:" destination="BYZ-38-t0r" eventType="touchUpInside" id="63a-uH-hTe"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="VWP-nN-U6K" secondAttribute="bottom" constant="61" id="0iW-h7-WDE"/>
|
||||
<constraint firstItem="VWP-nN-U6K" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="yZb-ba-qfO"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="recordButton" destination="VWP-nN-U6K" id="gSk-uh-nDX"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="115" y="-27"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
25
package/ios/TestRecorder/Info.plist
Normal file
25
package/ios/TestRecorder/Info.plist
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
<key>UISceneStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
15
package/ios/TestRecorder/ReactStubs.h
Normal file
15
package/ios/TestRecorder/ReactStubs.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// ReactStubs.h
|
||||
// TestRecorder
|
||||
//
|
||||
// Created by Rafael Bastos on 12/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIView (React)
|
||||
|
||||
- (void)didSetProps:(NSArray<NSString *> *)changedProps;
|
||||
|
||||
@end
|
17
package/ios/TestRecorder/ReactStubs.m
Normal file
17
package/ios/TestRecorder/ReactStubs.m
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// ReactStubs.m
|
||||
// TestRecorder
|
||||
//
|
||||
// Created by Rafael Bastos on 12/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ReactStubs.h"
|
||||
|
||||
@implementation UIView (React)
|
||||
|
||||
- (void)didSetProps:(__unused NSArray<NSString *> *)changedProps
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
102
package/ios/TestRecorder/ReactStubs.swift
Normal file
102
package/ios/TestRecorder/ReactStubs.swift
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// ReactStubs.swift
|
||||
// TestRecorder
|
||||
//
|
||||
// Created by Rafael Bastos on 11/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
enum RCTLogLevel: String {
|
||||
case trace
|
||||
case info
|
||||
case warning
|
||||
case error
|
||||
}
|
||||
|
||||
enum RCTLogSource {
|
||||
case native
|
||||
}
|
||||
|
||||
func RCTDefaultLogFunction(_ level: RCTLogLevel, _ source: RCTLogSource, _ file: String, _ line: NSNumber, _ message: String) {
|
||||
print(level.rawValue, "-", message)
|
||||
}
|
||||
|
||||
typealias RCTDirectEventBlock = (Any?) -> Void
|
||||
typealias RCTPromiseResolveBlock = (Any?) -> Void
|
||||
typealias RCTPromiseRejectBlock = (String, String, NSError?) -> Void
|
||||
typealias RCTResponseSenderBlock = (Any) -> Void
|
||||
|
||||
func NSNull() -> [String: String] {
|
||||
return [:]
|
||||
}
|
||||
|
||||
|
||||
func makeReactError(_ cameraError: CameraError, cause: NSError?) -> [String: Any] {
|
||||
var causeDictionary: [String: Any]?
|
||||
if let cause = cause {
|
||||
causeDictionary = [
|
||||
"cause": "\(cause.domain): \(cause.code) \(cause.description)",
|
||||
"userInfo": cause.userInfo
|
||||
]
|
||||
}
|
||||
return [
|
||||
"error": "\(cameraError.code): \(cameraError.message)",
|
||||
"extra": [
|
||||
"code": cameraError.code,
|
||||
"message": cameraError.message,
|
||||
"cause": causeDictionary ?? NSNull(),
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
func makeReactError(_ cameraError: CameraError) -> [String: Any] {
|
||||
return makeReactError(cameraError, cause: nil)
|
||||
}
|
||||
|
||||
|
||||
class RCTFPSGraph: UIView {
|
||||
convenience init(frame: CGRect, color: UIColor) {
|
||||
self.init(frame: frame)
|
||||
}
|
||||
|
||||
func onTick(_ tick: CFTimeInterval) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func RCTTempFilePath(_ ext: String, _ error: ErrorPointer) -> String? {
|
||||
let directory = NSTemporaryDirectory().appending("ReactNative")
|
||||
let fm = FileManager.default
|
||||
if fm.fileExists(atPath: directory) {
|
||||
try! fm.removeItem(atPath: directory)
|
||||
}
|
||||
if !fm.fileExists(atPath: directory) {
|
||||
try! fm.createDirectory(atPath: directory, withIntermediateDirectories: true)
|
||||
}
|
||||
return directory
|
||||
.appending("/").appending(UUID().uuidString)
|
||||
.appending(".").appending(ext)
|
||||
}
|
||||
|
||||
|
||||
class RCTViewManager: NSObject {
|
||||
|
||||
var methodQueue: DispatchQueue! { nil }
|
||||
class func requiresMainQueueSetup() -> Bool { false }
|
||||
func view() -> UIView! { nil }
|
||||
|
||||
struct Bridge {
|
||||
let uiManager = UIManager()
|
||||
}
|
||||
|
||||
struct UIManager {
|
||||
func view(forReactTag: NSNumber) -> UIView! {
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
||||
let bridge: Bridge = Bridge()
|
||||
}
|
53
package/ios/TestRecorder/SceneDelegate.swift
Normal file
53
package/ios/TestRecorder/SceneDelegate.swift
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// SceneDelegate.swift
|
||||
// TestRecorder
|
||||
//
|
||||
// Created by Rafael Bastos on 11/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
guard let _ = (scene as? UIWindowScene) else { return }
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
// Called as the scene is being released by the system.
|
||||
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
||||
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
||||
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
|
||||
}
|
||||
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// Called when the scene has moved from an inactive state to an active state.
|
||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// Called when the scene will move from an active state to an inactive state.
|
||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the background to the foreground.
|
||||
// Use this method to undo the changes made on entering the background.
|
||||
}
|
||||
|
||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the foreground to the background.
|
||||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||
// to restore the scene back to its current state.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
6
package/ios/TestRecorder/TestRecorder-Bridging-Header.h
Normal file
6
package/ios/TestRecorder/TestRecorder-Bridging-Header.h
Normal file
@@ -0,0 +1,6 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
|
||||
#import "ReactStubs.h"
|
117
package/ios/TestRecorder/ViewController.swift
Normal file
117
package/ios/TestRecorder/ViewController.swift
Normal file
@@ -0,0 +1,117 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// TestRecorder
|
||||
//
|
||||
// Created by Rafael Bastos on 11/07/2024.
|
||||
// Copyright © 2024 mrousavy. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
@IBOutlet weak var recordButton: UIButton!
|
||||
|
||||
let cameraView = CameraView()
|
||||
let filePath: String = {
|
||||
NSTemporaryDirectory() + "TestRecorder"
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
try? FileManager.default.removeItem(atPath: filePath)
|
||||
|
||||
cameraView.translatesAutoresizingMaskIntoConstraints = false;
|
||||
view.insertSubview(cameraView, at: 0)
|
||||
NSLayoutConstraint.activate([
|
||||
cameraView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
cameraView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
cameraView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
cameraView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
])
|
||||
|
||||
recordButton.isHidden = true
|
||||
cameraView.onInitialized = { _ in
|
||||
DispatchQueue.main.async {
|
||||
self.recordButton.isHidden = false
|
||||
}
|
||||
}
|
||||
cameraView.onInitReady = { json in
|
||||
print("onInitReady:", json ?? "nil")
|
||||
}
|
||||
cameraView.onVideoChunkReady = { json in
|
||||
print("onVideoChunkReady:", json ?? "nil")
|
||||
}
|
||||
|
||||
Task { @MainActor in
|
||||
await requestAuthorizations()
|
||||
|
||||
cameraView.photo = true
|
||||
cameraView.video = true
|
||||
cameraView.audio = false
|
||||
cameraView.isActive = true
|
||||
cameraView.cameraId = getCameraDeviceId() as NSString?
|
||||
cameraView.didSetProps([])
|
||||
}
|
||||
}
|
||||
|
||||
func isAuthorized(for mediaType: AVMediaType) async -> Bool {
|
||||
let status = AVCaptureDevice.authorizationStatus(for: mediaType)
|
||||
var isAuthorized = status == .authorized
|
||||
if status == .notDetermined {
|
||||
isAuthorized = await AVCaptureDevice.requestAccess(for: mediaType)
|
||||
}
|
||||
return isAuthorized
|
||||
}
|
||||
|
||||
|
||||
func requestAuthorizations() async {
|
||||
guard await isAuthorized(for: .video) else { return }
|
||||
guard await isAuthorized(for: .audio) else { return }
|
||||
// Set up the capture session.
|
||||
}
|
||||
|
||||
private func getCameraDeviceId() -> String? {
|
||||
let deviceTypes: [AVCaptureDevice.DeviceType] = [
|
||||
.builtInWideAngleCamera
|
||||
]
|
||||
let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: deviceTypes, mediaType: .video, position: .back)
|
||||
|
||||
let device = discoverySession.devices.first
|
||||
|
||||
return device?.uniqueID
|
||||
}
|
||||
|
||||
@IBAction
|
||||
func toggleRecord(_ button: UIButton) {
|
||||
if button.title(for: .normal) == "Stop" {
|
||||
|
||||
cameraView.stopRecording(promise: Promise(
|
||||
resolver: { result in
|
||||
print("result")
|
||||
}, rejecter: { code, message, cause in
|
||||
print("error")
|
||||
}))
|
||||
|
||||
button.setTitle("Record", for: .normal)
|
||||
button.configuration = .filled()
|
||||
|
||||
} else {
|
||||
cameraView.startRecording(
|
||||
options: [
|
||||
"fileType": "mp4",
|
||||
"videoCodec": "h265",
|
||||
],
|
||||
filePath: filePath) { callback in
|
||||
print("callback", callback)
|
||||
}
|
||||
|
||||
button.setTitle("Stop", for: .normal)
|
||||
button.configuration = .bordered()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import AVFoundation
|
||||
import Foundation
|
||||
|
||||
struct RecordVideoOptions {
|
||||
var fileType: AVFileType = .mov
|
||||
var fileType: AVFileType = .mp4
|
||||
var flash: Torch = .off
|
||||
var codec: AVVideoCodecType?
|
||||
/**
|
||||
|
@@ -7,6 +7,79 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
B31481772C46547B00084A26 /* CameraViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518125E0102000DB86D6 /* CameraViewManager.swift */; };
|
||||
B31481782C46558C00084A26 /* CameraView+TakePhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517125E0102000DB86D6 /* CameraView+TakePhoto.swift */; };
|
||||
B31481792C46559700084A26 /* CameraView+Focus.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A1AEC52AD7F08E00169C0D /* CameraView+Focus.swift */; };
|
||||
B3AF8E862C410FB700CC198C /* ReactStubs.m in Sources */ = {isa = PBXBuildFile; fileRef = B3AF8E852C410FB700CC198C /* ReactStubs.m */; };
|
||||
B3AF8E882C41159300CC198C /* ChunkedRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3AF8E872C41159300CC198C /* ChunkedRecorder.swift */; };
|
||||
B3AF8E892C41159300CC198C /* ChunkedRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3AF8E872C41159300CC198C /* ChunkedRecorder.swift */; };
|
||||
B3EF9F0D2C3FBD8300832EE7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EF9F0C2C3FBD8300832EE7 /* AppDelegate.swift */; };
|
||||
B3EF9F0F2C3FBD8300832EE7 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EF9F0E2C3FBD8300832EE7 /* SceneDelegate.swift */; };
|
||||
B3EF9F112C3FBD8300832EE7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EF9F102C3FBD8300832EE7 /* ViewController.swift */; };
|
||||
B3EF9F142C3FBD8300832EE7 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = B3EF9F132C3FBD8300832EE7 /* Base */; };
|
||||
B3EF9F162C3FBD8400832EE7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B3EF9F152C3FBD8400832EE7 /* Assets.xcassets */; };
|
||||
B3EF9F192C3FBD8400832EE7 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = B3EF9F182C3FBD8400832EE7 /* Base */; };
|
||||
B3EF9F1E2C3FBDCF00832EE7 /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518425E0102000DB86D6 /* CameraView.swift */; };
|
||||
B3EF9F1F2C3FBDDC00832EE7 /* ReactLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516F25E0102000DB86D6 /* ReactLogger.swift */; };
|
||||
B3EF9F212C3FBDFC00832EE7 /* ReactStubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3EF9F202C3FBDFC00832EE7 /* ReactStubs.swift */; };
|
||||
B3EF9F222C3FBE8200832EE7 /* CameraConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88685E62AD698DF00E93869 /* CameraConfiguration.swift */; };
|
||||
B3EF9F232C3FBE8B00832EE7 /* VideoStabilizationMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85882332AD969E000317161 /* VideoStabilizationMode.swift */; };
|
||||
B3EF9F242C3FBEBC00832EE7 /* CameraError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518325E0102000DB86D6 /* CameraError.swift */; };
|
||||
B3EF9F252C3FBED900832EE7 /* Orientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88103DE2AD6FB230087F063 /* Orientation.swift */; };
|
||||
B3EF9F262C3FBEEA00832EE7 /* CameraDeviceFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85882312AD966FC00317161 /* CameraDeviceFormat.swift */; };
|
||||
B3EF9F272C3FBEF800832EE7 /* PixelFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = B87B11BE2A8E63B700732EBF /* PixelFormat.swift */; };
|
||||
B3EF9F282C3FBF1900832EE7 /* JSUnionValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85882372AD96B4400317161 /* JSUnionValue.swift */; };
|
||||
B3EF9F292C3FBF2500832EE7 /* Torch.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88103E02AD7046E0087F063 /* Torch.swift */; };
|
||||
B3EF9F2A2C3FBF3400832EE7 /* CodeScannerOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8FF60AD2ACC9731009D612F /* CodeScannerOptions.swift */; };
|
||||
B3EF9F2B2C3FBF4100832EE7 /* AVMetadataObject.ObjectType+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8FF60B02ACC981B009D612F /* AVMetadataObject.ObjectType+descriptor.swift */; };
|
||||
B3EF9F2C2C3FBF4A00832EE7 /* EnumParserError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517325E0102000DB86D6 /* EnumParserError.swift */; };
|
||||
B3EF9F2D2C3FBF9600832EE7 /* CameraSessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88103E22AD7065C0087F063 /* CameraSessionDelegate.swift */; };
|
||||
B3EF9F2E2C3FBFA600832EE7 /* CameraSession+CodeScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88685EC2AD6A5E600E93869 /* CameraSession+CodeScanner.swift */; };
|
||||
B3EF9F2F2C3FBFB200832EE7 /* CameraSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88685E42AD68D9300E93869 /* CameraSession.swift */; };
|
||||
B3EF9F302C3FBFBB00832EE7 /* RecordingSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BC9263DC4D8004C18D7 /* RecordingSession.swift */; };
|
||||
B3EF9F312C3FBFD500832EE7 /* AVAssetWriter.Status+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BC7263DC28C004C18D7 /* AVAssetWriter.Status+descriptor.swift */; };
|
||||
B3EF9F322C3FBFF100832EE7 /* CameraQueues.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84760DE2608F57D004C3180 /* CameraQueues.swift */; };
|
||||
B3EF9F332C3FC00900832EE7 /* CameraSession+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A1AEC72AD8005400169C0D /* CameraSession+Configuration.swift */; };
|
||||
B3EF9F362C3FC05600832EE7 /* ResizeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80175EB2ABDEBD000E7DE90 /* ResizeMode.swift */; };
|
||||
B3EF9F372C3FC0CA00832EE7 /* CameraView+Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518225E0102000DB86D6 /* CameraView+Zoom.swift */; };
|
||||
B3EF9F382C3FC0D900832EE7 /* PreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83D5EE629377117000AFD2F /* PreviewView.swift */; };
|
||||
B3EF9F3A2C3FC2EB00832EE7 /* AutoFocusSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B85882352AD96AFF00317161 /* AutoFocusSystem.swift */; };
|
||||
B3EF9F3C2C3FC30D00832EE7 /* AVCaptureDevice.Position+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517C25E0102000DB86D6 /* AVCaptureDevice.Position+descriptor.swift */; };
|
||||
B3EF9F4A2C3FC31E00832EE7 /* AVFrameRateRange+includes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516725E0102000DB86D6 /* AVFrameRateRange+includes.swift */; };
|
||||
B3EF9F4B2C3FC31E00832EE7 /* AVAssetWriterInputPixelBufferAdaptor+initWithVideoSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8D22CDB2642DB4D00234472 /* AVAssetWriterInputPixelBufferAdaptor+initWithVideoSettings.swift */; };
|
||||
B3EF9F4C2C3FC31E00832EE7 /* AVAudioSession+updateCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80E069F266632F000728644 /* AVAudioSession+updateCategory.swift */; };
|
||||
B3EF9F4D2C3FC31E00832EE7 /* AVCaptureVideoDataOutput+findPixelFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = B881D35F2ABC8E4E009B21C8 /* AVCaptureVideoDataOutput+findPixelFormat.swift */; };
|
||||
B3EF9F4E2C3FC31E00832EE7 /* AVCaptureOutput+mirror.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516825E0102000DB86D6 /* AVCaptureOutput+mirror.swift */; };
|
||||
B3EF9F4F2C3FC31E00832EE7 /* Collection+safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516225E0102000DB86D6 /* Collection+safe.swift */; };
|
||||
B3EF9F502C3FC31E00832EE7 /* AVCaptureVideoDataOutput+recommendedVideoSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8207AAE2B0E67460002990F /* AVCaptureVideoDataOutput+recommendedVideoSettings.swift */; };
|
||||
B3EF9F512C3FC31E00832EE7 /* AVCaptureDevice+minFocusDistance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88977BD2B556DBA0095C92C /* AVCaptureDevice+minFocusDistance.swift */; };
|
||||
B3EF9F522C3FC31E00832EE7 /* AVCaptureDevice+physicalDevices.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516625E0102000DB86D6 /* AVCaptureDevice+physicalDevices.swift */; };
|
||||
B3EF9F532C3FC31E00832EE7 /* AVCaptureDevice+neutralZoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516325E0102000DB86D6 /* AVCaptureDevice+neutralZoom.swift */; };
|
||||
B3EF9F542C3FC31E00832EE7 /* AVCaptureDevice.Format+dimensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B81BE1BE26B936FF002696CC /* AVCaptureDevice.Format+dimensions.swift */; };
|
||||
B3EF9F552C3FC31E00832EE7 /* AVCaptureVideoDataOutput+pixelFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A1AEC32AD7EDE800169C0D /* AVCaptureVideoDataOutput+pixelFormat.swift */; };
|
||||
B3EF9F562C3FC31E00832EE7 /* AVCaptureSession+synchronizeBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8207AAC2B0E5DD70002990F /* AVCaptureSession+synchronizeBuffer.swift */; };
|
||||
B3EF9F572C3FC31E00832EE7 /* AVCaptureDevice+isMultiCam.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516525E0102000DB86D6 /* AVCaptureDevice+isMultiCam.swift */; };
|
||||
B3EF9F582C3FC31E00832EE7 /* AVCaptureDevice+toDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B881D35D2ABC775E009B21C8 /* AVCaptureDevice+toDictionary.swift */; };
|
||||
B3EF9F592C3FC31E00832EE7 /* AVCaptureDevice.Format+toDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887516A25E0102000DB86D6 /* AVCaptureDevice.Format+toDictionary.swift */; };
|
||||
B3EF9F5A2C3FC31E00832EE7 /* CMVideoDimensions+toCGSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8F127CF2ACF054A00B39EA3 /* CMVideoDimensions+toCGSize.swift */; };
|
||||
B3EF9F5B2C3FC33000832EE7 /* AVCaptureDevice.DeviceType+physicalDeviceDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517A25E0102000DB86D6 /* AVCaptureDevice.DeviceType+physicalDeviceDescriptor.swift */; };
|
||||
B3EF9F5C2C3FC33E00832EE7 /* RecordVideoOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A1AEC92AD8034E00169C0D /* RecordVideoOptions.swift */; };
|
||||
B3EF9F5D2C3FC34600832EE7 /* Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8A1AECB2AD803B200169C0D /* Video.swift */; };
|
||||
B3EF9F5E2C3FC43000832EE7 /* AVCapturePhotoOutput.QualityPrioritization+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517925E0102000DB86D6 /* AVCapturePhotoOutput.QualityPrioritization+descriptor.swift */; };
|
||||
B3EF9F5F2C3FC43000832EE7 /* AVAuthorizationStatus+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517B25E0102000DB86D6 /* AVAuthorizationStatus+descriptor.swift */; };
|
||||
B3EF9F602C3FC43000832EE7 /* AVCaptureDevice.FlashMode+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517E25E0102000DB86D6 /* AVCaptureDevice.FlashMode+descriptor.swift */; };
|
||||
B3EF9F612C3FC43000832EE7 /* AVFileType+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8DB3BCB263DC97E004C18D7 /* AVFileType+descriptor.swift */; };
|
||||
B3EF9F622C3FC43000832EE7 /* AVVideoCodecType+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517525E0102000DB86D6 /* AVVideoCodecType+descriptor.swift */; };
|
||||
B3EF9F632C3FC43000832EE7 /* AVCaptureDevice.TorchMode+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517725E0102000DB86D6 /* AVCaptureDevice.TorchMode+descriptor.swift */; };
|
||||
B3EF9F642C3FC43000832EE7 /* AVCaptureDevice.Format.AutoFocusSystem+descriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517F25E0102000DB86D6 /* AVCaptureDevice.Format.AutoFocusSystem+descriptor.swift */; };
|
||||
B3EF9F652C3FC43C00832EE7 /* CameraSession+Audio.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88103DA2AD6F0A00087F063 /* CameraSession+Audio.swift */; };
|
||||
B3EF9F662C3FC44B00832EE7 /* CameraSession+Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88685E82AD6A5D600E93869 /* CameraSession+Video.swift */; };
|
||||
B3EF9F672C3FC44B00832EE7 /* CameraSession+Photo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88685EA2AD6A5DE00E93869 /* CameraSession+Photo.swift */; };
|
||||
B3EF9F682C3FC44B00832EE7 /* CameraSession+Focus.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88103DC2AD6F62C0087F063 /* CameraSession+Focus.swift */; };
|
||||
B3EF9F692C3FC44B00832EE7 /* PhotoCaptureDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887515C25E0102000DB86D6 /* PhotoCaptureDelegate.swift */; };
|
||||
B3EF9F6A2C3FC46900832EE7 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887517025E0102000DB86D6 /* Promise.swift */; };
|
||||
B3EF9F6B2C3FD35600832EE7 /* CameraView+RecordVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887515D25E0102000DB86D6 /* CameraView+RecordVideo.swift */; };
|
||||
B3EF9F6C2C3FD36800832EE7 /* Callback.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8BD3BA1266E22D2006C80A2 /* Callback.swift */; };
|
||||
B80175EC2ABDEBD000E7DE90 /* ResizeMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80175EB2ABDEBD000E7DE90 /* ResizeMode.swift */; };
|
||||
B80C0E00260BDDF7001699AB /* FrameProcessorPluginRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = B80C0DFF260BDDF7001699AB /* FrameProcessorPluginRegistry.m */; };
|
||||
B80E06A0266632F000728644 /* AVAudioSession+updateCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B80E069F266632F000728644 /* AVAudioSession+updateCategory.swift */; };
|
||||
@@ -94,6 +167,19 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134814201AA4EA6300B7C361 /* libVisionCamera.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libVisionCamera.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B3AF8E832C410FB600CC198C /* TestRecorder-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestRecorder-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
B3AF8E842C410FB700CC198C /* ReactStubs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReactStubs.h; sourceTree = "<group>"; };
|
||||
B3AF8E852C410FB700CC198C /* ReactStubs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactStubs.m; sourceTree = "<group>"; };
|
||||
B3AF8E872C41159300CC198C /* ChunkedRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChunkedRecorder.swift; sourceTree = "<group>"; };
|
||||
B3EF9F0A2C3FBD8300832EE7 /* TestRecorder.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestRecorder.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B3EF9F0C2C3FBD8300832EE7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
B3EF9F0E2C3FBD8300832EE7 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
B3EF9F102C3FBD8300832EE7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
B3EF9F132C3FBD8300832EE7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
B3EF9F152C3FBD8400832EE7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
B3EF9F182C3FBD8400832EE7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
B3EF9F1A2C3FBD8400832EE7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
B3EF9F202C3FBDFC00832EE7 /* ReactStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactStubs.swift; sourceTree = "<group>"; };
|
||||
B80175EB2ABDEBD000E7DE90 /* ResizeMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResizeMode.swift; sourceTree = "<group>"; };
|
||||
B80C02EB2A6A954D001975E2 /* FrameProcessorPluginHostObject.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FrameProcessorPluginHostObject.mm; sourceTree = "<group>"; };
|
||||
B80C02EC2A6A9552001975E2 /* FrameProcessorPluginHostObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameProcessorPluginHostObject.h; sourceTree = "<group>"; };
|
||||
@@ -191,6 +277,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B3EF9F072C3FBD8300832EE7 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@@ -221,10 +314,30 @@
|
||||
B887516125E0102000DB86D6 /* Extensions */,
|
||||
B887517225E0102000DB86D6 /* Parsers */,
|
||||
B887516D25E0102000DB86D6 /* React Utils */,
|
||||
B3EF9F0B2C3FBD8300832EE7 /* TestRecorder */,
|
||||
134814211AA4EA7D00B7C361 /* Products */,
|
||||
B3EF9F0A2C3FBD8300832EE7 /* TestRecorder.app */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3EF9F0B2C3FBD8300832EE7 /* TestRecorder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B3EF9F0C2C3FBD8300832EE7 /* AppDelegate.swift */,
|
||||
B3EF9F0E2C3FBD8300832EE7 /* SceneDelegate.swift */,
|
||||
B3EF9F102C3FBD8300832EE7 /* ViewController.swift */,
|
||||
B3EF9F202C3FBDFC00832EE7 /* ReactStubs.swift */,
|
||||
B3AF8E842C410FB700CC198C /* ReactStubs.h */,
|
||||
B3AF8E852C410FB700CC198C /* ReactStubs.m */,
|
||||
B3AF8E832C410FB600CC198C /* TestRecorder-Bridging-Header.h */,
|
||||
B3EF9F122C3FBD8300832EE7 /* Main.storyboard */,
|
||||
B3EF9F152C3FBD8400832EE7 /* Assets.xcassets */,
|
||||
B3EF9F172C3FBD8400832EE7 /* LaunchScreen.storyboard */,
|
||||
B3EF9F1A2C3FBD8400832EE7 /* Info.plist */,
|
||||
);
|
||||
path = TestRecorder;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B80175EA2ABDEBBB00E7DE90 /* Types */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -257,6 +370,7 @@
|
||||
B88103E22AD7065C0087F063 /* CameraSessionDelegate.swift */,
|
||||
B83D5EE629377117000AFD2F /* PreviewView.swift */,
|
||||
B8DB3BC9263DC4D8004C18D7 /* RecordingSession.swift */,
|
||||
B3AF8E872C41159300CC198C /* ChunkedRecorder.swift */,
|
||||
B887515C25E0102000DB86D6 /* PhotoCaptureDelegate.swift */,
|
||||
B84760DE2608F57D004C3180 /* CameraQueues.swift */,
|
||||
B887518325E0102000DB86D6 /* CameraError.swift */,
|
||||
@@ -366,18 +480,42 @@
|
||||
productReference = 134814201AA4EA6300B7C361 /* libVisionCamera.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
B3EF9F092C3FBD8300832EE7 /* TestRecorder */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B3EF9F1D2C3FBD8400832EE7 /* Build configuration list for PBXNativeTarget "TestRecorder" */;
|
||||
buildPhases = (
|
||||
B3EF9F062C3FBD8300832EE7 /* Sources */,
|
||||
B3EF9F072C3FBD8300832EE7 /* Frameworks */,
|
||||
B3EF9F082C3FBD8300832EE7 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = TestRecorder;
|
||||
productName = TestRecorder;
|
||||
productReference = B3EF9F0A2C3FBD8300832EE7 /* TestRecorder.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
58B511D31A9E6C8500147676 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1540;
|
||||
LastUpgradeCheck = 1240;
|
||||
ORGANIZATIONNAME = mrousavy;
|
||||
TargetAttributes = {
|
||||
58B511DA1A9E6C8500147676 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
};
|
||||
B3EF9F092C3FBD8300832EE7 = {
|
||||
CreatedOnToolsVersion = 15.4;
|
||||
DevelopmentTeam = HP3AMBWJGS;
|
||||
LastSwiftMigration = 1540;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "VisionCamera" */;
|
||||
@@ -387,6 +525,7 @@
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 58B511D21A9E6C8500147676;
|
||||
productRefGroup = 58B511D21A9E6C8500147676;
|
||||
@@ -394,10 +533,24 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
58B511DA1A9E6C8500147676 /* VisionCamera */,
|
||||
B3EF9F092C3FBD8300832EE7 /* TestRecorder */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
B3EF9F082C3FBD8300832EE7 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B3EF9F162C3FBD8400832EE7 /* Assets.xcassets in Resources */,
|
||||
B3EF9F192C3FBD8400832EE7 /* Base in Resources */,
|
||||
B3EF9F142C3FBD8300832EE7 /* Base in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
B80D6CAB25F770FE006F2CB7 /* Run SwiftFormat */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -490,6 +643,7 @@
|
||||
B88977BE2B556DBA0095C92C /* AVCaptureDevice+minFocusDistance.swift in Sources */,
|
||||
B80175EC2ABDEBD000E7DE90 /* ResizeMode.swift in Sources */,
|
||||
B887519F25E0102000DB86D6 /* AVCaptureDevice.DeviceType+physicalDeviceDescriptor.swift in Sources */,
|
||||
B3AF8E882C41159300CC198C /* ChunkedRecorder.swift in Sources */,
|
||||
B88685ED2AD6A5E600E93869 /* CameraSession+CodeScanner.swift in Sources */,
|
||||
B8207AAD2B0E5DD70002990F /* AVCaptureSession+synchronizeBuffer.swift in Sources */,
|
||||
B8D22CDC2642DB4D00234472 /* AVAssetWriterInputPixelBufferAdaptor+initWithVideoSettings.swift in Sources */,
|
||||
@@ -516,8 +670,103 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B3EF9F062C3FBD8300832EE7 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B3EF9F372C3FC0CA00832EE7 /* CameraView+Zoom.swift in Sources */,
|
||||
B3EF9F232C3FBE8B00832EE7 /* VideoStabilizationMode.swift in Sources */,
|
||||
B3EF9F4A2C3FC31E00832EE7 /* AVFrameRateRange+includes.swift in Sources */,
|
||||
B3EF9F6A2C3FC46900832EE7 /* Promise.swift in Sources */,
|
||||
B3EF9F4B2C3FC31E00832EE7 /* AVAssetWriterInputPixelBufferAdaptor+initWithVideoSettings.swift in Sources */,
|
||||
B3EF9F5E2C3FC43000832EE7 /* AVCapturePhotoOutput.QualityPrioritization+descriptor.swift in Sources */,
|
||||
B3AF8E892C41159300CC198C /* ChunkedRecorder.swift in Sources */,
|
||||
B3EF9F5F2C3FC43000832EE7 /* AVAuthorizationStatus+descriptor.swift in Sources */,
|
||||
B3EF9F602C3FC43000832EE7 /* AVCaptureDevice.FlashMode+descriptor.swift in Sources */,
|
||||
B3EF9F612C3FC43000832EE7 /* AVFileType+descriptor.swift in Sources */,
|
||||
B3EF9F622C3FC43000832EE7 /* AVVideoCodecType+descriptor.swift in Sources */,
|
||||
B3EF9F632C3FC43000832EE7 /* AVCaptureDevice.TorchMode+descriptor.swift in Sources */,
|
||||
B3EF9F642C3FC43000832EE7 /* AVCaptureDevice.Format.AutoFocusSystem+descriptor.swift in Sources */,
|
||||
B3EF9F4C2C3FC31E00832EE7 /* AVAudioSession+updateCategory.swift in Sources */,
|
||||
B3EF9F4D2C3FC31E00832EE7 /* AVCaptureVideoDataOutput+findPixelFormat.swift in Sources */,
|
||||
B3EF9F4E2C3FC31E00832EE7 /* AVCaptureOutput+mirror.swift in Sources */,
|
||||
B3EF9F4F2C3FC31E00832EE7 /* Collection+safe.swift in Sources */,
|
||||
B3EF9F502C3FC31E00832EE7 /* AVCaptureVideoDataOutput+recommendedVideoSettings.swift in Sources */,
|
||||
B3EF9F512C3FC31E00832EE7 /* AVCaptureDevice+minFocusDistance.swift in Sources */,
|
||||
B3EF9F5B2C3FC33000832EE7 /* AVCaptureDevice.DeviceType+physicalDeviceDescriptor.swift in Sources */,
|
||||
B31481792C46559700084A26 /* CameraView+Focus.swift in Sources */,
|
||||
B31481772C46547B00084A26 /* CameraViewManager.swift in Sources */,
|
||||
B3EF9F522C3FC31E00832EE7 /* AVCaptureDevice+physicalDevices.swift in Sources */,
|
||||
B3EF9F532C3FC31E00832EE7 /* AVCaptureDevice+neutralZoom.swift in Sources */,
|
||||
B3EF9F542C3FC31E00832EE7 /* AVCaptureDevice.Format+dimensions.swift in Sources */,
|
||||
B3EF9F552C3FC31E00832EE7 /* AVCaptureVideoDataOutput+pixelFormat.swift in Sources */,
|
||||
B3EF9F562C3FC31E00832EE7 /* AVCaptureSession+synchronizeBuffer.swift in Sources */,
|
||||
B3EF9F572C3FC31E00832EE7 /* AVCaptureDevice+isMultiCam.swift in Sources */,
|
||||
B3EF9F582C3FC31E00832EE7 /* AVCaptureDevice+toDictionary.swift in Sources */,
|
||||
B3EF9F592C3FC31E00832EE7 /* AVCaptureDevice.Format+toDictionary.swift in Sources */,
|
||||
B3EF9F5A2C3FC31E00832EE7 /* CMVideoDimensions+toCGSize.swift in Sources */,
|
||||
B3EF9F212C3FBDFC00832EE7 /* ReactStubs.swift in Sources */,
|
||||
B3EF9F5C2C3FC33E00832EE7 /* RecordVideoOptions.swift in Sources */,
|
||||
B3EF9F6B2C3FD35600832EE7 /* CameraView+RecordVideo.swift in Sources */,
|
||||
B3EF9F222C3FBE8200832EE7 /* CameraConfiguration.swift in Sources */,
|
||||
B3EF9F282C3FBF1900832EE7 /* JSUnionValue.swift in Sources */,
|
||||
B3EF9F332C3FC00900832EE7 /* CameraSession+Configuration.swift in Sources */,
|
||||
B3EF9F362C3FC05600832EE7 /* ResizeMode.swift in Sources */,
|
||||
B3EF9F312C3FBFD500832EE7 /* AVAssetWriter.Status+descriptor.swift in Sources */,
|
||||
B3EF9F292C3FBF2500832EE7 /* Torch.swift in Sources */,
|
||||
B31481782C46558C00084A26 /* CameraView+TakePhoto.swift in Sources */,
|
||||
B3EF9F2C2C3FBF4A00832EE7 /* EnumParserError.swift in Sources */,
|
||||
B3EF9F272C3FBEF800832EE7 /* PixelFormat.swift in Sources */,
|
||||
B3EF9F652C3FC43C00832EE7 /* CameraSession+Audio.swift in Sources */,
|
||||
B3EF9F382C3FC0D900832EE7 /* PreviewView.swift in Sources */,
|
||||
B3EF9F3A2C3FC2EB00832EE7 /* AutoFocusSystem.swift in Sources */,
|
||||
B3EF9F112C3FBD8300832EE7 /* ViewController.swift in Sources */,
|
||||
B3EF9F5D2C3FC34600832EE7 /* Video.swift in Sources */,
|
||||
B3EF9F2B2C3FBF4100832EE7 /* AVMetadataObject.ObjectType+descriptor.swift in Sources */,
|
||||
B3AF8E862C410FB700CC198C /* ReactStubs.m in Sources */,
|
||||
B3EF9F0D2C3FBD8300832EE7 /* AppDelegate.swift in Sources */,
|
||||
B3EF9F2D2C3FBF9600832EE7 /* CameraSessionDelegate.swift in Sources */,
|
||||
B3EF9F262C3FBEEA00832EE7 /* CameraDeviceFormat.swift in Sources */,
|
||||
B3EF9F242C3FBEBC00832EE7 /* CameraError.swift in Sources */,
|
||||
B3EF9F2E2C3FBFA600832EE7 /* CameraSession+CodeScanner.swift in Sources */,
|
||||
B3EF9F252C3FBED900832EE7 /* Orientation.swift in Sources */,
|
||||
B3EF9F662C3FC44B00832EE7 /* CameraSession+Video.swift in Sources */,
|
||||
B3EF9F672C3FC44B00832EE7 /* CameraSession+Photo.swift in Sources */,
|
||||
B3EF9F682C3FC44B00832EE7 /* CameraSession+Focus.swift in Sources */,
|
||||
B3EF9F6C2C3FD36800832EE7 /* Callback.swift in Sources */,
|
||||
B3EF9F692C3FC44B00832EE7 /* PhotoCaptureDelegate.swift in Sources */,
|
||||
B3EF9F302C3FBFBB00832EE7 /* RecordingSession.swift in Sources */,
|
||||
B3EF9F322C3FBFF100832EE7 /* CameraQueues.swift in Sources */,
|
||||
B3EF9F2F2C3FBFB200832EE7 /* CameraSession.swift in Sources */,
|
||||
B3EF9F2A2C3FBF3400832EE7 /* CodeScannerOptions.swift in Sources */,
|
||||
B3EF9F0F2C3FBD8300832EE7 /* SceneDelegate.swift in Sources */,
|
||||
B3EF9F1E2C3FBDCF00832EE7 /* CameraView.swift in Sources */,
|
||||
B3EF9F3C2C3FC30D00832EE7 /* AVCaptureDevice.Position+descriptor.swift in Sources */,
|
||||
B3EF9F1F2C3FBDDC00832EE7 /* ReactLogger.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
B3EF9F122C3FBD8300832EE7 /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
B3EF9F132C3FBD8300832EE7 /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3EF9F172C3FBD8400832EE7 /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
B3EF9F182C3FBD8400832EE7 /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
58B511ED1A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
@@ -660,6 +909,94 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B3EF9F1B2C3FBD8400832EE7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = HP3AMBWJGS;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = TestRecorder/Info.plist;
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "Record form camera";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Record from microphone";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = camera.TestRecorder;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "TestRecorder/TestRecorder-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B3EF9F1C2C3FBD8400832EE7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = HP3AMBWJGS;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = TestRecorder/Info.plist;
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "Record form camera";
|
||||
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Record from microphone";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||
INFOPLIST_KEY_UIMainStoryboardFile = Main;
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = camera.TestRecorder;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "TestRecorder/TestRecorder-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@@ -681,6 +1018,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
B3EF9F1D2C3FBD8400832EE7 /* Build configuration list for PBXNativeTarget "TestRecorder" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B3EF9F1B2C3FBD8400832EE7 /* Debug */,
|
||||
B3EF9F1C2C3FBD8400832EE7 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
|
||||
|
@@ -26,6 +26,9 @@ interface OnErrorEvent {
|
||||
message: string
|
||||
cause?: ErrorWithCause
|
||||
}
|
||||
interface OnInitReadyEvent {
|
||||
filepath: string
|
||||
}
|
||||
interface OnVideoChunkReadyEvent {
|
||||
filepath: string
|
||||
index: number
|
||||
@@ -39,6 +42,7 @@ type NativeCameraViewProps = Omit<CameraProps, 'device' | 'onInitialized' | 'onE
|
||||
onCodeScanned?: (event: NativeSyntheticEvent<OnCodeScannedEvent>) => void
|
||||
onStarted?: (event: NativeSyntheticEvent<void>) => void
|
||||
onStopped?: (event: NativeSyntheticEvent<void>) => void
|
||||
onInitReady?: (event: NativeSyntheticEvent<OnInitReadyEvent>) => void
|
||||
onVideoChunkReady?: (event: NativeSyntheticEvent<OnVideoChunkReadyEvent>) => void
|
||||
onViewReady: () => void
|
||||
}
|
||||
|
Reference in New Issue
Block a user