`hello everyone , i am try to apply deep ar effect...
# ask-ai
g
hello everyone , i am try to apply deep ar effects on Live kit track , any guide or doc?
t
Thanks for reaching out, CTO. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’m happy to help with applying DeepAR effects to a LiveKit track. To make sure I give the right guidance: 1. Do you want to apply DeepAR effects on the publisher side (before sending the track to LiveKit) or on the subscriber side (after receiving the track)? 2. Which platform are you building for: web (browser), iOS, or Android? 3. Are you using an existing DeepAR SDK (DeepAR, Banuba, Snap AR, etc.)? If so, which one and which version? 4. Is the track video from a camera (live) or pre-recorded? Once you tell me those details I’ll outline the exact integration approach and provide sample steps or code snippets. If you’re not sure, say what you’ve tried so far and I’ll suggest the most typical setup.
g
1- apply DeepAR effects on the publisher side (before sending the track to LiveKit) 2 - flutter (android-ios) 3-DeepAR 4- from the camera
t
Thanks — this is helpful. I’ll guide you to publish a DeepAR-processed live camera track from Flutter into LiveKit. Before I provide platform-specific steps and code sketches, I need the following answers so I give an accurate, minimal plan: 1. Which LiveKit Flutter SDK version are you using (or will you use the latest)? 2. Which DeepAR SDKs/versions will you integrate on Android and iOS (native SDKs or a Flutter plugin)? 3. Can you add native Android (Kotlin/Java) and iOS (Swift/Obj‑C) code to your Flutter app (i.e., use platform channels and native views)? 4. Which Flutter camera approach are you currently using or prefer: the
camera
plugin, another plugin, or LiveKit’s built-in capturer? 5. Target latency, resolution, and framerate (e.g., 720p@30fps)? 6. Will you also publish audio from the same device? 7. Any device or OS minimums or performance constraints to consider? Pick one to start with: Android, iOS, or a combined architecture overview. Once you reply I’ll provide the recommended architecture and step-by-step integration plan (native capture → DeepAR processing → feed frames into LiveKit via custom video source), plus code sketches for your chosen platform.
g
1- flutter sdk -> 3.8.1 livekit->livekit_client: ^2.5.0+hotfix.3 deepar ->leatest package vibe.zo.app import android.graphics.* import android.media.Image import android.os.Build import androidx.annotation.RequiresApi import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result import java.nio.ByteBuffer import android.renderscript.* class BeautyFilterPlugin : FlutterPlugin, MethodCallHandler { private lateinit var channel: MethodChannel private var beautyFilter: BeautyFilter? = null override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { channel = MethodChannel(flutterPluginBinding.binaryMessenger, "vibez_beauty_filter") channel.setMethodCallHandler(this) beautyFilter = BeautyFilter(flutterPluginBinding.applicationContext) } override fun onMethodCall(call: MethodCall, result: Result) { when (call.method) { "initialize" -> { beautyFilter?.initialize() result.success(true) } "updateSettings" -> { val enabled = call.argument<Boolean>("enabled") ?: true val smoothing = call.argument<Double>("smoothing")?.toFloat() ?: 0.5f val brightness = call.argument<Double>("brightness")?.toFloat() ?: 0.3f beautyFilter?.updateSettings(enabled, smoothing, brightness) result.success(true) } "createBeautyVideoTrack" -> { result.success(mapOf( "success" to true, "message" to "Beauty filter initialized for video track" )) } "dispose" -> { beautyFilter?.dispose() result.success(true) } else -> { result.notImplemented() } } } override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel.setMethodCallHandler(null) beautyFilter?.dispose() } } class BeautyFilter(private val context: android.content.Context) { private var renderScript: RenderScript? = null private var blurScript: ScriptIntrinsicBlur? = null private var colorMatrixScript: ScriptIntrinsicColorMatrix? = null private var isEnabled = false private var smoothIntensity = 0.5f private var brightnessIntensity = 0.3f fun initialize() { renderScript = RenderScript.create(context) // Initialize blur script for smoothing val element = Element.U8_4(renderScript) blurScript = ScriptIntrinsicBlur.create(renderScript, element) // Initialize color matrix script for brightness/contrast colorMatrixScript = ScriptIntrinsicColorMatrix.create(renderScript, element) } fun updateSettings(enabled: Boolean, smoothing: Float, brightness: Float) { isEnabled = enabled smoothIntensity = smoothing.coerceIn(0f, 1f) brightnessIntensity = brightness.coerceIn(0f, 1f) } @RequiresApi(Build.VERSION_CODES.LOLLIPOP) fun processBitmap(inputBitmap: Bitmap): Bitmap { if (!isEnabled) return inputBitmap val outputBitmap = inputBitmap.copy(inputBitmap.config ?: Bitmap.Config.ARGB_8888, true) renderScript?.let { rs -> val inputAllocation = Allocation.createFromBitmap(rs, inputBitmap) val outputAllocation = Allocation.createFromBitmap(rs, outputBitmap) // Apply smoothing (bilateral filter effect) if (smoothIntensity > 0) { blurScript?.apply { setRadius(smoothIntensity * 10f) setInput(inputAllocation) forEach(outputAllocation) } } // Apply color adjustments for beauty effect if (brightnessIntensity > 0) { val colorMatrix = Matrix4f() // Brightness adjustment val brightness = 1f + brightnessIntensity * 0.3f colorMatrix.set(0, 0, brightness) // Red colorMatrix.set(1, 1, brightness) // Green colorMatrix.set(2, 2, brightness) // Blue colorMatrix.set(3, 3, 1f) // Alpha // Add warm tone for skin enhancement colorMatrix.set(0, 3, brightnessIntensity * 0.05f) // Red bias colorMatrix.set(1, 3, brightnessIntensity * 0.03f) // Green bias colorMatrixScript?.apply { setColorMatrix(colorMatrix) forEach(inputAllocation, outputAllocation) } } outputAllocation.copyTo(outputBitmap) } return outputBitmap } fun dispose() { blurScript?.destroy() colorMatrixScript?.destroy() renderScript?.destroy() } } android bridge (e.g., 720p@30fps) yes publish audio
t
Thanks — this is great detail. I’ll respond to your request about applying DeepAR effects on the publisher side from a Flutter app (Android + iOS), using your Flutter SDK 3.8.1 and LiveKit client ^2.5.0+hotfix.3, camera input (720p@30fps), and publishing audio. Below is a concise, actionable plan with steps and focused code guidance to integrate DeepAR (native) into your existing Android bridge and feed processed frames into LiveKit via a custom video source. If you want, I can follow up with a full working repo or the iOS counterpart after you confirm. Summary of approach • Capture camera frames in Flutter (camera plugin or native camera). • Send frames to native (Android/iOS) via platform channel/texture. • Process frames with DeepAR (preferred) or your RenderScript filter. • Deliver processed frames back into Flutter as a custom LiveKit VideoSource (zero-copy texture or I420 buffer). • Publish the custom video track together with the microphone audio. High-level integration steps 1. Use a custom VideoSource in LiveKit Flutter to accept frames delivered from native. 2. On Android, replace the RenderScript pipeline with DeepAR processing or call DeepAR on the GPU, then output frames as a texture or I420 frames. 3. Send processed frames to Flutter: ◦ Preferred: share a SurfaceTexture / OES texture to Flutter (zero-copy). ◦ Acceptable prototype: convert to I420 byte buffer and send via platform channel (higher CPU). 1. In Flutter, feed those frames into LiveKit by creating a LocalVideoTrack from the custom VideoSource and publishing it. 2. Publish audio separately as a LocalAudioTrack (keeps audio unaffected by video processing). Concrete Android guidance (use with your BeautyFilterPlugin) 1. Capture camera frames ◦ If using the Flutter
camera
plugin: use
startImageStream
and forward frames to Android native for processing. ◦ For best performance on Android: capture natively with Camera2/ImageReader and produce Surface for DeepAR input. 1. Integrate DeepAR on Android ◦ Initialize DeepAR in native plugin and attach the camera Surface/texture to DeepAR input. ◦ Use DeepAR’s frame callback or output texture to obtain processed frames. Avoid CPU bitmap round-trips when possible. 1. Deliver processed frames to Flutter / LiveKit ◦ Preferred (low-latency): expose DeepAR output texture as an external texture to Flutter or as a SurfaceTexture and use LiveKit’s native VideoSource to push frames directly into the SDK (zero-copy). ◦ Prototype (simpler): convert DeepAR output to I420 bytes and call a platform channel method, e.g., `onFrameAvailable`: ▪︎ Send payload: bytes, width, height, rotation, timestamp. ▪︎ On Flutter side, convert bytes to a LiveKit VideoFrame and call
captureFrame
on your custom VideoSource. Example additions to your Android plugin (conceptual) • Add a method channel method name:
onFrameAvailable
. • After processing a frame (bitmap or buffer), convert to I420 (or NV21 if that’s what LiveKit expects) and call: channel.invokeMethod("onFrameAvailable", mapOf("bytes" to byteArray, "width" to w, "height" to h, "rotation" to rot, "timestamp" to ts)) Flutter side: custom VideoSource usage • Implement a VideoSource subclass or use LiveKit’s API for injecting frames. • On receiving
onFrameAvailable
channel calls, build a VideoFrame and call the capture/inject API: ◦ Use LiveKit’s `VideoFrame`/`VideoBuffer` types (wrap planes for I420). ◦ Ensure timestamps and rotation are provided. • Create and publish LocalVideoTrack from that VideoSource: a. Start the custom source. b. Create LocalVideoTrack from source. c. Publish LocalVideoTrack along with a microphone LocalAudioTrack. Audio publishing • Capture microphone via LiveKit/local audio APIs and publish as a separate LocalAudioTrack concurrently with the custom video track. Performance recommendations • Use GPU/texture-based processing in DeepAR to avoid CPU copies. • Target 720p@30fps as you stated. • Reuse buffers and avoid frequent allocations. • Keep audio publishing separate to avoid audio interruption from heavy video processing. • If you must send frames over platform channel, batch minimal metadata and use binary buffers (not base64/JSON). Next step choices I can provide • A minimal working Android code sample converting your current RenderScript output to I420 bytes + Dart receive + LiveKit injection (prototype path). • A zero-copy approach using SurfaceTexture/texture sharing and LiveKit native VideoSource wiring (higher performance, more native code). • iOS implementation outline (Swift) for DeepAR + LiveKit (after you confirm you want iOS steps). Which would you like next: (A) Prototype using I420 byte buffers (fast to implement), (B) High-performance zero-copy texture integration, or (C) iOS implementation? Sources: client-sdk-flutter | livekit/livekit_composite | DeepWiki