Nosmai  Effects Nosmai  Moderation Nosmai Try-ons coming soon
Docs menu Android
How-to guide

Use Nosmai Effects with WebRTC on Android

Publish Nosmai's processed Android texture output through a custom WebRTC video capturer and your own signalling layer.

Platform Android SDK version Nosmai 3.0.4 · WebRTC 125.6422.07 verified example Updated Aug 22, 2026 Time 10 min

Streaming path

Nosmai processes Android camera frames before WebRTC publishes them

Raw WebRTC has no managed rooms or token service. Nosmai provides processed video, while your application owns peer connections, signalling, ICE, audio, and reconnect behaviour.

Prerequisites

  • Android API 21 or later on a physical arm64-v8a device
  • The verified Nosmai 3.0.4 AAR
  • A WebRTC library and signalling service
  • A working Nosmai camera preview
dependencies {
    implementation(files("libs/nosmai-sdk-3.0.4.aar"))
    implementation("io.github.webrtc-sdk:android:125.6422.07")
}

Share the encoder context

Create one EglBase, register it with Nosmai before initialization, and use it for WebRTC's encoder, decoder, and SurfaceTextureHelper.

val eglBase = EglBase.create()

System.loadLibrary("nosmai")
NosmaiSDK.setAgoraShareContext(
    eglBase.eglBaseContext.nativeEglContext
)
NosmaiSDK.initialize(applicationContext, nosmaiLicenseKey)

Create the processed video track

Use the NosmaiVideoCapturer from the official example. It implements WebRTC's VideoCapturer, receives processed Nosmai textures, and returns every producer slot after the frame is handed off.

val source = factory.createVideoSource(false)
val helper = SurfaceTextureHelper.create(
    "NosmaiCapture",
    eglBase.eglBaseContext,
)

val capturer = NosmaiVideoCapturer()
capturer.initialize(helper, context, source.capturerObserver)
capturer.startCapture(720, 1280, 30)

val videoTrack = factory.createVideoTrack("nosmai-video", source)
peerConnection.addTrack(videoTrack, listOf("nosmai-stream"))

Add the microphone as a normal WebRTC audio track. WebRTC must not open a second camera.

Connect through your signalling layer

Exchange SDP offers, answers, and ICE candidates through your own authenticated service. The viewer server in the example is a local test fixture, not a production signalling service.

Stop in the correct order

  1. Stop and dispose NosmaiVideoCapturer.
  2. Close the peer connection and signalling socket.
  3. Dispose WebRTC sources and the factory.
  4. Release Nosmai and the shared EglBase when capture ends.

Common errors

SymptomCauseFix
Local preview works but the peer receives black videoWebRTC cannot read Nosmai's texture contextRegister and reuse one EGL context before Nosmai initialization
Stream freezes after several framesA producer texture slot was not releasedRelease slots exactly once on success, drop, and error paths
Peer never connectsSDP, ICE, TURN, or signalling is incompleteInspect peer and ICE state separately from the Nosmai frame path

Verify it worked

Use the example browser viewer to confirm decoded resolution, frame rate, orientation, codec, and visible effects.

Complete example

The native Android WebRTC example contains the tested capturer, peer connection, signalling client, and local browser viewer.

Next steps

References

Was this page helpful?

Your response helps us prioritize documentation improvements.

Nosmai

An AR and AI company. Founded on the idea that the next decade of software will be visual, and that the tools for it should be within reach of anyone building.

Newsletter

Product updates and release notes. No spam.

© 2026 nosmai, inc · all rights reserved