Stream In (Ingress)

Stream into BaxCloud rooms from OBS Studio, FFmpeg, or any RTMP/WHIP-compatible encoder

Overview

BaxCloud Ingress allows external video sources like OBS Studio, FFmpeg, vMix, or hardware encoders to stream directly into a BaxCloud room. Viewers in the room see the ingress stream as a regular participant, enabling professional broadcasting setups with your existing streaming tools.

RTMP / RTMPS

Use OBS Studio, vMix, Wirecast, or any RTMP encoder. Supports secure RTMPS with TLS.

WHIP

WebRTC-HTTP Ingestion Protocol for ultra-low latency browser-based ingest (~300ms).

Any Encoder

Works with FFmpeg, GStreamer, hardware encoders, and mobile streaming apps.

RTMP vs WHIP: Which to Use?

RTMP / RTMPS

  • Best for OBS Studio, vMix, Wirecast
  • Widely supported by all streaming software
  • RTMPS provides TLS encryption
  • Latency: ~1-2 seconds
  • Codecs: H.264 video + AAC audio

WHIP (WebRTC)

  • Best for browser-based ingest
  • Ultra-low latency (~300ms)
  • Can bypass transcoding for lower CPU usage
  • OBS 30+ supports WHIP natively
  • Codecs: VP8/VP9/H.264 video + Opus audio

How Stream In Works

1. Start Streaming In

Use the API or SDK to create an ingress endpoint for a specific room. You'll receive an RTMP URL + Stream Key (for RTMP) or a WHIP URL + Bearer Token (for WHIP).

2. Configure Your Encoder

Enter the URL and stream key into OBS Studio, FFmpeg, or your preferred encoder. For RTMPS, use rtmps://rtmps.your-domain.io:1935/live with the stream key. For WHIP, use the WHIP URL with the bearer token.

3. Start Streaming

Press "Start Streaming" in your encoder. The stream appears in the BaxCloud room as a participant. All room viewers see the stream with low latency via WebRTC.

4. Monitor & Control

Monitor ingress status via the dashboard or API. The ingress transitions through states: INACTIVE → BUFFERING → ACTIVE → COMPLETE. You can delete the ingress endpoint to disconnect the encoder.

SDK Methods

All available ingress (stream-in) methods across every SDK

MethodNode.js (Server)React / React NativeFlutterKotlinSwift
Start stream instartStreamIn()startStreamIn()startStreamIn()startStreamIn()startStreamIn()
List stream inlistStreamIn()listStreamIn()listStreamIn()listStreamIn()listStreamIn()
Get stream ingetStreamIn()getStreamIn()getStreamIn()getStreamIn()getStreamIn()
Stop stream instopStreamIn()stopStreamIn()stopStreamIn()stopStreamIn()stopStreamIn()

startStreamIn() — Start Streaming In

Create an RTMP or WHIP ingress for streaming into a room from OBS, FFmpeg, etc.

1import { BaxCloudClient } from '@baxcloud/server-sdk';
2
3const client = new BaxCloudClient({
4  apiKey: process.env.BAXCLOUD_API_KEY!,
5});
6
7// Create RTMP ingress (for OBS Studio)
8const rtmpIngress = await client.startStreamIn({
9  inputType: 'RTMP_INPUT',
10  roomName: 'my-live-room',
11  participantIdentity: 'obs-streamer',
12  participantName: 'OBS Studio',
13  enableTranscoding: true,
14});
15
16console.log('RTMPS URL:', rtmpIngress.rtmpsUrl);
17console.log('Stream Key:', rtmpIngress.streamKey);
18
19// Create WHIP ingress (for browser/OBS 30+)
20const whipIngress = await client.startStreamIn({
21  inputType: 'WHIP_INPUT',
22  roomName: 'my-live-room',
23  participantIdentity: 'whip-streamer',
24  participantName: 'Browser Streamer',
25  bypassTranscoding: true,
26});
27
28console.log('WHIP URL:', whipIngress.whipUrl);
29console.log('Bearer Token:', whipIngress.token);
💡

Server-side recommended

For production apps, create ingress endpoints from your backend server. Never expose your API key in client-side code.

listStreamIn() — List Active Streams In

List all ingress endpoints, optionally filtered by room name

1const { items } = await client.listStreamIn({
2  roomName: 'my-live-room', // optional filter
3});
4
5for (const ingress of items) {
6  console.log(`[${ingress.inputType}] ${ingress.participantName}`);
7  console.log(`  Status: ${ingress.status}`);
8  console.log(`  Stream Key: ${ingress.streamKey}`);
9}

getStreamIn() — Get Stream In Details

Get the status and details of a specific ingress endpoint by ID

