react-native-webrtc-kaleidoscope 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/NOTICE.md +35 -0
  2. package/README.md +140 -3
  3. package/android/build.gradle +65 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/assets/backgrounds/office-1.png +0 -0
  6. package/android/src/main/assets/backgrounds/office-2.png +0 -0
  7. package/android/src/main/java/com/simiancraft/kaleidoscope/EffectTuning.kt +57 -0
  8. package/android/src/main/java/com/simiancraft/kaleidoscope/KaleidoscopeModule.kt +43 -0
  9. package/android/src/main/java/com/simiancraft/kaleidoscope/Registration.kt +39 -0
  10. package/android/src/main/java/com/simiancraft/kaleidoscope/effects/BackgroundImageFactory.kt +335 -0
  11. package/android/src/main/java/com/simiancraft/kaleidoscope/effects/BlurFactory.kt +336 -0
  12. package/android/src/main/java/com/simiancraft/kaleidoscope/effects/MirrorFactory.kt +57 -0
  13. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Egl.kt +88 -0
  14. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Fbo.kt +61 -0
  15. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/GlDebug.kt +41 -0
  16. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/GlProgram.kt +74 -0
  17. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/GpuEffectFactory.kt +14 -0
  18. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/GpuEffectProcessor.kt +198 -0
  19. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/Shaders.kt +129 -0
  20. package/android/src/main/java/com/simiancraft/kaleidoscope/segmentation/Mask.kt +298 -0
  21. package/android/src/main/java/com/simiancraft/kaleidoscope/segmentation/MaskTuning.kt +34 -0
  22. package/app.plugin.d.ts +4 -0
  23. package/app.plugin.js +5 -0
  24. package/dist/backgrounds.d.ts +3 -0
  25. package/dist/backgrounds.d.ts.map +1 -0
  26. package/dist/backgrounds.js +21 -0
  27. package/dist/backgrounds.js.map +1 -0
  28. package/dist/index.d.ts +28 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +106 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/index.web.d.ts +27 -0
  33. package/dist/index.web.d.ts.map +1 -0
  34. package/dist/index.web.js +74 -0
  35. package/dist/index.web.js.map +1 -0
  36. package/dist/types.d.ts +67 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +13 -0
  39. package/dist/types.js.map +1 -0
  40. package/dist/web/effects/background-image.d.ts +3 -0
  41. package/dist/web/effects/background-image.d.ts.map +1 -0
  42. package/dist/web/effects/background-image.js +217 -0
  43. package/dist/web/effects/background-image.js.map +1 -0
  44. package/dist/web/effects/blur.d.ts +3 -0
  45. package/dist/web/effects/blur.d.ts.map +1 -0
  46. package/dist/web/effects/blur.js +208 -0
  47. package/dist/web/effects/blur.js.map +1 -0
  48. package/dist/web/effects/mirror.d.ts +3 -0
  49. package/dist/web/effects/mirror.d.ts.map +1 -0
  50. package/dist/web/effects/mirror.js +31 -0
  51. package/dist/web/effects/mirror.js.map +1 -0
  52. package/dist/web/effects/passthrough.d.ts +3 -0
  53. package/dist/web/effects/passthrough.d.ts.map +1 -0
  54. package/dist/web/effects/passthrough.js +15 -0
  55. package/dist/web/effects/passthrough.js.map +1 -0
  56. package/dist/web/insertable-streams.d.ts +26 -0
  57. package/dist/web/insertable-streams.d.ts.map +1 -0
  58. package/dist/web/insertable-streams.js +46 -0
  59. package/dist/web/insertable-streams.js.map +1 -0
  60. package/dist/web/segmenter.d.ts +20 -0
  61. package/dist/web/segmenter.d.ts.map +1 -0
  62. package/dist/web/segmenter.js +51 -0
  63. package/dist/web/segmenter.js.map +1 -0
  64. package/dist/web/shaders.d.ts +4 -0
  65. package/dist/web/shaders.d.ts.map +1 -0
  66. package/dist/web/shaders.js +106 -0
  67. package/dist/web/shaders.js.map +1 -0
  68. package/dist/web/tuning.d.ts +22 -0
  69. package/dist/web/tuning.d.ts.map +1 -0
  70. package/dist/web/tuning.js +43 -0
  71. package/dist/web/tuning.js.map +1 -0
  72. package/expo-module.config.json +9 -0
  73. package/ios/Kaleidoscope.podspec +37 -0
  74. package/ios/KaleidoscopeModule/EffectTuning.swift +73 -0
  75. package/ios/KaleidoscopeModule/KaleidoscopeModule.swift +32 -0
  76. package/ios/KaleidoscopeModule/Registration.swift +21 -0
  77. package/ios/KaleidoscopeModule/effects/BlurProcessor.swift +24 -0
  78. package/ios/KaleidoscopeModule/effects/MirrorProcessor.swift +17 -0
  79. package/ios/KaleidoscopeModule/segmentation/Segmenter.swift +30 -0
  80. package/package.json +99 -3
  81. package/plugin/build/withKaleidoscope.d.ts +3 -0
  82. package/plugin/build/withKaleidoscope.js +14 -0
  83. package/plugin/build/withKaleidoscope.js.map +1 -0
  84. package/src/backgrounds.ts +23 -0
  85. package/src/index.ts +149 -0
  86. package/src/index.web.ts +93 -0
  87. package/src/types.ts +80 -0
  88. package/src/web/effects/background-image.ts +277 -0
  89. package/src/web/effects/blur.ts +256 -0
  90. package/src/web/effects/mirror.ts +37 -0
  91. package/src/web/effects/passthrough.ts +17 -0
  92. package/src/web/insertable-streams.ts +84 -0
  93. package/src/web/segmenter.ts +73 -0
  94. package/src/web/shaders.ts +108 -0
  95. package/src/web/tuning.ts +53 -0
