Skip to main content

gravix_effects 1.1.2 copy "gravix_effects: ^1.1.2" to clipboard
gravix_effects: ^1.1.2 copied to clipboard

PlatformAndroid

Gravix Effects — real-time beauty filter, reshape, makeup and looks for Flutter livestreaming. Outputs: gravix_effects_webrtc, gravix_effects_agora.

gravix_effects — Flutter plugin (Android) #

Real-time beauty filter, face reshape, makeup and looks for Flutter livestreaming. The plugin owns the camera, draws the local preview, and hands the filtered stream to your streaming stack through a small output package:

Your stack Package You get
flutter_webrtc / LiveKit gravix_effects_webrtc a flutter_webrtc video track (GravixWebRtc.attach(cam))
Agora (agora_rtc_engine 6.x) gravix_effects_agora Agora's custom video track (GravixAgora.createEngine + attach)
preview only gravix_effects no stream

gravix_effects itself depends on no streaming SDK. Android only for now (minSdk 24, OpenGL ES 3): on iOS / web / desktop GravixCamera.isSupported is false and every call throws GravixException('E_UNSUPPORTED_PLATFORM') — check it and use your normal camera there:

if (GravixCamera.isSupported) { cam = await GravixCamera.start(); out = await GravixWebRtc.attach(cam); }
else { /* your existing camera track */ }

Install #

Gravix Effects is distributed from a private git repository (you receive access from Gravix). Add only the output package for your stack by URL, sub-folder and version tag — it brings gravix_effects (from the same repo and tag) and re-exports its whole API; the Gravix Android SDK is bundled inside (android/maven), nothing else to configure:

dependencies:
  flutter_webrtc: ">=1.0.0 <2.0.0"      # or agora_rtc_engine — your stack, as you use it today
  gravix_effects_webrtc:                # or gravix_effects_agora
    git:
      url: <the Gravix repository URL you were given>
      path: gravix_effects_webrtc
      ref: v1.0.0

Do not also list gravix_effects itself (pub then sees two git references to it and stops); import package:gravix_effects_webrtc/gravix_effects_webrtc.dart (or _agora) — plus package:gravix_effects/beauty_ui.dart for the ready-made panel.

android/app/build.gradle(.kts): minSdk = 24. The camera permission (android.permission.CAMERA) is declared by the plugin and merged into your app's manifest automatically; requestPermission() asks the user for it at run time. Release builds with R8 need no extra keep rules (the SDK ships its consumer rules; verified with a minified release app). Hosting the SDK on your own Maven instead: set GRAVIX_MAVEN_URL (+ GRAVIX_MAVEN_USER / GRAVIX_MAVEN_PASSWORD) as a Gradle property or environment variable.

Licence: proprietary — see LICENSE.

Camera + preview #

await GravixCamera.preload();                       // early (e.g. lobby screen): loads the face model, ~0.6-1.7 s
if (!await GravixCamera.requestPermission()) return;
final cam = await GravixCamera.start(lens: GravixLens.front, fps: 30);   // 540p effects + 540x960 stream
// preview (drawn by the engine; mirrored for the front camera):
GravixPreview(cam)
await cam.switchCamera();                           // same track / publication; completes when the new camera shows
await cam.setEnabled(false);                        // plain camera, stream keeps running
await cam.stop();

