feat: Replace Reanimated with RN Worklets (#1468)
* Setup RN Worklets * Use RN Worklets on iOS * Fix console * Add `installFrameProcessorBindings()` function * Add `FrameProcessorPlugins` proxy (BREAKING CHANGE) * Clean up docs * Update FRAME_PROCESSORS.mdx * Use RN Worklets 0.2.5 * feat: Android build setup * Rewrite Android Frame Processor Part * Update CMakeLists.txt * fix: Add react-native-worklets Gradle dependency * Update Podfile.lock * fix build * gradle:7.4.1 * Init JSI Bindings in method on Android * Fix Folly flags * fix: Init `FrameProcessorRuntimeManager` later * fix: Wrap in `<GestureHandlerRootView>` * Refactor plugins * fix: Remove enableFrameProcessors * Install RN Worklets from current GH master * Update babel.config.js * Update CameraViewModule.kt * Update ImageProxyUtils.java * feat: Upgrade to Reanimated v3 * fix: Fix crash on Worklet init * Update RN Worklets to latest master * fix: Simplify FP Plugins Proxy
This commit is contained in:
@@ -12,8 +12,6 @@ import com.facebook.react.defaults.DefaultReactNativeHost;
|
||||
|
||||
import com.mrousavy.camera.CameraPackage;
|
||||
import com.mrousavy.camera.frameprocessor.FrameProcessorPlugin;
|
||||
import com.facebook.react.bridge.JSIModulePackage;
|
||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
@@ -47,11 +45,6 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
protected Boolean isHermesEnabled() {
|
||||
return BuildConfig.IS_HERMES_ENABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSIModulePackage getJSIModulePackage() {
|
||||
return new ReanimatedJSIModulePackage();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,7 +13,7 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle")
|
||||
classpath('com.android.tools.build:gradle:7.4.1')
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,8 @@ const pak = require('../package.json');
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
plugins: [
|
||||
[
|
||||
'react-native-reanimated/plugin',
|
||||
{
|
||||
globals: ['__example_plugin', '__example_plugin_swift'],
|
||||
},
|
||||
],
|
||||
['react-native-reanimated/plugin'],
|
||||
['react-native-worklets/plugin'],
|
||||
[
|
||||
'module-resolver',
|
||||
{
|
||||
|
||||
@@ -283,6 +283,10 @@ PODS:
|
||||
- react-native-video/Video (= 5.2.1)
|
||||
- react-native-video/Video (5.2.1):
|
||||
- React-Core
|
||||
- react-native-worklets (0.1.0):
|
||||
- React
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
- React-perflogger (0.71.2)
|
||||
- React-RCTActionSheet (0.71.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.71.2)
|
||||
@@ -369,7 +373,7 @@ PODS:
|
||||
- React-perflogger (= 0.71.2)
|
||||
- RNGestureHandler (2.9.0):
|
||||
- React-Core
|
||||
- RNReanimated (2.14.4):
|
||||
- RNReanimated (3.0.0-rc.10):
|
||||
- DoubleConversion
|
||||
- FBLazyVector
|
||||
- FBReactNativeSpec
|
||||
@@ -407,6 +411,7 @@ PODS:
|
||||
- React
|
||||
- React-callinvoker
|
||||
- React-Core
|
||||
- react-native-worklets
|
||||
- Yoga (1.14.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -437,6 +442,7 @@ DEPENDENCIES:
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
||||
- react-native-video (from `../node_modules/react-native-video`)
|
||||
- react-native-worklets (from `../node_modules/react-native-worklets`)
|
||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
@@ -514,6 +520,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-community/slider"
|
||||
react-native-video:
|
||||
:path: "../node_modules/react-native-video"
|
||||
react-native-worklets:
|
||||
:path: "../node_modules/react-native-worklets"
|
||||
React-perflogger:
|
||||
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
|
||||
React-RCTActionSheet:
|
||||
@@ -583,6 +591,7 @@ SPEC CHECKSUMS:
|
||||
react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
|
||||
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
|
||||
react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253
|
||||
react-native-worklets: c7576ad4ad0f030ff41e8d74ad0077c96054a6c1
|
||||
React-perflogger: c7ccda3d1d1da837f7ff4e54e816022a6803ee87
|
||||
React-RCTActionSheet: 01c125aebbad462a24228f68c584c7a921d6c28e
|
||||
React-RCTAnimation: 5277a9440acffc4a5b7baa6ae3880fe467277ae6
|
||||
@@ -597,11 +606,11 @@ SPEC CHECKSUMS:
|
||||
React-runtimeexecutor: 4bf9a9086d27f74065fce1dddac274aa95216952
|
||||
ReactCommon: f697c0ac52e999aa818e43e2b6f277787c735e2d
|
||||
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
|
||||
RNReanimated: cc5e3aa479cb9170bcccf8204291a6950a3be128
|
||||
RNReanimated: fbc356493970e3acddc15586b1bccb5eab3ff1ec
|
||||
RNScreens: ea4cd3a853063cda19a4e3c28d2e52180c80f4eb
|
||||
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
|
||||
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
|
||||
VisionCamera: b9345e7da5eff343cc1603dd19153e2b9acd0c07
|
||||
VisionCamera: 312151eb95370d1d764720de3b7dad33d8c7fb40
|
||||
Yoga: 5b0304b3dbef2b52e078052138e23a19c7dacaef
|
||||
|
||||
PODFILE CHECKSUM: d53724fe402c2547f1dd1cc571bbe77d9820e636
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"typescript": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native-community/blur": "^4.3.0",
|
||||
"@react-native-camera-roll/camera-roll": "^5.2.3",
|
||||
"@react-native-community/blur": "^4.3.0",
|
||||
"@react-native-community/slider": "^4.4.2",
|
||||
"@react-navigation/native": "^6.1.3",
|
||||
"@react-navigation/native-stack": "^6.9.9",
|
||||
@@ -23,12 +23,13 @@
|
||||
"react-native": "^0.71.2",
|
||||
"react-native-gesture-handler": "^2.9.0",
|
||||
"react-native-pressable-opacity": "^1.0.10",
|
||||
"react-native-reanimated": "^2.14.4",
|
||||
"react-native-reanimated": "^3.0.0-rc.10",
|
||||
"react-native-safe-area-context": "^4.5.0",
|
||||
"react-native-screens": "^3.19.0",
|
||||
"react-native-static-safe-area-insets": "^2.2.0",
|
||||
"react-native-vector-icons": "^9.2.0",
|
||||
"react-native-video": "^5.2.1"
|
||||
"react-native-video": "^5.2.1",
|
||||
"react-native-worklets": "https://github.com/chrfalch/react-native-worklets#50950aa"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { MediaPage } from './MediaPage';
|
||||
import { CameraPage } from './CameraPage';
|
||||
import type { Routes } from './Routes';
|
||||
import { Camera, CameraPermissionStatus } from 'react-native-vision-camera';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
|
||||
const Stack = createNativeStackNavigator<Routes>();
|
||||
|
||||
@@ -28,24 +29,26 @@ export function App(): React.ReactElement | null {
|
||||
const showPermissionsPage = cameraPermission !== 'authorized' || microphonePermission === 'not-determined';
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
statusBarStyle: 'dark',
|
||||
animationTypeForReplace: 'push',
|
||||
}}
|
||||
initialRouteName={showPermissionsPage ? 'PermissionsPage' : 'CameraPage'}>
|
||||
<Stack.Screen name="PermissionsPage" component={PermissionsPage} />
|
||||
<Stack.Screen name="CameraPage" component={CameraPage} />
|
||||
<Stack.Screen
|
||||
name="MediaPage"
|
||||
component={MediaPage}
|
||||
options={{
|
||||
animation: 'none',
|
||||
presentation: 'transparentModal',
|
||||
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
statusBarStyle: 'dark',
|
||||
animationTypeForReplace: 'push',
|
||||
}}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
initialRouteName={showPermissionsPage ? 'PermissionsPage' : 'CameraPage'}>
|
||||
<Stack.Screen name="PermissionsPage" component={PermissionsPage} />
|
||||
<Stack.Screen name="CameraPage" component={CameraPage} />
|
||||
<Stack.Screen
|
||||
name="MediaPage"
|
||||
component={MediaPage}
|
||||
options={{
|
||||
animation: 'none',
|
||||
presentation: 'transparentModal',
|
||||
}}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
</GestureHandlerRootView>
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
/* global __example_plugin __example_plugin_swift */
|
||||
import type { Frame } from 'react-native-vision-camera';
|
||||
|
||||
declare let _WORKLET: true | undefined;
|
||||
import { FrameProcessorPlugins, Frame } from 'react-native-vision-camera';
|
||||
|
||||
export function examplePluginSwift(frame: Frame): string[] {
|
||||
'worklet';
|
||||
if (!_WORKLET) throw new Error('examplePluginSwift must be called from a frame processor!');
|
||||
|
||||
// @ts-expect-error because this function is dynamically injected by VisionCamera
|
||||
return __example_plugin_swift(frame, 'hello!', 'parameter2', true, 42, { test: 0, second: 'test' }, ['another test', 5]);
|
||||
return FrameProcessorPlugins.example_plugin_swift(frame, 'hello!', 'parameter2', true, 42, { test: 0, second: 'test' }, [
|
||||
'another test',
|
||||
5,
|
||||
]);
|
||||
}
|
||||
|
||||
export function examplePlugin(frame: Frame): string[] {
|
||||
'worklet';
|
||||
if (!_WORKLET) throw new Error('examplePlugin must be called from a frame processor!');
|
||||
|
||||
// @ts-expect-error because this function is dynamically injected by VisionCamera
|
||||
return __example_plugin(frame, 'hello!', 'parameter2', true, 42, { test: 0, second: 'test' }, ['another test', 5]);
|
||||
return FrameProcessorPlugins.example_plugin(frame, 'hello!', 'parameter2', true, 42, { test: 0, second: 'test' }, ['another test', 5]);
|
||||
}
|
||||
|
||||
@@ -1190,7 +1190,7 @@
|
||||
dependencies:
|
||||
"@hapi/hoek" "^9.0.0"
|
||||
|
||||
"@sideway/formula@^3.0.0":
|
||||
"@sideway/formula@^3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f"
|
||||
integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==
|
||||
@@ -2259,9 +2259,9 @@ ee-first@1.1.1:
|
||||
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
|
||||
|
||||
electron-to-chromium@^1.4.284:
|
||||
version "1.4.292"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.292.tgz#e3a3dca3780c8ce01e2c1866b5ec2fbe31c423e3"
|
||||
integrity sha512-ESWOSyJy5odDlE8wvh5NNAMORv4r6assPwIPGHEMWrWD0SONXcG/xT+9aD9CQyeRwyYDPo6dJT4Bbeg5uevVQQ==
|
||||
version "1.4.294"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.294.tgz#ad80317b85f0859a9454680fbc1c726fefa7e6fd"
|
||||
integrity sha512-PuHZB3jEN7D8WPPjLmBQAsqQz8tWHlkkB4n0E2OYw8RwVdmBYV0Wn+rUFH8JqYyIRb4HQhhedgxlZL163wqLrQ==
|
||||
|
||||
eme-encryption-scheme-polyfill@^2.0.1:
|
||||
version "2.1.1"
|
||||
@@ -2884,7 +2884,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5:
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
|
||||
integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==
|
||||
@@ -3162,11 +3162,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
internal-slot@^1.0.3, internal-slot@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3"
|
||||
integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986"
|
||||
integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==
|
||||
dependencies:
|
||||
get-intrinsic "^1.1.3"
|
||||
get-intrinsic "^1.2.0"
|
||||
has "^1.0.3"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
@@ -3550,14 +3550,14 @@ jest-worker@^27.2.0:
|
||||
supports-color "^8.0.0"
|
||||
|
||||
joi@^17.2.1:
|
||||
version "17.7.0"
|
||||
resolved "https://registry.yarnpkg.com/joi/-/joi-17.7.0.tgz#591a33b1fe1aca2bc27f290bcad9b9c1c570a6b3"
|
||||
integrity sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==
|
||||
version "17.7.1"
|
||||
resolved "https://registry.yarnpkg.com/joi/-/joi-17.7.1.tgz#854fc85c7fa3cfc47c91124d30bffdbb58e06cec"
|
||||
integrity sha512-teoLhIvWE298R6AeJywcjR4sX2hHjB3/xJX4qPjg+gTg+c0mzUDsziYlqPmLomq9gVsfaMcgPaGc7VxtD/9StA==
|
||||
dependencies:
|
||||
"@hapi/hoek" "^9.0.0"
|
||||
"@hapi/topo" "^5.0.0"
|
||||
"@sideway/address" "^4.1.3"
|
||||
"@sideway/formula" "^3.0.0"
|
||||
"@sideway/formula" "^3.0.1"
|
||||
"@sideway/pinpoint" "^2.0.0"
|
||||
|
||||
js-sdsl@^4.1.4:
|
||||
@@ -4444,9 +4444,9 @@ minimatch@^5.0.1:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.6:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
|
||||
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
|
||||
mixin-deep@^1.2.0:
|
||||
version "1.3.2"
|
||||
@@ -4984,9 +4984,9 @@ range-parser@~1.2.1:
|
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
|
||||
|
||||
react-devtools-core@^4.26.1:
|
||||
version "4.27.1"
|
||||
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.27.1.tgz#167aa174383c65786cbb7e965a5b39c702f0a2d3"
|
||||
integrity sha512-qXhcxxDWiFmFAOq48jts9YQYe1+wVoUXzJTlY4jbaATzyio6dd6CUGu3dXBhREeVgpZ+y4kg6vFJzIOZh6vY2w==
|
||||
version "4.27.2"
|
||||
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.27.2.tgz#d20fc57e258c656eedabafc2c851d38b33583148"
|
||||
integrity sha512-8SzmIkpO87alD7Xr6gWIEa1jHkMjawOZ+6egjazlnjB4UUcbnzGDf/vBJ4BzGuWWEM+pzrxuzsPpcMqlQkYK2g==
|
||||
dependencies:
|
||||
shell-quote "^1.6.1"
|
||||
ws "^7"
|
||||
@@ -5042,10 +5042,10 @@ react-native-pressable-opacity@^1.0.10:
|
||||
resolved "https://registry.yarnpkg.com/react-native-pressable-opacity/-/react-native-pressable-opacity-1.0.10.tgz#799df1a913d3b28f42ada765465fe7723eb7166d"
|
||||
integrity sha512-Py9YH9TlS3Lv1so5JCj6bgiqkeYYGupF4ZImlpoyhhId/t/RiSqR68LlASOHgdctqQuqVJObQiFfzX8oZI9+6w==
|
||||
|
||||
react-native-reanimated@^2.14.4:
|
||||
version "2.14.4"
|
||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.14.4.tgz#3fa3da4e7b99f5dfb28f86bcf24d9d1024d38836"
|
||||
integrity sha512-DquSbl7P8j4SAmc+kRdd75Ianm8G+IYQ9T4AQ6lrpLVeDkhZmjWI0wkutKWnp6L7c5XNVUrFDUf69dwETLCItQ==
|
||||
react-native-reanimated@^3.0.0-rc.10:
|
||||
version "3.0.0-rc.10"
|
||||
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.0.0-rc.10.tgz#40e5b628759aa81f94317fd0301231292b4eacf5"
|
||||
integrity sha512-0P2jSO+dXHRxSzqSxNp08VaUy89nqeUIvqBS0wlI8lsli8CJcqulL3pjNqTGzBkxXjt13mGdIzJv4u9lSjHPzg==
|
||||
dependencies:
|
||||
"@babel/plugin-transform-object-assign" "^7.16.7"
|
||||
"@babel/preset-typescript" "^7.16.7"
|
||||
@@ -5091,6 +5091,10 @@ react-native-video@^5.2.1:
|
||||
prop-types "^15.7.2"
|
||||
shaka-player "^2.5.9"
|
||||
|
||||
"react-native-worklets@https://github.com/chrfalch/react-native-worklets#50950aa":
|
||||
version "0.1.0"
|
||||
resolved "https://github.com/chrfalch/react-native-worklets#50950aa1b671a0d8a9e79878e63a3445991e7192"
|
||||
|
||||
react-native@^0.71.2:
|
||||
version "0.71.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.2.tgz#b6977eda2a6dc10baa006bf4ab1ee08318607ce9"
|
||||
|
||||
Reference in New Issue
Block a user