package/NOTICE.md ADDED
@@ -0,0 +1,35 @@
1
+ # Notices and Attributions
2
+
3
+ react-native-webrtc-kaleidoscope ships under the MIT license (see [LICENSE](./LICENSE)). This document tracks third-party sources, standards, and trademarks referenced by the library and the effects it ships.
4
+
5
+ ## Runtime peer dependency
6
+
7
+ - **react-native-webrtc** — MIT license. <https://github.com/react-native-webrtc/react-native-webrtc>. The `track._setVideoEffects(...)` JS surface, the Android `ProcessorProvider` registry, and the iOS `RTCVideoFrameProcessor` protocol all originate upstream. This package is a consumer of, not a fork of, that codebase.
8
+
9
+ ## Native segmentation backends (used by the `blur` effect)
10
+
11
+ - **Apple Vision** (iOS) — system framework. `VNGeneratePersonSegmentationRequest`. Subject to the Apple SDK License Agreement.
12
+ - **MLKit Selfie Segmentation** (Android) — Apache License 2.0. Distributed by Google as a managed AAR. <https://developers.google.com/ml-kit/vision/selfie-segmentation>.
13
+ - **MediaPipe Selfie Segmentation** (web) — Apache License 2.0. Loaded as an `optionalDependency` so native consumers do not bundle the WASM payload. <https://github.com/google-ai-edge/mediapipe>.
14
+
15
+ ## Algorithmic and architectural references
16
+
17
+ - **mrousavy/FaceBlurApp** — segmentation + GPU composite at 60–120 FPS. Different plumbing (camera-preview pipeline, not a WebRTC track), but the algorithmic shape of "mask + blurred copy + composite" is the same.
18
+ - **Volcomix/virtual-background** — TFLite WASM reference for the web blur composite.
19
+
20
+ ## Trademarks
21
+
22
+ - "Apple", "Vision", "Core Image", and related Apple marks are trademarks of Apple Inc. Used here as nominative references only.
23
+ - "Google", "MLKit", and "MediaPipe" are trademarks of Google LLC. Used here as nominative references only.
24
+ - "WebRTC" is a project of the W3C and IETF.
25
+
26
+ This package is not affiliated with, endorsed by, or certified by Apple, Google, the W3C, or the `react-native-webrtc` project.
27
+
28
+ ## Forward-looking discipline
29
+
30
+ Effects added after v0.1 that depend on new third-party code or registered marks must:
31
+
32
+ 1. Cite the source (with a stable URL and version) in the effect's source code.
33
+ 2. Add an attribution section to this document.
34
+ 3. Disclaim affiliation, endorsement, or certification where appropriate.
35
+ 4. Treat trademarked names as **nominative references** only.
package/README.md CHANGED
@@ -1,7 +1,144 @@
1
+ <p align="center">
2
+ <img src="./docs/kaleidoscope-logo.png" alt="react-native-webrtc-kaleidoscope logo" width="180" />
3
+ </p>
4
+
1
5
  # react-native-webrtc-kaleidoscope