1const ingress = await client.getStreamIn('IN_abc123');
2console.log('Status:', ingress.status);
3// → INACTIVE | BUFFERING | ACTIVE | ERROR | COMPLETE
4console.log('Input Type:', ingress.inputType);
5console.log('Room:', ingress.roomName);

stopStreamIn() — Stop a Stream In Endpoint

Remove an ingress endpoint and disconnect the encoder

1await client.stopStreamIn('IN_abc123');
2// Encoder is disconnected immediately

Configure OBS Studio

Set up OBS to stream to your BaxCloud room

In OBS Studio, go to Settings → Stream:

For RTMPS:
  • Service: Custom...
  • Server: rtmps://rtmps.your-domain.io:1935/live
  • Stream Key: paste the stream key from startStreamIn()
For WHIP (OBS 30+):
  • Service: WHIP
  • Server: paste the WHIP URL from startStreamIn()
  • Bearer Token: paste the token from startStreamIn()
⚠️

RTMP Encoder Settings

For RTMPS, use H.264 video encoder (x264, NVENC H.264, or Apple VT H264). Do not use HEVC/H.265 or AV1 — Enhanced RTMP is not yet supported. Audio should be AAC at 128-320 kbps.

FFmpeg & Other Encoders

1# Stream a file via RTMPS
2ffmpeg -re -i input.mp4 \
3  -c:v libx264 -preset veryfast -b:v 3000k \
4  -c:a aac -b:a 128k \
5  -f flv "rtmps://rtmps.your-domain.io:1935/live/YOUR_STREAM_KEY"
6
7# Stream webcam via RTMPS (macOS)
8ffmpeg -f avfoundation -i "0:0" \
9  -c:v libx264 -preset veryfast -b:v 2500k \
10  -c:a aac -b:a 128k \
11  -f flv "rtmps://rtmps.your-domain.io:1935/live/YOUR_STREAM_KEY"
12
13# Stream webcam via RTMPS (Linux)
14ffmpeg -f v4l2 -i /dev/video0 -f pulse -i default \
15  -c:v libx264 -preset veryfast -b:v 2500k \
16  -c:a aac -b:a 128k \
17  -f flv "rtmps://rtmps.your-domain.io:1935/live/YOUR_STREAM_KEY"

Webhook Events

Receive real-time notifications for ingress lifecycle events

BaxCloud sends webhook events when an ingress stream starts, updates, or ends. Configure webhooks in your project dashboard settings.

EventDescriptionWhen
live.startedIngress stream has startedEncoder connects and stream begins buffering/active
live.updatedIngress state changedState transitions (BUFFERING → ACTIVE, etc.)
live.endedIngress stream has endedEncoder disconnects or ingress is deleted
live.failedIngress stream failedConnection error, encoding failure, etc.
1// Webhook payload for live.started
2{
3  "event": "live.started",
4  "timestamp": "2026-03-29T14:30:00Z",
5  "data": {
6    "ingressId": "IN_abc123",
7    "roomName": "my-live-room",
8    "inputType": "RTMP",             // "RTMP" or "WHIP"
9    "participantIdentity": "obs-streamer",
10    "participantName": "OBS Studio",
11    "status": "ACTIVE"
12  }
13}
14
15// Webhook payload for live.ended
16{
17  "event": "live.ended",
18  "timestamp": "2026-03-29T15:45:00Z",
19  "data": {
20    "ingressId": "IN_abc123",
21    "roomName": "my-live-room",
22    "inputType": "RTMP",
23    "participantIdentity": "obs-streamer",
24    "status": "COMPLETE",
25    "durationSec": 4500
26  }
27}
28
29// Webhook payload for live.failed
30{
31  "event": "live.failed",
32  "timestamp": "2026-03-29T14:31:00Z",
33  "data": {
34    "ingressId": "IN_abc123",
35    "roomName": "my-live-room",
36    "inputType": "RTMP",
37    "status": "ERROR",
38    "errorMessage": "Connection timeout — encoder stopped sending data"
39  }
40}

REST API Reference

MethodEndpointDescription
POST/v1/ingressCreate a new ingress endpoint
GET/v1/ingressList all ingress endpoints
GET/v1/ingress/:idGet ingress details by ID
DELETE/v1/ingress/:idDelete an ingress endpoint

Create Ingress Parameters

ParameterTypeRequiredDescription
inputTypestringYesRTMP_INPUT or WHIP_INPUT
roomNamestringYesTarget room name
participantIdentitystringYesUnique identity for the ingress participant
participantNamestringNoDisplay name shown in room
enableTranscodingbooleanNoEnable server-side transcoding (default: true)
bypassTranscodingbooleanNoWHIP only — bypass transcoding for lower latency