Orientation: portrait apps (the owner's target, Priyu Live, is portrait-only — 2026-09-27). The camera orientation is set when the camera starts; live rotation to landscape is not supported yet.

resolution = processing short side (540 default = the stream size; 720 = sharper local preview on stronger phones, more GPU). The stream frames are cam.streamSize (540×960 default) and reach your stack as I420 (one asynchronous GPU readback per frame), so every encoder — including software VP8, which many phones use — holds full rate: measured 28–30 fps, 540×960 received at 30 fps, 0 drops, on a heat-throttled Redmi Note 11 with LiveKit VP8 3-layer simulcast. The stream is sent un-mirrored; viewers mirror a front-camera host themselves (e.g. LiveKit VideoTrackRenderer(mirrorMode: …)), or pass mirrorStream: true.

Publish with LiveKit (gravix_effects_webrtc) #

Step-by-step integration into an existing LiveKit app (written for AI coding agents, from the Priyu Live integration): gravix_effects_webrtc/AGENTS.md.

final out = await GravixWebRtc.attach(cam);          // textureFrames: true = zero-copy, hardware encoders only
final track = LocalVideoTrack(TrackSource.camera, out.stream, out.videoTrack, const CameraCaptureOptions());
await room.localParticipant!.publishVideoTrack(track);
// do NOT call track.setCameraPosition / restartTrack — use cam.switchCamera()

(LocalVideoTrack's constructor is annotated @internal in livekit_client 2.x; ignore the analyzer hint.)

Publish with Agora (gravix_effects_agora) #

final engine = await GravixAgora.createEngine(const RtcEngineContext(appId: appId)); // instead of createAgoraRtcEngine()
await engine.enableVideo();
await engine.joinChannel(token: token, channelId: channel, uid: 0, options: const ChannelMediaOptions(
    clientRoleType: ClientRoleType.clientRoleBroadcaster,
    publishCameraTrack: false, publishCustomVideoTrack: true, publishMicrophoneTrack: true));
await GravixAgora.attach(cam);
// …
await cam.stop();
await GravixAgora.releaseEngine(engine);

The engine is Agora's own (created natively so Gravix can push frames into it) — use Agora's Dart API as usual. Create it through Gravix before any other Agora call: an engine made with createAgoraRtcEngine() cannot be adopted. Measured on a throttled Redmi Note 11: 28–30 fps sent at 540×960, 0 push failures. Note: agora_rtc_engine 6.6.4 compiles against Android API 31, which current AndroidX rejects — every Agora app needs this in its root android/build.gradle.kts (see gravix_effects_agora/example):

subprojects {
    plugins.withId("com.android.library") {
        extensions.getByType(com.android.build.api.variant.LibraryAndroidComponentsExtension::class.java)
            .finalizeDsl { if ((it.compileSdk ?: 0) < 34) it.compileSdk = 36 }
    }
}

Looks #

final glow  = await GravixLooks.builtin('glow');              // natural, smooth, glow, fresh, rosy, fair
final party = await GravixLooks.fromAsset('assets/looks/party.gfx');
final promo = await GravixLooks.fromUrl('https://cdn.example.com/promo.gfx', sha256: '…'); // cached, validated
Image.memory(promo.thumbnail!);                                // preview image
await cam.applyLook(promo);
await GravixLooks.prefetch([url1, url2]); await GravixLooks.clearCache();

Remote looks: HTTPS only, validated before caching, revalidated (ETag / Last-Modified), served from cache when offline, LRU 50 MB. A bad file is a GravixException with a code — never a crash.

Sliders, makeup, colour grade #

await cam.setAdjustments(tone: {'smoothness': 0.7, 'whiten': 0.2}, region: {'lipTint': 0.5},
    lipTintColor: [0.8, 0.2, 0.3], reshape: {'faceSlim': 0.4});
await cam.setLut('bright');          // SDK LUTs + any 512x512 HALD PNG at android/app/src/main/assets/luts/<name>.png
await cam.setLutBytes(pngBytes);     // or from bytes
await cam.clearAdjustments();        // back to the look
final values = await cam.currentValues();   // for positioning sliders

Values are absolute and clamped by the SDK to each parameter's range; adjustments survive look switches.

Drop-in for the legacy BeautyFilter API #

import 'package:gravix_effects/compat/beauty_filter.dart';
BeautyFilter.camera = cam;                     // once, after start
await BeautyFilter.applyPreset('smooth');      // existing beauty sheets keep working

Same static names as the legacy plugin (setSmoothness … setBlemish, setLut, setMakeup, applyMakeupPreset, applyPreset, setEnabled, reset). attach / attachToTrackId / setMinFps become no-ops. Brows have no SDK equivalent.

Audio / video #

The engine shows each frame ~250 ms after capture (this keeps the effects glued to the face). The plugin hands WebRTC each frame's true capture time (timestamp alignment off), so viewers get audio and video in sync (measured: audio 46 ms behind the lips at the viewer; a plain camera is 20 ms). The cost: the whole stream reaches viewers ~0.25 s later.

Example #

Each package has a small example with the same screen — camera preview, looks, the ready-made beauty panel, camera switch — plus its own action:

Example Shows Run
gravix_effects/example preview only (no streaming SDK) flutter run
gravix_effects_webrtc/example + Go live / End live to a LiveKit room (video + mic) flutter run --dart-define=LK_URL=… --dart-define=LK_TOKEN=…
gravix_effects_agora/example + Go live / End live on an Agora channel (video + mic) flutter run --dart-define=AGORA_APP_ID=… --dart-define=AGORA_TOKEN=… --dart-define=CHANNEL=…
1
likes
140
points
36
downloads

Documentation

API reference

Publisher

verified publishergravixcloud.com

Weekly Downloads

Gravix Effects — real-time beauty filter, reshape, makeup and looks for Flutter livestreaming. Outputs: gravix_effects_webrtc, gravix_effects_agora.

Homepage

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on gravix_effects

Packages that implement gravix_effects