2
6
 
3
- Live video effects (mirror, blur, more) for `react-native-webrtc`, packaged as a managed-Expo-friendly Expo Module.
7
+ [![status: alpha](https://img.shields.io/badge/status-alpha-orange)](#status)
8
+ [![npm version](https://img.shields.io/npm/v/react-native-webrtc-kaleidoscope?color=cb3837&logo=npm)](https://www.npmjs.com/package/react-native-webrtc-kaleidoscope)
9
+ [![Types: included](https://img.shields.io/npm/types/react-native-webrtc-kaleidoscope?color=3178c6&logo=typescript)](https://www.npmjs.com/package/react-native-webrtc-kaleidoscope)
10
+ [![CI](https://github.com/simiancraft/react-native-webrtc-kaleidoscope/actions/workflows/ci.yml/badge.svg)](https://github.com/simiancraft/react-native-webrtc-kaleidoscope/actions/workflows/ci.yml)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
12
+
13
+ > Live video effects for `react-native-webrtc`, packaged as a managed-Expo-friendly Expo Module.
14
+
15
+ ## Status
16
+
17
+ **Active development; not yet production-ready.** Published to npm as `0.1.0-alpha.x` for name reservation and integration testing. The npm presentation, marketing, and release-quality polish will come in a later pass; right now the README's job is to tell the truth about what works.
18
+
19
+ ### What works today
20
+
21
+ - **Mirror** (horizontal flip).
22
+ - **Blur** (background blur, person stays sharp).
23
+ - **Background replacement** (composite a still PNG behind the segmented person; two bundled office presets, library-side asset pipeline).
24
+ - **Runtime tuning** of the GLSL effects; see the [Use](#use) section.
25
+
26
+ | Platform | Mirror | Blur | Background replacement | Notes |
27
+ |---|---|---|---|---|
28
+ | Web (Chrome / Edge) | ✓ | ✓ | ✓ | MediaStreamTrackProcessor + MediaPipe Selfie Segmentation (WASM, CDN) |
29
+ | Android (API 24+) | ✓ | ✓ | ✓ | OpenGL ES 3.0 + MLKit Selfie Segmentation |
30
+ | iOS (≥ 15) | — | — | — | Coming soon; transpilation pipeline in place, host implementation pending |
31
+ | Safari / Firefox | — | — | — | No Insertable Streams; `applyVideoEffects` throws a typed error |
32
+
33
+ ### Coming soon
34
+
35
+ - **iOS support**, via the canonical GLSL transpiled to Metal Shading Language (`glslangValidator` → `spirv-cross --msl`). The pipeline is in the repo at `scripts/transpile-shaders.ts` and the GLSL canonical source lives in `shaders/`. The Swift host code that loads the metallib and runs the Metal pipeline is the next chunk of work.
36
+ - **Procedural backgrounds** (animated shaders behind the person, not just still images). Same composite path; the only new piece is each effect's background producer.
37
+ - A careful pass over the npm presentation, install docs, and demo polish before any "we recommend you use this" framing.
38
+
39
+ ## Install
40
+
41
+ ```sh
42
+ bun add react-native-webrtc react-native-webrtc-kaleidoscope
43
+ ```
44
+
45
+ `react-native-webrtc` is a peer dependency. Install it explicitly.
46
+
47
+ ### Using LiveKit?
48
+
49
+ If your project uses `@livekit/react-native` it pulls in `@livekit/react-native-webrtc`, a fork of upstream `react-native-webrtc` that preserves the same `videoEffects` native classes and the `_setVideoEffects` JS API. Kaleidoscope works against either fork; the Android Gradle script picks whichever one your autolinking surfaced.
50
+
51
+ ```sh
52
+ bun add @livekit/react-native @livekit/react-native-webrtc react-native-webrtc-kaleidoscope
53
+ ```
54
+
55
+ Pick one fork. Installing both upstream `react-native-webrtc` and `@livekit/react-native-webrtc` in the same app will cause native class collisions; that's the consumer's problem to resolve.
56
+
57
+ ## Configure
58
+
59
+ Add the config plugin to `app.config.ts`:
60
+
61
+ ```ts
62
+ export default {
63
+ expo: {
64
+ plugins: ['react-native-webrtc-kaleidoscope'],
65
+ },
66
+ };
67
+ ```
68
+
69
+ (`react-native-webrtc` 124.x does not ship a config plugin upstream; do not list it in `plugins`. If you are on a fork that adds one, add it explicitly.)
70
+
71
+ Then rebuild native code:
72
+
73
+ ```sh
74
+ bunx expo prebuild
75
+ ```
76
+
77
+ ## Use
78
+
79
+ ```ts
80
+ import { mediaDevices } from 'react-native-webrtc';
81
+ import {
82
+ applyVideoEffects,
83
+ setBlurSigma,
84
+ setMaskHardness,
85
+ setMaskThreshold,
86
+ } from 'react-native-webrtc-kaleidoscope';
87
+
88
+ const stream = await mediaDevices.getUserMedia({ video: true });
89
+ const [track] = stream.getVideoTracks();
90
+
91
+ applyVideoEffects(track, ['mirror']);
92
+ applyVideoEffects(track, ['blur']);
93
+ applyVideoEffects(track, [{ name: 'background-image', source: 'office-1' }]);
94
+ applyVideoEffects(track, []); // clear all effects
95
+
96
+ // Runtime tuning (effects pick up the new values on the next frame):
97
+ setBlurSigma(25); // Gaussian σ; clamped to [0.5, 64], default 8.
98
+ setMaskHardness(0.2); // smoothstep transition width; clamped to [0, 1]. 0 = soft halo, 1 = near-step. Default 0.5.
99
+ setMaskThreshold(0.7); // smoothstep center; clamped to [0.05, 0.95]. Higher rejects low-confidence pixels. Default 0.5.
100
+ ```
101
+
102
+ Effects chain in array order.
103
+
104
+ **Tuning note:** optimal values are platform-specific because each segmentation model (MediaPipe on web, MLKit on Android, Vision when iOS lands) produces a different confidence distribution. Working defaults on a typical well-lit scene:
105
+
106
+ | Platform | Blur sigma | Mask hardness | Mask threshold |
107
+ |---|---|---|---|
108
+ | Web (MediaPipe) | 25 | 0.2 | 0.85 |
109
+ | Android (MLKit) | 30 | 0.2 | 0.6 |
110
+
111
+ The library ships neutral defaults (8, 0.5, 0.5) and consumers tune at runtime via the API above; whether to ship the dialed-in values as platform-specific defaults is an open question waiting on iOS data.
112
+
113
+ ## What this isn't
114
+
115
+ - **Not a fork of `react-native-webrtc`.** A thin layer over its undocumented `_setVideoEffects` registry on native, and `MediaStreamTrackProcessor` on web. Install alongside `react-native-webrtc`.
116
+ - **Not a managed cloud SaaS.** Effects run locally on the device; the track stays peer-to-peer. No service, no API key, no per-minute billing.
117
+ - **Not a face-filter SDK.** Effects are background segmentation and frame transforms, not facial AR.
118
+ - **Not a streaming protocol replacement.** The transformed track plugs into the consumer's existing `RTCPeerConnection` pipeline.
119
+
120
+ ## Architecture
121
+
122
+ The codebase lives across four surfaces:
123
+
124
+ - `src/` — JS facade and shared types. `applyVideoEffects(track, effects)` plus runtime tuning setters.
125
+ - `src/web/` — WebGL2 pipeline. MediaPipe segmentation + GLSL composite. One shader file per stage in `src/web/shaders.ts`.
126
+ - `android/` — OpenGL ES 3.0 pipeline. MLKit segmentation (async, worker-thread, last-known-mask cache) + GLSL composite. Shaders inline in `gpu/Shaders.kt` as `const val` strings.
127
+ - `ios/` — Scaffold only; the canonical GLSL in `shaders/` will transpile to Metal Shading Language for the iOS path.
128
+
129
+ The composite shader (`shaders/composite.frag`) is the same GLSL source for every effect category (blur, background-image, future procedural backgrounds). Per-effect difference is upstream of the composite: how the `uBackground` texture gets produced.
130
+
131
+ See [`PATTERNS.md`](./PATTERNS.md) for the file-layout conventions, texture-orientation contract, and recipe for adding new effects, shaders, presets, or tunable parameters.
132
+
133
+ ## Reference
134
+
135
+ - [CONTRIBUTING.md](./CONTRIBUTING.md): setup, scripts, commit conventions.
136
+ - [AGENTS.md](./AGENTS.md): agent and contributor orientation.
137
+ - [PATTERNS.md](./PATTERNS.md): codebase conventions and how-to-extend.
138
+ - [SECURITY.md](./SECURITY.md): security policy and reporting.
139
+ - [NOTICE.md](./NOTICE.md): third-party attributions.
140
+ - Sibling projects: [chromonym](https://github.com/simiancraft/chromonym) and [unitforge](https://github.com/simiancraft/unitforge); same OSS-hygiene template.
4
141
 
5
- **This is a placeholder.** The package name is reserved while active development is in progress. The first usable release will be `v0.1` shipping the `mirror` and `blur` effects on iOS, Android, and web.
142
+ ---
6
143
 
7
- Source: <https://github.com/simiancraft/react-native-webrtc-kaleidoscope>
144
+ MIT licensed. © 2026 Jesse Harlin / [Simiancraft](https://github.com/simiancraft).
@@ -0,0 +1,65 @@
1
+ // Android build script for react-native-webrtc-kaleidoscope.
2
+
3
+ apply plugin: 'com.android.library'
4
+ apply plugin: 'kotlin-android'
5
+
6
+ group = 'com.simiancraft.kaleidoscope'
7
+ version = '0.1.0-alpha.1'
8
+
9
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
10
+ if (expoModulesCorePlugin.exists()) {
11
+ apply from: expoModulesCorePlugin
12
+ applyKotlinExpoModulesCorePlugin()
13
+ }
14
+
15
+ android {
16
+ namespace 'com.simiancraft.kaleidoscope'
17
+ compileSdkVersion safeExtGet('compileSdkVersion', 34)
18
+
19
+ defaultConfig {
20
+ minSdkVersion safeExtGet('minSdkVersion', 24)
21
+ targetSdkVersion safeExtGet('targetSdkVersion', 34)
22
+ }
23
+
24
+ compileOptions {
25
+ sourceCompatibility JavaVersion.VERSION_17
26
+ targetCompatibility JavaVersion.VERSION_17
27
+ }
28
+
29
+ kotlinOptions {
30
+ jvmTarget = '17'
31
+ }
32
+ }
33
+
34
+ dependencies {
35
+ implementation project(':expo-modules-core')
36
+
37
+ // react-native-webrtc is a peer dependency: link against its types
38
+ // (ProcessorProvider, VideoFrameProcessor, VideoFrameProcessorFactoryInterface,
39
+ // and the org.webrtc.* surface it bundles) at compile time only; the consumer
40
+ // app provides the runtime via autolinking.
41
+ //
42
+ // Two forks ship the same classes under `com.oney.WebRTCModule.videoEffects.*`:
43
+ // - react-native-webrtc/react-native-webrtc (upstream)
44
+ // - livekit/react-native-webrtc (LiveKit fork, required by @livekit/react-native)
45
+ // Pick whichever the consumer's autolinking surfaced; throw if neither is present.
46
+ def rnWebrtcCandidates = [':react-native-webrtc', ':livekit_react-native-webrtc']
47
+ def rnWebrtcProject = rnWebrtcCandidates.find { rootProject.findProject(it) != null }
48
+ if (rnWebrtcProject == null) {
49
+ throw new GradleException(
50
+ 'react-native-webrtc-kaleidoscope: install either react-native-webrtc ' +
51
+ 'or @livekit/react-native-webrtc as a peer dependency.'
52
+ )
53
+ }
54
+ compileOnly project(rnWebrtcProject)
55
+
56
+ // Person/background mask for the blur effect. The Google artifact ID is
57
+ // `segmentation-selfie`, not `selfie-segmentation` (the plan and earlier
58
+ // notes had it inverted; that is why the pin would not resolve).
59
+ implementation 'com.google.mlkit:segmentation-selfie:16.0.0-beta6'
60
+ }
61
+
62
+ // Helper: gracefully read root project ext properties with a default.
63
+ def safeExtGet(prop, fallback) {
64
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
65
+ }
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" />
@@ -0,0 +1,57 @@
1
+ // Mutable runtime parameters for the GLSL effects on Android. The Expo
2
+ // Module's setBlurSigma / setMaskHardness JS functions update these values;
3
+ // per-frame processors read them on every frame so changes take effect
4
+ // without re-registering processors.
5
+ //
6
+ // This is the parameter-passing side-channel that lets us tune effect
7
+ // uniforms without touching the upstream react-native-webrtc registry,
8
+ // which only accepts flat-string effect names. The web side mirrors this
9
+ // shape in src/web/tuning.ts; iOS mirrors it in
10
+ // ios/KaleidoscopeModule/EffectTuning.swift.
11
+
12
+ package com.simiancraft.kaleidoscope
13
+
14
+ internal object EffectTuning {
15
+ /**
16
+ * Gaussian sigma for the blur effect; higher = softer blur. Default
17
+ * matches the v0.1 hardcoded value. Custom setter clamps to a sane
18
+ * range; setting the property is the public mutation API.
19
+ */
20
+ @Volatile
21
+ var blurSigma: Float = 8f
22
+ set(value) {
23
+ field = value.coerceIn(0.5f, 64f)
24
+ }
25
+
26
+ /**
27
+ * Mask smoothstep hardness for blur and background-image composites,
28
+ * in [0, 1]; 0 = soft halo, 1 = near-step. Default reproduces the
29
+ * historical smoothstep(0.34, 0.66) edge.
30
+ */
31
+ @Volatile
32
+ var maskHardness: Float = 0.5f
33
+ set(value) {
34
+ field = value.coerceIn(0f, 1f)
35
+ }
36
+
37
+ /**
38
+ * Mask smoothstep center for blur and background-image composites,
39
+ * in [0, 1]; the threshold at which a pixel's raw confidence flips from
40
+ * "background" to "person". Default 0.5 reproduces the historical
41
+ * smoothstep centered on the confidence midpoint. Higher values reject
42
+ * low-confidence edges (chair backs, hair flyaway); lower values are
43
+ * more inclusive. Clamped to a workable range below to keep the
44
+ * smoothstep transition non-degenerate.
45
+ */
46
+ @Volatile
47
+ var maskThreshold: Float = 0.5f
48
+ set(value) {
49
+ field = value.coerceIn(0.05f, 0.95f)
50
+ }
51
+
52
+ fun reset() {
53
+ blurSigma = 8f
54
+ maskHardness = 0.5f
55
+ maskThreshold = 0.5f
56
+ }
57
+ }
@@ -0,0 +1,43 @@
1
+ // Expo Module entry point for react-native-webrtc-kaleidoscope on Android.
2
+ // Calls Registration.registerAll(context) at module init so frame-processor
3
+ // factories land in ProcessorProvider before any track requests them.
4
+ //
5
+ // Also exposes setBlurSigma / setMaskHardness / resetEffectTuning JS
6
+ // functions that mutate com.simiancraft.kaleidoscope.EffectTuning at
7
+ // runtime; the per-frame processors read those values each frame, so
8
+ // changes take effect without re-registering or rebuilding processors.
9
+ // This side-channels the upstream react-native-webrtc registry, which only
10
+ // accepts flat-string effect names; spec parameters flow through here.
11
+
12
+ package com.simiancraft.kaleidoscope
13
+
14
+ import expo.modules.kotlin.modules.Module
15
+ import expo.modules.kotlin.modules.ModuleDefinition
16
+
17
+ class KaleidoscopeModule : Module() {
18
+ override fun definition() = ModuleDefinition {
19
+ Name("RnWebrtcKaleidoscope")
20
+
21
+ OnCreate {
22
+ val ctx = appContext.reactContext
23
+ ?: error("Kaleidoscope: no react context at OnCreate; cannot register Android effects")
24
+ Registration.registerAll(ctx)
25
+ }
26
+
27
+ Function("setBlurSigma") { value: Float ->
28
+ EffectTuning.blurSigma = value
29
+ }
30
+
31
+ Function("setMaskHardness") { value: Float ->
32
+ EffectTuning.maskHardness = value
33
+ }
34
+
35
+ Function("setMaskThreshold") { value: Float ->
36
+ EffectTuning.maskThreshold = value
37
+ }
38
+
39
+ Function("resetEffectTuning") {
40
+ EffectTuning.reset()
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,39 @@
1
+ // Frame-processor registration for Android. Called from
2
+ // KaleidoscopeModule.OnCreate at Expo Module init time, before any track
3
+ // requests an effect by name. The Context is needed by GPU effects so they
4
+ // can read PNG assets for background-image and create RenderScript-style
5
+ // resources where applicable.
6
+
7
+ package com.simiancraft.kaleidoscope
8
+
9
+ import android.content.Context
10
+ import com.oney.WebRTCModule.videoEffects.ProcessorProvider
11
+ import com.simiancraft.kaleidoscope.effects.BackgroundImageFactory
12
+ import com.simiancraft.kaleidoscope.effects.BlurFactory
13
+ import com.simiancraft.kaleidoscope.effects.MirrorFactory
14
+ import com.simiancraft.kaleidoscope.gpu.GpuEffectFactory
15
+
16
+ object Registration {
17
+ @JvmStatic
18
+ fun registerAll(context: Context) {
19
+ ProcessorProvider.addProcessor("mirror", MirrorFactory())
20
+ ProcessorProvider.addProcessor("blur", BlurFactory(context))
21
+
22
+ // Background-image variants — one factory per source preset. JS side
23
+ // emits "background-image-{source}" so each preset gets its own
24
+ // ProcessorProvider entry. Parameterized dispatch via uniforms lands
25
+ // when we extend the upstream rn-webrtc API surface.
26
+ ProcessorProvider.addProcessor(
27
+ "background-image-office-1",
28
+ BackgroundImageFactory(context, "office-1"),
29
+ )
30
+ ProcessorProvider.addProcessor(
31
+ "background-image-office-2",
32
+ BackgroundImageFactory(context, "office-2"),
33
+ )
34
+
35
+ // Architecture-proof hook from PLAN.md Commit 3. Removed in the cleanup
36
+ // pass before v0.1 ships.
37
+ ProcessorProvider.addProcessor("gpu-passthrough", GpuEffectFactory())
38
+ }
39
+ }