Effects Android
Effects / Live streaming / WebRTC / Android

Stream Android AR camera effects with raw WebRTC and Nosmai

Updated August 27, 2026

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

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")
}

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.

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

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