session.camera.startStream(). One method, three modes - managed relay (default), relay with restreaming, or direct to your own server.
Quick Start
Pick the option that matches what you want to do:Stream with viewer URLs (managed relay)
The default. Glasses stream to the MentraOS cloud relay, which handles quality normalization, reconnection, and provides playback URLs.Stream to YouTube, Twitch, etc.
Stream through the managed relay and fan out to external platforms. More reliable than streaming directly from the glasses because the relay handles quality and reconnection.Stream directly to your own server
Glasses connect straight to your URL. No cloud relay in the middle. Supports SRT, RTMP, RTMPS, and WHIP protocols.Which should I use?
| I want to… | Use |
|---|---|
| Get WebRTC/HLS viewer URLs for my app | startStream() (default) |
| Go live on YouTube/Twitch | startStream({ destinations: [...] }) |
| Stream to my own local server | startStream({ direct: "srt://..." }) |
| Record video locally for testing | startStream({ direct: "srt://..." }) + FFmpeg |
| Process video with CV/AI | startStream() then consume the WebRTC URL |
Managed Streaming
When you callstartStream() without direct, the glasses stream to the MentraOS cloud relay. The relay provides:
- WebRTC playback with sub-second latency (default)
- HLS/DASH playback when destinations are provided
- Quality normalization so upstream services accept the stream
- Reconnection handling if the glasses have a brief network blip
- Multi-region servers for lower latency to the relay
- Fan-out to multiple destinations from a single stream
Stream result
Quality options
Video and audio configuration
UseframeRate (not fps) for the SDK field name.
Supported video parameters
When you setvideo, each field you pass must be an integer within these ranges (matching glasses-side parsing). Omitted fields use glasses defaults.
- width: 320–1920 (default 854)
- height: 240–1080 (default 480)
- frameRate: 10–60 fps (default 15)
- bitrate: 100_000–10_000_000 bits per second (default 1_000_000)
video values cause the SDK to throw RangeError before any request is sent. Portrait resolutions are not yet recommended on Mentra Live.
Direct Streaming
When you passdirect, the glasses connect straight to the URL you provide. The cloud relay is not used. No viewer URLs are returned.
Supported protocols
| Protocol | URL format | Notes |
|---|---|---|
| SRT | srt://host:port?mode=caller | Recommended. Low latency, handles packet loss well. |
| RTMP | rtmp://host/app/key | Widely supported. Higher latency than SRT. |
| RTMPS | rtmps://host/app/key | RTMP over TLS. |
| WHIP | https://host/whip/endpoint | WebRTC ingest. |
Recording locally with FFmpeg
Start FFmpeg as an SRT listener on your computer:Stream Status
Monitor the stream status regardless of mode (managed or direct):"initializing", "active", "stopped", and "error".
Always subscribe to status events before starting a stream. For managed streams, don’t use playback URLs until status reports "active".
Stopping a Stream
stopStream() stops whichever mode is active (managed or direct):
Permissions
Your app needs the camera permission to stream video. Add it in the Developer Console when creating or editing your app.Sound
By default, the glasses play a sound when streaming starts and stops (privacy indicator for bystanders). You can control the sound:Checking for Existing Streams
If your app crashes or a session disconnects unexpectedly, the glasses may still have an active stream running. UsecheckExistingStream() to detect and adopt orphaned streams from previous sessions.
Return type
checkExistingStream() returns Promise<ExistingStreamInfo>:
Typical usage at session start
Complete Example
Migrating from v2
startLocalLivestream, startLivestream, stopLocalLivestream, stopLivestream) still work via the compatibility layer. See the Migration Guide for the full list of changes.
