From 8f31930b4f5c1d7782231c3706dfd79e30b08248 Mon Sep 17 00:00:00 2001 From: Milosz Filimowski Date: Thu, 10 Sep 2026 15:22:38 +0200 Subject: [PATCH 1/3] feat(react-native): createCameraEffectMiddleware A camera-track middleware for useCamera().setCameraTrackMiddleware. It acquires the GPU device, builds the effect session and the frame kernel, and disposes them when cleared, so an app can switch an effect on from any screen with no provider and no hook. --- CHANGELOG.md | 4 + README.md | 27 ++-- src/fishjam-react-native.ts | 5 + .../createCameraEffectMiddleware.ts | 116 ++++++++++++++++++ .../webgpu/useCameraWebGpuDevice.ts | 5 +- 5 files changed, 144 insertions(+), 13 deletions(-) create mode 100644 src/react-native/createCameraEffectMiddleware.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 50bb809..2a2c630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- `createCameraEffectMiddleware(effect)` for React Native: a camera-track middleware for `useCamera().setCameraTrackMiddleware`, so an effect can be switched on from any screen without a provider or a hook. + ## 0.1.2 - Background blur: the person no longer bleeds into the blurred background (no halo), the outline is a smooth ramp that hugs the body, and similar-coloured background next to the person is no longer left sharp. diff --git a/README.md b/README.md index 8420830..77cb1c4 100644 --- a/README.md +++ b/README.md @@ -38,28 +38,33 @@ const effect = useBackgroundImage({ `@fishjam-cloud/video-effects/fishjam-react-native` runs an effect on the camera track Fishjam already publishes, through `useCamera`'s camera-track middleware. No separate camera and no custom track: the app keeps using `useCamera`, and remote peers keep seeing `peer.cameraTrack`. -```tsx -import { useBackgroundBlur } from "@fishjam-cloud/video-effects/background-blur"; -import { useFishjamCameraEffect } from "@fishjam-cloud/video-effects/fishjam-react-native"; +```ts +import { createBackgroundBlurEffect } from "@fishjam-cloud/video-effects/background-blur"; +import { createCameraEffectMiddleware } from "@fishjam-cloud/video-effects/fishjam-react-native"; import { typeGpuPersonSegmentation } from "@fishjam-cloud/video-effects/segmentation/typegpu"; const segmentation = typeGpuPersonSegmentation({ modelUrl }); +export const backgroundBlur = createCameraEffectMiddleware( + createBackgroundBlurEffect(() => ({ segmentation, radius: 24 })), +); +``` -function BackgroundBlur({ enabled }: { enabled: boolean }) { - const blur = useBackgroundBlur({ segmentation, radius: 24 }); - const { status, error } = useFishjamCameraEffect(enabled ? blur : null); - return null; -} +```tsx +const { currentCameraMiddleware, setCameraTrackMiddleware } = useCamera(); +const isBlurOn = currentCameraMiddleware === backgroundBlur; +