Skip to content
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

feat: Expose .external and .continuityCamera devices #3065

Merged
merged 4 commits into from
Jul 10, 2024
Merged
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
16 changes: 8 additions & 8 deletions package/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1391,16 +1391,16 @@ PODS:
- ReactCommon/turbomodule/core
- Yoga
- SocketRocket (0.7.0)
- VisionCamera (4.4.0):
- VisionCamera/Core (= 4.4.0)
- VisionCamera/FrameProcessors (= 4.4.0)
- VisionCamera/React (= 4.4.0)
- VisionCamera/Core (4.4.0)
- VisionCamera/FrameProcessors (4.4.0):
- VisionCamera (4.4.1):
- VisionCamera/Core (= 4.4.1)
- VisionCamera/FrameProcessors (= 4.4.1)
- VisionCamera/React (= 4.4.1)
- VisionCamera/Core (4.4.1)
- VisionCamera/FrameProcessors (4.4.1):
- React
- React-callinvoker
- react-native-worklets-core
- VisionCamera/React (4.4.0):
- VisionCamera/React (4.4.1):
- React-Core
- VisionCamera/FrameProcessors
- Yoga (0.0.0)
Expand Down Expand Up @@ -1688,7 +1688,7 @@ SPEC CHECKSUMS:
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
RNVectorIcons: 2a2f79274248390b80684ea3c4400bd374a15c90
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
VisionCamera: 5b17187dd09e4c8bef7c0b1d5abebfb268ff703d
VisionCamera: 670bd7d5ec35b6e3bfaf9d48f4a102248291b00d
Yoga: 2f71ecf38d934aecb366e686278102a51679c308

PODFILE CHECKSUM: 49584be049764895189f1f88ebc9769116621103
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ extension AVCaptureDevice {
// 2. Add this device as an input
guard let input = try? AVCaptureDeviceInput(device: self) else {
VisionLogger.log(level: .error, message: "Cannot dynamically determine \(uniqueID)'s sensorOrientation, " +
"falling back to \(DEFAULT_SENSOR_ORIENTATION)...")
"because the AVCaptureDeviceInput cannot be created. Falling back to \(DEFAULT_SENSOR_ORIENTATION)...")
return DEFAULT_SENSOR_ORIENTATION
}
guard session.canAddInput(input) else {
VisionLogger.log(level: .error, message: "Cannot dynamically determine \(uniqueID)'s sensorOrientation, because " +
"it cannot be added to the temporary AVCaptureSession. Falling back to \(DEFAULT_SENSOR_ORIENTATION)...")
return DEFAULT_SENSOR_ORIENTATION
}
session.addInput(input)
Expand All @@ -43,6 +45,8 @@ extension AVCaptureDevice {
output.automaticallyConfiguresOutputBufferDimensions = false
output.deliversPreviewSizedOutputBuffers = true
guard session.canAddOutput(output) else {
VisionLogger.log(level: .error, message: "Cannot dynamically determine \(uniqueID)'s sensorOrientation, because " +
"the AVCaptureVideoDataOutput cannot be added to the AVCaptureSession. Falling back to \(DEFAULT_SENSOR_ORIENTATION)...")
return DEFAULT_SENSOR_ORIENTATION
}
session.addOutput(output)
Expand Down
28 changes: 17 additions & 11 deletions package/ios/React/CameraDevicesManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import AVFoundation
import Foundation

@objc(CameraDevicesManager)
class CameraDevicesManager: RCTEventEmitter {
final class CameraDevicesManager: RCTEventEmitter {
private let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: getAllDeviceTypes(),
mediaType: .video,
position: .unspecified)
Expand All @@ -32,17 +32,17 @@ class CameraDevicesManager: RCTEventEmitter {
return [devicesChangedEventName]
}

override class func requiresMainQueueSetup() -> Bool {
override static func requiresMainQueueSetup() -> Bool {
return false
}

override func constantsToExport() -> [AnyHashable: Any]! {
let devices = getDevicesJson()
let preferredDevice = getPreferredDevice()
let preferredDevice = getPreferredDeviceJson()

return [
"availableCameraDevices": devices,
"userPreferredCameraDevice": preferredDevice?.toDictionary() as Any,
"userPreferredCameraDevice": preferredDevice as Any,
]
}

Expand All @@ -52,6 +52,11 @@ class CameraDevicesManager: RCTEventEmitter {
}
}

private func getPreferredDeviceJson() -> [String: Any]? {
let preferredDevice = getPreferredDevice()
return preferredDevice?.toDictionary()
}

private func getPreferredDevice() -> AVCaptureDevice? {
#if swift(>=5.9)
if #available(iOS 17.0, *) {
Expand Down Expand Up @@ -80,13 +85,14 @@ class CameraDevicesManager: RCTEventEmitter {
deviceTypes.append(.builtInLiDARDepthCamera)
}

// iOS 17 specifics:
// This is only reported if `NSCameraUseExternalDeviceType` is set to true in Info.plist,
// otherwise external devices are just reported as wide-angle-cameras
// deviceTypes.append(.external)
// This is only reported if `NSCameraUseContinuityCameraDeviceType` is set to true in Info.plist,
// otherwise continuity camera devices are just reported as wide-angle-cameras
// deviceTypes.append(.continuityCamera)
if #available(iOS 17.0, *) {
// This is only reported if `NSCameraUseExternalDeviceType` is set to true in Info.plist,
// otherwise external devices are just reported as wide-angle-cameras
deviceTypes.append(.external)
// This is only reported if `NSCameraUseContinuityCameraDeviceType` is set to true in Info.plist,
// otherwise continuity camera devices are just reported as wide-angle-cameras
deviceTypes.append(.continuityCamera)
}

return deviceTypes
}
Expand Down
Loading