diff --git a/apps/example/app.json b/apps/example/app.json index db73dc6d8..73135e124 100644 --- a/apps/example/app.json +++ b/apps/example/app.json @@ -27,7 +27,18 @@ ] }, "ios": { - "metalAPIValidation": false + "metalAPIValidation": false, + "infoPlist": { + "NSCameraUsageDescription": "$(PRODUCT_NAME) needs access to your Camera.", + "NSMicrophoneUsageDescription": "$(PRODUCT_NAME) needs access to your Microphone." + } + }, + "android": { + "permissions": [ + { "android:name": "android.permission.INTERNET" }, + { "android:name": "android.permission.CAMERA" }, + { "android:name": "android.permission.RECORD_AUDIO" } + ] }, "macos": { "metalAPIValidation": false diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock index 87a3ba3cc..e21cd966e 100644 --- a/apps/example/ios/Podfile.lock +++ b/apps/example/ios/Podfile.lock @@ -8,6 +8,65 @@ PODS: - hermes-engine (0.81.4): - hermes-engine/Pre-built (= 0.81.4) - hermes-engine/Pre-built (0.81.4) + - NitroImage (0.14.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - NitroModules + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - NitroModules (0.35.7): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - RCT-Folly (2024.11.18.00): - boost - DoubleConversion @@ -2460,7 +2519,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNReanimated (4.3.1): + - RNReanimated (4.2.1): - boost - DoubleConversion - fast_float @@ -2487,12 +2546,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/apple (= 4.3.1) - - RNReanimated/common (= 4.3.1) + - RNReanimated/reanimated (= 4.2.1) - RNWorklets - SocketRocket - Yoga - - RNReanimated/apple (4.3.1): + - RNReanimated/reanimated (4.2.1): - boost - DoubleConversion - fast_float @@ -2519,10 +2577,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core + - RNReanimated/reanimated/apple (= 4.2.1) - RNWorklets - SocketRocket - Yoga - - RNReanimated/common (4.3.1): + - RNReanimated/reanimated/apple (4.2.1): - boost - DoubleConversion - fast_float @@ -2552,7 +2611,7 @@ PODS: - RNWorklets - SocketRocket - Yoga - - RNWorklets (0.8.3): + - RNWorklets (0.7.2): - boost - DoubleConversion - fast_float @@ -2579,11 +2638,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNWorklets/apple (= 0.8.3) - - RNWorklets/common (= 0.8.3) + - RNWorklets/worklets (= 0.7.2) - SocketRocket - Yoga - - RNWorklets/apple (0.8.3): + - RNWorklets/worklets (0.7.2): - boost - DoubleConversion - fast_float @@ -2610,9 +2668,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core + - RNWorklets/worklets/apple (= 0.7.2) - SocketRocket - Yoga - - RNWorklets/common (0.8.3): + - RNWorklets/worklets/apple (0.7.2): - boost - DoubleConversion - fast_float @@ -2642,6 +2701,37 @@ PODS: - SocketRocket - Yoga - SocketRocket (0.7.1) + - VisionCamera (5.0.10): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - NitroImage + - NitroModules + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-callinvoker + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - Yoga (0.0.0) DEPENDENCIES: @@ -2652,6 +2742,8 @@ DEPENDENCIES: - fmt (from `../../../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../../../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - NitroImage (from `../../../node_modules/react-native-nitro-image`) + - NitroModules (from `../../../node_modules/react-native-nitro-modules`) - RCT-Folly (from `../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTDeprecation (from `../../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`) - RCTRequired (from `../../../node_modules/react-native/Libraries/Required`) @@ -2726,6 +2818,7 @@ DEPENDENCIES: - RNReanimated (from `../../../node_modules/react-native-reanimated`) - RNWorklets (from `../../../node_modules/react-native-worklets`) - SocketRocket (~> 0.7.1) + - VisionCamera (from `../../../node_modules/react-native-vision-camera`) - Yoga (from `../../../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -2748,6 +2841,10 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2025-07-07-RNv0.81.0-e0fc67142ec0763c6b6153ca2bf96df815539782 + NitroImage: + :path: "../../../node_modules/react-native-nitro-image" + NitroModules: + :path: "../../../node_modules/react-native-nitro-modules" RCT-Folly: :podspec: "../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTDeprecation: @@ -2892,6 +2989,8 @@ EXTERNAL SOURCES: :path: "../../../node_modules/react-native-reanimated" RNWorklets: :path: "../../../node_modules/react-native-worklets" + VisionCamera: + :path: "../../../node_modules/react-native-vision-camera" Yoga: :path: "../../../node_modules/react-native/ReactCommon/yoga" @@ -2903,6 +3002,8 @@ SPEC CHECKSUMS: fmt: 530618a01105dae0fa3a2f27c81ae11fa8f67eac glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394 + NitroImage: 4ffcf183d975de179ae1662b7c3b4b3b37747c7e + NitroModules: 9ec4a2e0b9af22ba1f1f550e1dd9be94143afd18 RCT-Folly: b29feb752b08042c62badaef7d453f3bb5e6ae23 RCTDeprecation: c0ed3249a97243002615517dff789bf4666cf585 RCTRequired: 58719f5124f9267b5f9649c08bf23d9aea845b23 @@ -2973,9 +3074,10 @@ SPEC CHECKSUMS: ReactTestApp-DevSupport: 9b7bbba5e8fed998e763809171d9906a1375f9d3 ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf RNGestureHandler: e37bdb684df1ac17c7e1d8f71a3311b2793c186b - RNReanimated: 9d012d4031abc9df896f8a82f9928eb2b9eae417 - RNWorklets: 0da2552f9ff5d17506918a692304110cfebb9f0a + RNReanimated: 464375ff2caa801358547c44eca894ff0bf68e74 + RNWorklets: ee58e869ea579800ec5f2f1cb6ae195fd3537546 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 + VisionCamera: 8c913d0cb2c868f779035fb69a1e0ab69e10f1c3 Yoga: a3ed390a19db0459bd6839823a6ac6d9c6db198d PODFILE CHECKSUM: 22a8651333bf096f67ca333598bd33455d994c1f diff --git a/apps/example/package.json b/apps/example/package.json index bc1e36625..476341f0d 100644 --- a/apps/example/package.json +++ b/apps/example/package.json @@ -33,8 +33,11 @@ "react-native": "0.81.4", "react-native-gesture-handler": "^2.28.0", "react-native-macos": "^0.79.0", + "react-native-nitro-image": "0.14.0", + "react-native-nitro-modules": "0.35.7", "react-native-reanimated": "4.2.1", "react-native-safe-area-context": "^5.4.0", + "react-native-vision-camera": "5.0.10", "react-native-web": "^0.21.2", "react-native-wgpu": "*", "react-native-worklets": "0.7.2", diff --git a/apps/example/react-native.config.js b/apps/example/react-native.config.js index 45416343e..75794451e 100644 --- a/apps/example/react-native.config.js +++ b/apps/example/react-native.config.js @@ -19,6 +19,27 @@ const project = (() => { } })(); +// Workaround: react-native-nitro-image's NitroImagePackage extends +// BaseReactPackage, which @react-native-community/cli@13's autolinking regex +// does not detect. Without this override, autolinking returns android: null +// for nitro-image and vision-camera's gradle build fails with +// "Project with path ':react-native-nitro-image' could not be found". +const path = require("path"); + module.exports = { ...(project ? { project } : undefined), + dependencies: { + "react-native-nitro-image": { + platforms: { + android: { + sourceDir: path.join( + __dirname, + "../../node_modules/react-native-nitro-image/android", + ), + packageImportPath: "import com.margelo.nitro.image.NitroImagePackage;", + packageInstance: "new NitroImagePackage()", + }, + }, + }, + }, }; \ No newline at end of file diff --git a/apps/example/src/App.tsx b/apps/example/src/App.tsx index 0b26ab049..354a1c572 100644 --- a/apps/example/src/App.tsx +++ b/apps/example/src/App.tsx @@ -37,6 +37,7 @@ import { AsyncStarvation } from "./Diagnostics/AsyncStarvation"; import { DeviceLostHang } from "./Diagnostics/DeviceLostHang"; import { StorageBufferVertices } from "./StorageBufferVertices"; import { SharedTextureMemory } from "./SharedTextureMemory"; +import { Camera } from "./Camera"; // The two lines below are needed by three.js import "fast-text-encoding"; @@ -102,6 +103,7 @@ function App() { name="SharedTextureMemory" component={SharedTextureMemory} /> + diff --git a/apps/example/src/Camera/Camera.tsx b/apps/example/src/Camera/Camera.tsx new file mode 100644 index 000000000..b0e9529a2 --- /dev/null +++ b/apps/example/src/Camera/Camera.tsx @@ -0,0 +1,60 @@ +import React, { useEffect } from "react"; +import { StyleSheet, Text, View } from "react-native"; +import { + Camera as VisionCamera, + useCameraDevice, + useCameraPermission, +} from "react-native-vision-camera"; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: "black", + }, + camera: { + flex: 1, + }, + centered: { + flex: 1, + alignItems: "center", + justifyContent: "center", + padding: 24, + }, + message: { + color: "white", + textAlign: "center", + }, +}); + +export const Camera = () => { + const { hasPermission, requestPermission } = useCameraPermission(); + const device = useCameraDevice("back"); + + useEffect(() => { + if (!hasPermission) { + requestPermission(); + } + }, [hasPermission, requestPermission]); + + if (!hasPermission) { + return ( + + Requesting camera permission... + + ); + } + + if (device == null) { + return ( + + No camera device available. + + ); + } + + return ( + + + + ); +}; diff --git a/apps/example/src/Camera/index.ts b/apps/example/src/Camera/index.ts new file mode 100644 index 000000000..17290593b --- /dev/null +++ b/apps/example/src/Camera/index.ts @@ -0,0 +1 @@ +export { Camera } from "./Camera"; diff --git a/apps/example/src/Home.tsx b/apps/example/src/Home.tsx index 2db838041..74c153c0f 100644 --- a/apps/example/src/Home.tsx +++ b/apps/example/src/Home.tsx @@ -131,6 +131,10 @@ export const examples = [ screen: "SharedTextureMemory", title: "🎞️ Shared Texture Memory", }, + { + screen: "Camera", + title: "📷 Camera", + }, ]; const styles = StyleSheet.create({ diff --git a/apps/example/src/Route.ts b/apps/example/src/Route.ts index 1f2dbf187..5c43b2a36 100644 --- a/apps/example/src/Route.ts +++ b/apps/example/src/Route.ts @@ -30,4 +30,5 @@ export type Routes = { DeviceLostHang: undefined; StorageBufferVertices: undefined; SharedTextureMemory: undefined; + Camera: undefined; }; diff --git a/yarn.lock b/yarn.lock index f6a59461c..78e07a5b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4965,9 +4965,12 @@ __metadata: react-native: 0.81.4 react-native-gesture-handler: ^2.28.0 react-native-macos: ^0.79.0 + react-native-nitro-image: 0.14.0 + react-native-nitro-modules: 0.35.7 react-native-reanimated: 4.2.1 react-native-safe-area-context: ^5.4.0 react-native-test-app: 4.4.10 + react-native-vision-camera: 5.0.10 react-native-web: ^0.21.2 react-native-wgpu: "*" react-native-worklets: 0.7.2 @@ -12769,6 +12772,27 @@ __metadata: languageName: node linkType: hard +"react-native-nitro-image@npm:0.14.0": + version: 0.14.0 + resolution: "react-native-nitro-image@npm:0.14.0" + peerDependencies: + react: "*" + react-native: "*" + react-native-nitro-modules: "*" + checksum: ea5d19665bdffc8bb38fd5fef78a7d9c5f3f033cf0e0b6c224a39f718b863f3de74d776765eb7f5440743e985e2ea6c9ab210a1545947b0dcf02570408af5877 + languageName: node + linkType: hard + +"react-native-nitro-modules@npm:0.35.7": + version: 0.35.7 + resolution: "react-native-nitro-modules@npm:0.35.7" + peerDependencies: + react: "*" + react-native: "*" + checksum: 61f10d28b1e207361abef39b522259b1cee829ad4b0e44b07586119e3503e0aa460e2c7a514702a6cec7cc575db9614a5469d204865e23bb296c149dff0e8b95 + languageName: node + linkType: hard + "react-native-reanimated@npm:4.2.1, react-native-reanimated@npm:^4.2.1": version: 4.2.1 resolution: "react-native-reanimated@npm:4.2.1" @@ -12858,6 +12882,18 @@ __metadata: languageName: node linkType: hard +"react-native-vision-camera@npm:5.0.10": + version: 5.0.10 + resolution: "react-native-vision-camera@npm:5.0.10" + peerDependencies: + react: "*" + react-native: "*" + react-native-nitro-image: "*" + react-native-nitro-modules: "*" + checksum: 52ffda9cbf8ec06e2156f86f48cabe5fd83e76d6fd6c939b85fe50814e26d8af1796ddb22ceb58fd21017c615f40e5e559a74034b8b5224a05b790650f8f4d95 + languageName: node + linkType: hard + "react-native-web@npm:^0.21.2": version: 0.21.2 resolution: "react-native-web@npm:0.21.2"