react-native-webrtc-kaleidoscope 2.7.3 → 2.7.4
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.
- package/README.md +59 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,18 +44,16 @@ Every other turnkey option we could find is a feature welded to one vendor's cal
|
|
|
44
44
|
|
|
45
45
|
What you get:
|
|
46
46
|
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
- **[Drop-in components
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **[Ship only the presets you reference.](#only-ship-what-you-use)** Per-asset subpath exports plus `sideEffects: false`; web tree-shakes by import and `expo prebuild` copies only the assets your book names into the native bundle.
|
|
54
|
-
- **[A new shader is one folder.](#make-your-own-presets)** Every effect is a layer in one [compositor](#architecture); drop a `.frag` into `catalog/shaders/` and it codegens to web, Android, and iOS, masked and oriented for free.
|
|
47
|
+
- **Four simple functions.** `bindKaleidoscope(track, { presets })` hands back [`kaleidoscope`, `transform`, `mask`, and `dispose`](#the-four-verbs); that is the whole runtime API.
|
|
48
|
+
- **Agent-first setup.** Point a coding agent at [`llms.txt`](./llms.txt) and it [installs the package, writes the config plugin, and gets an effect on screen](#with-an-agent) without you babysitting it.
|
|
49
|
+
- **Turnkey implementation.** [Drop-in components](#quick-start), a picker, a live editor, and a persistence provider, render [dozens of presets](#presets) over your camera; wire a callback, ship it.
|
|
50
|
+
- **Cost and tooling.** Every shader carries a [measured GPU cost](#performance) you can read before you ship, and the [bench, meter, and thumbnail tools](#authoring-tooling) come in the box.
|
|
51
|
+
- **Won't bloat your binary.** Per-asset subpath exports and `sideEffects: false` mean you [ship only the presets you reference](#only-ship-what-you-use); web tree-shakes and native bundles just the assets your book names.
|
|
52
|
+
- **Built for extension.** A new shader is one folder that codegens to every platform, [clear by construction](#architecture); remix the compositor to [build your own worlds](#make-your-own-presets).
|
|
55
53
|
|
|
56
54
|
## Presets
|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
The demo book ships the gallery below; **every tile is a live link**, so click one and it opens on your own camera. Bring your own with a few lines (see [Make your own presets](#make-your-own-presets)).
|
|
59
57
|
|
|
60
58
|
<!-- PRESET-WAFFLE:START -->
|
|
61
59
|
|
|
@@ -73,7 +71,6 @@ Like a synthesizer, the fastest way to judge it is to hear the patches. The demo
|
|
|
73
71
|
<tr><td align="right" valign="middle"><sub><b>Sci-Fi</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=sci-fi-light" title="Landscape"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/sci-fi-light.thumb.webp" alt="Landscape" title="Landscape" width="58" /></a></td></tr>
|
|
74
72
|
<tr><td align="right" valign="middle"><sub><b>Ocean</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=oceanscape-dark" title="Underwater"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/oceanscape-dark.thumb.webp" alt="Underwater" title="Underwater" width="58" /></a></td></tr>
|
|
75
73
|
<tr><td align="right" valign="middle"><sub><b>Debug</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=debug-resolutions" title="Resolutions"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/debug-resolutions.thumb.webp" alt="Resolutions" title="Resolutions" width="58" /></a></td></tr>
|
|
76
|
-
<tr><td align="right" valign="middle"><sub><b>User</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=wolf-cave" title="Wolf Cave"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/wolf-cave.thumb.webp" alt="Wolf Cave" title="Wolf Cave" width="58" /></a></td></tr>
|
|
77
74
|
<tr><td align="right" valign="middle"><sub><b>Sky</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=clouds" title="Daytime"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/catalog/composites/clouds/clouds.thumb.webp" alt="Daytime" title="Daytime" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=clouds-dawn" title="Dawn"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/clouds-dawn.thumb.webp" alt="Dawn" title="Dawn" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=clouds-dusk" title="Dusk"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/clouds-dusk.thumb.webp" alt="Dusk" title="Dusk" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=clouds-night" title="Night"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/clouds-night.thumb.webp" alt="Night" title="Night" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=clouds-otherworld" title="Otherworld"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/clouds-otherworld.thumb.webp" alt="Otherworld" title="Otherworld" width="58" /></a></td></tr>
|
|
78
75
|
<tr><td align="right" valign="middle"><sub><b>Plasma</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=plasma-ocean" title="Ocean"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/plasma-ocean.thumb.webp" alt="Ocean" title="Ocean" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=plasma-sunset" title="Sunset"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/plasma-sunset.thumb.webp" alt="Sunset" title="Sunset" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=plasma-mint" title="Mint"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/plasma-mint.thumb.webp" alt="Mint" title="Mint" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=plasma-fast" title="Fast"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/plasma-fast.thumb.webp" alt="Fast" title="Fast" width="58" /></a></td></tr>
|
|
79
76
|
<tr><td align="right" valign="middle"><sub><b>Kaleidoscope</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=kaleidoscope-stained-glass" title="Stained Glass"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/kaleidoscope-stained-glass.thumb.webp" alt="Stained Glass" title="Stained Glass" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=kaleidoscope-mandala" title="Mandala"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/kaleidoscope-mandala.thumb.webp" alt="Mandala" title="Mandala" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=kaleidoscope-prism" title="Prism"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/kaleidoscope-prism.thumb.webp" alt="Prism" title="Prism" width="58" /></a></td></tr>
|
|
@@ -87,7 +84,7 @@ Like a synthesizer, the fastest way to judge it is to hear the patches. The demo
|
|
|
87
84
|
<tr><td align="right" valign="middle"><sub><b>Data-Mesh</b></sub></td><td valign="middle"><a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=data-mesh-datafield" title="Datafield"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/data-mesh-datafield.thumb.webp" alt="Datafield" title="Datafield" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=data-mesh-boardroom" title="Boardroom"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/data-mesh-boardroom.thumb.webp" alt="Boardroom" title="Boardroom" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=data-mesh-acid" title="Acid"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/data-mesh-acid.thumb.webp" alt="Acid" title="Acid" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=data-mesh-cobalt" title="Cobalt"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/data-mesh-cobalt.thumb.webp" alt="Cobalt" title="Cobalt" width="58" /></a> <a href="https://simiancraft.github.io/react-native-webrtc-kaleidoscope/?preset=data-mesh-slate" title="Slate"><img src="https://raw.githubusercontent.com/simiancraft/react-native-webrtc-kaleidoscope/main/demo/assets/thumbnails/data-mesh-slate.thumb.webp" alt="Slate" title="Slate" width="58" /></a></td></tr>
|
|
88
85
|
</table>
|
|
89
86
|
|
|
90
|
-
<sub>
|
|
87
|
+
<sub>63 presets across 4 families (Effects, Worlds, Backgrounds, Shaders); click any to open it live, or <a href="#make-your-own-presets">make your own</a> in a few lines.</sub>
|
|
91
88
|
|
|
92
89
|
<!-- PRESET-WAFFLE:END -->
|
|
93
90
|
|
|
@@ -164,14 +161,14 @@ import { presets } from './kaleidoscope.preset-book';
|
|
|
164
161
|
const stream = await mediaDevices.getUserMedia({ video: true });
|
|
165
162
|
const [track] = stream.getVideoTracks();
|
|
166
163
|
|
|
167
|
-
const { kaleidoscope } = bindKaleidoscope(track, {
|
|
164
|
+
const { kaleidoscope, dispose } = bindKaleidoscope(track, {
|
|
168
165
|
presets,
|
|
169
|
-
// Web
|
|
170
|
-
// Native mutates the bound track in place.
|
|
166
|
+
// Web yields a NEW track per command; read it here. Native mutates in place.
|
|
171
167
|
onTrack: (out) => {/* setPreviewTrack(out) */},
|
|
172
168
|
});
|
|
173
169
|
|
|
174
170
|
kaleidoscope('wizard-tower'); // autocompletes from your book
|
|
171
|
+
// call dispose() on unmount to release the track
|
|
175
172
|
```
|
|
176
173
|
|
|
177
174
|
For a ready-made gallery, drop in the picker; it reads your book directly:
|
|
@@ -206,54 +203,71 @@ On web, LiveKit owns the `RTCRtpSender`, so you cannot swap the track yourself;
|
|
|
206
203
|
```ts
|
|
207
204
|
import { KaleidoscopeProcessor, setMaskTuning } from 'react-native-webrtc-kaleidoscope/livekit';
|
|
208
205
|
|
|
209
|
-
|
|
210
|
-
|
|
206
|
+
// A processor effect is a `composite` spec: the same layer stack a preset projects into.
|
|
207
|
+
const composite = {
|
|
208
|
+
name: 'composite',
|
|
209
|
+
layers: [
|
|
210
|
+
{ id: 'bg', shader: 'blur', uniforms: { sigma: 8 } },
|
|
211
|
+
{ id: 'you', shader: 'direct', target: 'subject' },
|
|
212
|
+
],
|
|
213
|
+
};
|
|
214
|
+
await localVideoTrack.setProcessor(
|
|
215
|
+
new KaleidoscopeProcessor([composite]),
|
|
216
|
+
true,
|
|
217
|
+
);
|
|
218
|
+
setMaskTuning({ hardness: 0.2, threshold: 0.85 }); // the processor-path twin of `mask`
|
|
211
219
|
```
|
|
212
220
|
|
|
213
|
-
The processor
|
|
221
|
+
The processor takes the same effect inputs as the core API: a `composite` spec (its layer stack), or a bare transform name like `'flip-x'`; not a preset-book id. The `true` shows the processed stream in your local preview. It tears down its Insertable-Streams pipeline on camera flip (`restart`) and unpublish (`destroy`), so repeated flips do not leak generators.
|
|
214
222
|
|
|
215
223
|
## Concepts
|
|
216
224
|
|
|
217
|
-
|
|
225
|
+
The vocabulary, in the order you meet it.
|
|
218
226
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
227
|
+
| Term | What it is |
|
|
228
|
+
|---|---|
|
|
229
|
+
| **Preset book** | The file you author (`kaleidoscope.preset-book.ts`): a flat, typed map of the effects your app can command. Your point of entry; everything hangs off it. Declare `as const satisfies KaleidoscopePresetBook` for per-layer typing and id autocomplete. |
|
|
230
|
+
| **Preset** | One named entry in the book: `{ name, taxonomy, thumbnail?, layers, controls? }`. What `kaleidoscope(id)` applies. `taxonomy` is the picker's grouping path (`[group, category]`). |
|
|
231
|
+
| **Layer** | One entry in a preset's stack, painted back to front, addressed by a unique `id`. Three fields shape it:<br>• **shader**: what it draws (`image`, `direct` the camera, `blur`, or a generative shader like `plasma` or `clouds`).<br>• **target**: where it lands, `background` (fullscreen) or `subject` (stenciled to the person).<br>• **blend**: how it stacks, opaque, `normal` (alpha-over), or `additive`. |
|
|
232
|
+
| **Composite** | What a preset becomes at runtime: the layer stack rendered into the frame. One registered native effect; "one effect" is a composite with a single layer. |
|
|
233
|
+
| **Patch** | A partial uniform override addressed by a layer `id`, merged over the baked values live with no rebuild. The lever the live editor and persistence ride on. |
|
|
234
|
+
| **Controls** | The editor component a preset supplies (`controls?`) so its tunable uniforms get sliders in the live panel. |
|
|
223
235
|
|
|
224
|
-
|
|
236
|
+
`direct` + `subject` is the masked person; `direct` + `background` is the raw camera frame.
|
|
225
237
|
|
|
226
|
-
## The
|
|
238
|
+
## The four verbs
|
|
227
239
|
|
|
228
240
|
<p align="center">
|
|
229
|
-
<code>kaleidoscope</code> • <code>transform</code> • <code>mask</code>
|
|
241
|
+
<code>kaleidoscope</code> • <code>transform</code> • <code>mask</code> • <code>dispose</code>
|
|
230
242
|
</p>
|
|
231
243
|
|
|
232
|
-
`bindKaleidoscope(track, { presets })` returns
|
|
244
|
+
`bindKaleidoscope(track, { presets })` returns four functions (plus the live `track`). That is the whole runtime API.
|
|
245
|
+
|
|
246
|
+
| Verb | What it does |
|
|
247
|
+
|---|---|
|
|
248
|
+
| **`kaleidoscope(id, patches?)`** | Swap the background. Pass a preset id; optionally patch a layer's uniforms live, addressed by `id`. Pass `null` to clear. |
|
|
249
|
+
| **`transform(state?)`** | Absolute flip and rotate, snapped to 90°. Every call is the full state from identity; call bare to reset. |
|
|
250
|
+
| **`mask(edge)`** | Tune the one segmentation edge shared by every effect: `hardness` and `threshold`, both `0..1`. |
|
|
251
|
+
| **`dispose()`** | Tear down the pipeline and release the bound track. Call on unmount. |
|
|
233
252
|
|
|
234
253
|
```ts
|
|
235
|
-
const { kaleidoscope, transform, mask } =
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
kaleidoscope('wizard-tower');
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
kaleidoscope(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// transform: absolute geometry. Every call is the full state from identity;
|
|
246
|
-
// re-pass what you want to keep. rotate snaps to the nearest 90°.
|
|
254
|
+
const { kaleidoscope, transform, mask, dispose } =
|
|
255
|
+
bindKaleidoscope(track, { presets, onTrack });
|
|
256
|
+
|
|
257
|
+
kaleidoscope('wizard-tower'); // a preset id
|
|
258
|
+
kaleidoscope('blur-soft', [ // patch a layer live, by id
|
|
259
|
+
{ id: 'bg', shader: 'blur', uniforms: { sigma: 9 } },
|
|
260
|
+
]);
|
|
261
|
+
kaleidoscope(null); // clear the art
|
|
262
|
+
|
|
247
263
|
transform({ flip: { x: true }, rotate: 90 });
|
|
248
|
-
transform();
|
|
264
|
+
transform(); // reset to identity
|
|
249
265
|
|
|
250
|
-
// mask: one segmentation edge for the whole composite (not per layer). Both 0..1.
|
|
251
266
|
mask({ hardness: 0.5, threshold: 0.5 });
|
|
267
|
+
dispose(); // on unmount
|
|
252
268
|
```
|
|
253
269
|
|
|
254
|
-
Many uniforms are normalized `0..1
|
|
255
|
-
|
|
256
|
-
**Tuning note.** All three platforms run MediaPipe selfie segmentation, so the mask edge that suits one may differ slightly from another. `mask` defaults to `0.5 / 0.5`; nudge `hardness` and `threshold` to match your camera and lighting.
|
|
270
|
+
Many uniforms are normalized `0..1`; others (`sigma`, scales, counts) carry natural units, and JSDoc documents each range. `mask` defaults to `0.5 / 0.5`; nudge it to match your camera and lighting.
|
|
257
271
|
|
|
258
272
|
## Make your own presets
|
|
259
273
|
|
|
@@ -272,7 +286,7 @@ A preset is a composition: **every preset is a back-to-front stack of N layers**
|
|
|
272
286
|
},
|
|
273
287
|
```
|
|
274
288
|
|
|
275
|
-
The
|
|
289
|
+
The demo book's [`wolf-cave`](./demo/kaleidoscope.preset-book.ts) is a runnable example of a custom composite (a bundled image plus the masked person). It is demo-owned, its image not shipped in the package, which is the point: it shows a consumer adding their own background.
|
|
276
290
|
|
|
277
291
|
- **Bundled images** ship as tree-shakeable `image` layers, filed by category and imported per image (`import { officeDark } from 'react-native-webrtc-kaleidoscope/images/office/office-dark'`). On web a `source` can also be any image URL or data URI; native resolves bundled ids only. See [`catalog/images/README.md`](./catalog/images/README.md).
|
|
278
292
|
- **New shaders** drop a single `.frag` + typed `.ts` into `catalog/shaders/<name>/`; `bun run build:shaders` codegens the web and Android sources and transpiles the iOS Metal. The canonical upright frame and the mask stencil come for free; you write zero orientation code. See [`catalog/shaders/README.md`](./catalog/shaders/README.md).
|
|
@@ -282,7 +296,7 @@ After adding a preset to the demo book, regenerate its thumbnail and this README
|
|
|
282
296
|
|
|
283
297
|
## Drop-in UI
|
|
284
298
|
|
|
285
|
-
Build your own controls against the
|
|
299
|
+
Build your own controls against the four verbs, or import the headless, controlled components. All are presentational: they emit a selection or a patch, you apply it.
|
|
286
300
|
|
|
287
301
|
### The picker
|
|
288
302
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-webrtc-kaleidoscope",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.4",
|
|
4
4
|
"description": "Live video effects (blur, background replacement, generative backgrounds, flip/rotate) for react-native-webrtc, packaged as a managed-Expo-friendly Expo Module. Working on web, Android, and iOS. Active development.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|