Skip to content

bokan/muxquito

Repository files navigation

muxquito

muxquito

npm version License

Modern WebRTC SFU built in Rust with a browser SDK, demo app, and telemetry UI. Focus: fast forwarding, adaptive quality, and real-world operability.

Try it (Docker only)

./docker-dev.sh

No Node.js, npm, or Rust required — just Docker. Builds SDK, demo, and server inside the container. Open http://localhost:8080/muxquito/ when ready.

Contents

Highlights

  • Simulcast forwarding with per-subscriber allocation. The server tracks q/h/f layers and chooses a layer per subscriber based on bandwidth + congestion, with keyframe-gated switches.
  • Adaptive streaming in the SDK. Client-side observers watch element size + visibility and request layer changes with debounce.
  • Cascading across nodes. A node can pull tracks from upstream servers (parent/child edges), and relay maps coordinate multi-node subscriptions for scale-out topologies.
  • Codec negotiation by default. VP8/VP9/H264/AV1 video, Opus + RED audio, RTX enabled.
  • Telemetry + debug. Clients stream RTC stats over a telemetry data channel; server persists and exposes a tail API alongside allocator/stats/rooms/peers endpoints.

Quick start

./docker-dev.sh   # Docker only — no local deps
./dev.sh          # local build (Node.js + Rust)
URL Description
http://localhost:8080/muxquito/ Demo app
http://localhost:8080/ui/ Telemetry UI

Demo app

Parameter Description
?room=name or #name Join room
?adaptive=0 Disable client-side layer requests

Features: mic/cam toggle, device select, screen share.

SDK (browser)

npm install muxquito-webrtc-sdk
import { Room, LocalAudioTrack, LocalVideoTrack, DeviceManager } from 'muxquito-webrtc-sdk';

const room = new Room({ reconnect: true, adaptiveStream: true, telemetry: true });
room.on('connected', () => console.log('connected'));
room.on('participantJoined', (p) => console.log('peer', p.sid));
room.on('trackSubscribed', (track) => {
  document.getElementById('videos')?.appendChild(track.attach());
});

await room.connect('ws://localhost:8080/ws', 'demo', 'alice');

const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
const audioTrack = new LocalAudioTrack(stream.getAudioTracks()[0]);
const videoTrack = new LocalVideoTrack(stream.getVideoTracks()[0], 'camera');

await room.localParticipant.publishTrack(audioTrack);
await room.localParticipant.publishTrack(videoTrack, { simulcast: true, source: 'camera' });

Server features

  • WebSocket signaling: join/leave, offer/answer/ice
  • Rooms + peer tracking
  • Simulcast forwarding with per-subscriber layer selection
  • Stream allocator (bandwidth estimate + congestion) with keyframe-gated layer switches
  • Track metadata + mute propagation
  • Audio level parsing → active speaker + audio level updates
  • Telemetry data channel ingest (client stats → disk)
  • Optional state backend: in-memory default, Redis supported
  • Optional cascade edges for multi-node experiments (debug endpoints in test mode)

SDK overview

  • Room with reconnect and adaptive stream support
  • LocalParticipant publish/unpublish + codec preferences
  • RemoteTrack.attach() / detach()
  • DeviceManager device enumeration + change events
  • Events: connected, disconnected, reconnecting, reconnected, participantJoined, participantLeft, trackSubscribed, trackUnsubscribed, trackMuted, trackUnmuted, activeSpeakerChanged, audioLevelsChanged, connectionStateChanged, connectionQualityChanged, error

Debug endpoints

Endpoint Method
/debug/stats GET
/debug/stats/:peer GET
/debug/bwe GET
/debug/bwe/:peer POST
/debug/allocator GET
/debug/layers GET
/debug/layers/:peer GET
/debug/forwarders GET
/debug/server GET
/debug/rooms GET
/debug/peers GET
/debug/telemetry/tail?room=... GET

Env vars

Variable Default Description
BIND_ADDR 0.0.0.0:8080 Server bind address
PUBLIC_BASE_PATH /muxquito Base path for demo app
STATIC_DIR demo/public Static files directory
UI_DIR server/static/ui Telemetry UI directory
STUN_SERVERS Comma-separated STUN servers
ICE_UDP_MIN Minimum UDP port for ICE
ICE_UDP_MAX Maximum UDP port for ICE
TLS_CERT_PATH TLS certificate path
TLS_KEY_PATH TLS key path
TEST_MODE Enable cascade debug endpoints
NODE_ID Node identifier
NODE_REGION Node region
NODE_CAPACITY Node capacity
STATE_BACKEND in_memory in_memory or redis
REDIS_URL Redis connection URL
STATE_USE_DEMAND_AGGREGATE Demand aggregation
STATE_PUBLISH_SUBSCRIPTIONS Publish subscriptions
ACTIVE_SET_BASE Active set base
ACTIVE_SET_MAX Active set maximum
ACTIVE_SET_SILENCE_MS Silence threshold (ms)
TELEMETRY_DIR Telemetry storage directory
CODEC_NEGOTIATION Enable codec negotiation
VIDEO_CODECS Allowed video codecs
AUDIO_CODECS Allowed audio codecs

Development

# bundle demo app
npx --package typescript tsc -p sdk/tsconfig.json
npx esbuild demo/src/main.ts --bundle --outfile=demo/public/main.js --format=esm --external:lucide --alias:muxquito-webrtc-sdk=./sdk/dist/index.js

# SDK tests
cd sdk && npm test

Docker

docker build -t muxquito .
docker run --rm --name muxquito -p 8080:8080 -p 10000-10100:10000-10100/udp muxquito

The container prints the demo, telemetry UI, WS, health, and debug URLs on startup.

# Stop the container
docker stop muxquito

License

MIT

About

WebRTC SFU built in Rust

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors