# Monibuca v6 > High-performance streaming media server engine (Rust rewrite) Monibuca v6 is a modular, plugin-based streaming media server engine written in Rust, powered by Tokio async runtime. It supports 8+ streaming protocols, a lock-free ring buffer architecture, and a flexible plugin system with 25+ plugins. Rewritten from Go (v5) to break through GC/goroutine overhead ceilings for 10,000+ concurrent streams and 100,000+ subscribers. --- ## Table of Contents - [Architecture Overview](#architecture-overview) - [Core Data Engine](#core-data-engine) - [Dispatcher Architecture](#dispatcher-architecture) - [Plugin System](#plugin-system) - [Protocol Support](#protocol-support) - [Room System](#room-system) - [Configuration System](#configuration-system) - [HTTP API Reference](#http-api-reference) - [Building & Running](#building--running) - [Performance](#performance) - [Tech Stack](#tech-stack) --- ## Architecture Overview Monibuca v6 uses a strict six-layer architecture with one-way downward dependency: ``` ┌─────────────────────────────────────────────────────────────┐ │ External Clients │ │ Browser · Mobile · FFmpeg/OBS · IoT · GB28181 · Admin │ ├─────────────────────────────────────────────────────────────┤ │ Infrastructure Layer │ │ HTTP Server · gRPC · Database · Config · Event System │ │ FFmpeg · Network/QUIC · User System · Admin UI │ ├─────────────────────────────────────────────────────────────┤ │ Engine Built-in Services │ │ StreamManager · PluginManager · RoomService │ │ TaskSystem · CoreAdapters │ ├─────────────────────────────────────────────────────────────┤ │ Feature Plugin Crates (26+) │ │ RTMP · RTSP · HLS · FLV · WebRTC · SRT · GB28181 │ │ WebTransport · MP4 · Snap · Transcode · Cluster · ... │ ├─────────────────────────────────────────────────────────────┤ │ monibuca-sdk (Plugin SDK) │ │ Plugin trait · EngineContext · HTTP SDK · EventBus │ │ ServiceRegistry · DatabaseApi · ProxyManager │ ├─────────────────────────────────────────────────────────────┤ │ codec (Foundation) │ │ AVFrame · NALU · RTP · PS · Audio/Video Codecs │ │ Trait Interfaces · Zero internal deps │ └─────────────────────────────────────────────────────────────┘ ``` ### Design principles: - **Compile isolation**: Changing one plugin doesn't trigger full recompilation - **Independent testing**: Each crate can compile and test independently - **Flexible composition**: Feature flags enable/disable plugins at build time ### Directory Structure ``` monibuca (main crate) ├── src/ │ ├── core/ # Core data structures │ │ ├── buffer.rs # RingBuffer - lock-free ring buffer │ │ ├── dispatcher.rs # Dispatcher/DispatcherPool frame distribution │ │ ├── frame.rs # AVFrame audio/video frames │ │ ├── publisher.rs # Publisher │ │ ├── subscriber.rs # Subscriber │ │ ├── track.rs # VideoTrack/AudioTrack │ │ ├── task.rs # Hierarchical task management │ │ ├── proxy.rs # Pull/push proxy │ │ ├── recorder.rs # Stream recording │ │ ├── transformer.rs # Stream transformation │ │ └── pool.rs # Object pool │ ├── auth/ # Authentication (JWT) │ ├── config/ # Configuration management │ ├── db/ # Database support (SQLite/MySQL/PostgreSQL) │ ├── event/ # Event system │ ├── ffmpeg/ # FFmpeg integration │ ├── grpc/ # gRPC support │ ├── http/ # HTTP server & router │ ├── license/ # License management │ ├── manager/ │ │ ├── stream.rs # StreamManager - stream lifecycle │ │ └── plugin.rs # PluginManager - plugin management │ ├── network/ # Networking │ ├── plugin/ # Plugin registration (pub use plugin_xxx as xxx) │ ├── room/ # Built-in Room service (not a plugin) │ ├── user_system/ # User management system │ └── util/ # Utilities │ ├── plugins/ # 25+ independent plugin crates │ ├── rtmp/ # RTMP protocol │ ├── rtsp/ # RTSP protocol │ ├── flv/ # HTTP-FLV protocol │ ├── hls/ # HLS protocol │ ├── webrtc/ # WebRTC WHIP/WHEP │ ├── srt/ # SRT low-latency transport │ ├── gb28181/ # GB28181 national standard │ ├── webtransport/ # WebTransport (QUIC-based) │ ├── cluster/ # Cluster support │ ├── mp4/ # MP4 recording/playback │ ├── snap/ # Video snapshot service │ ├── onvif/ # ONVIF device discovery │ ├── logrotate/ # Log rotation │ ├── crontab/ # Scheduled tasks │ ├── crypto/ # Stream encryption │ ├── transcode/ # Audio transcoding (Opus <-> AAC) │ ├── live/ # Live streaming rooms │ ├── meeting/ # Meeting rooms │ ├── customer-service/ # Customer service │ ├── report/ # Metrics reporting │ ├── debug/ # Debug tools │ ├── sei/ # SEI data insertion │ ├── test/ # Test plugin │ ├── mix/ # Stream mixing │ ├── homekit/ # HomeKit integration │ ├── v4l2/ # V4L2 video capture (Linux) │ └── alsa/ # ALSA audio capture (Linux) │ ├── crates/ │ ├── codec # Foundation: codec enums, traits, error types │ ├── monibuca-sdk # Plugin SDK (sole contract layer) │ ├── monibuca-sdk-macros # SDK proc macros │ ├── m7s-config-framework # Configuration framework │ └── m7s-config-macros # Config derive macros │ ├── admin/ # React Admin UI ├── web-sdk/ # TypeScript Web SDK └── docs/ # Technical documentation ``` ### IoC / EngineContext (Service Locator Pattern) `EngineContext` (in `crates/monibuca-sdk/src/context.rs`) serves as a capability container. The engine constructs it in `PluginManager::init_all()` and injects into each plugin. Required capabilities: - `stream_manager: Arc` (from codec) Optional capabilities: - `database`, `transform`, `playback` Adapters live in `src/core/core_adapter.rs`. --- ## Core Data Engine ### Lock-Free RingBuffer (SPMC) The core challenge: one data source, thousands of readers. Monibuca solves this with a lock-free Single-Producer Multiple-Consumer ring buffer. ```rust pub struct RingBuffer { slots: Box<[RingSlot]>, // Ring slot array write_pos: AtomicUsize, // Atomic write position idr_list: ArcSwap>, // IDR keyframe index (lock-free read) idr_write_lock: Mutex<()>, // IDR write serialization (COW mode) } pub struct RingSlot { frame: ArcSwapOption, // ArcSwap lock-free atomic swap version: AtomicU64, // Version number for overwrite detection } ``` Key design decisions: | Feature | Implementation | Effect | |---------|---------------|--------| | Write never blocks | `AtomicUsize::fetch_add` advances write position | Publisher write latency ~100ns | | Zero-copy read | `ArcSwapOption::load_full` returns `Arc` | Read latency ~50ns, only increments refcount | | Version verification | Per-slot `AtomicU64` version | Detects frame overwrite, ensures data consistency | | IDR tracking | `ArcSwap>` with COW updates | Fast keyframe seeking for new subscribers | | ArcSwap exchange | Uses `arc_swap` for lock-free frame replacement | No mutex contention on write path | --- ## Dispatcher Architecture ### Single-Stream Dispatcher Each Dispatcher reads frames from RingBuffer once and broadcasts to all subscribers via bounded channels: ``` Publisher → RingBuffer → Dispatcher (single read) → [Queue 1, Queue 2, ..., Queue N] → Subscribers ``` Comparison with traditional approach: | Metric | Traditional (N subscribers) | Dispatcher mode | |--------|---------------------------|-----------------| | RingBuffer reads | N times | 1 time | | Lock contention | High | None | | CPU cache hit rate | Low | High | | Backpressure | None | Bounded Channel (cap=60) | ### DispatcherPool (Multi-Stream) For 100+ concurrent streams, a fixed N worker pool distributes streams via consistent hashing: | Config | Mode | Task count | Use case | |--------|------|-----------|----------| | `dispatcher_workers = 0` | Per-Stream | M (one per stream) | Few streams (<100) | | `dispatcher_workers = N` | Pool | N (fixed) | Many streams (>100) | ### Data Flow Sequence ``` Publisher → RingBuffer.write_frame(Arc) Publisher → Dispatcher.frame_notify.send() Dispatcher → RingBuffer.read_next() → FrameHandle{Arc, version} Dispatcher → [try_send(Arc::clone) to each subscriber queue] Queue full → frame dropped (backpressure) Subscriber → queue.recv() → process/forward ``` --- ## Plugin System ### Plugin Types | Type | Description | |------|-------------| | Static | Compiled-in, linked at build time | | Dynamic | Shared library, loaded at runtime (.so/.dylib/.dll) | | WASM | WebAssembly sandbox (reserved for future) | ### Plugin Registry All plugins in `plugins/` are independent crates, imported via `pub use plugin_xxx as xxx` in the main crate. ### Built-in Plugins | Plugin | 配置节 | Category | Description | |--------|-------------|----------|-------------| | rtmp | `rtmp` | Protocol | RTMP publish/subscribe | | rtsp | `rtsp` | Protocol | RTSP publish/subscribe (TCP/UDP) | | flv | `flv` | Protocol | HTTP-FLV playback | | hls | `hls` | Protocol | HLS playback (TS/fMP4) | | webrtc | `webrtc` | Protocol | WebRTC WHIP/WHEP (H.264/H.265 + Opus) | | srt | `srt` | Protocol | SRT low-latency transport | | gb28181 | `gb28181` | Protocol | GB28181 Chinese national standard | | webtransport | `webtransport` | Protocol | WebTransport (QUIC-based) | | cluster | `cluster` | Protocol | QUIC-based cluster (origin-edge) | | mp4 | `mp4` | Utility | MP4 recording/playback | | snap | `snap` | Utility | Video snapshot | | logrotate | `logrotate` | Utility | Log rotation | | crontab | `crontab` | Utility | Scheduled tasks | | crypto | `crypto` | Utility | Stream encryption | | transcode | `ffmpeg_transcode` | Utility | Audio transcoding (Opus <-> AAC) | | report | `report` | Utility | Metrics reporting | | debug | `debug` | Utility | Debug tools | | sei | `sei` | Utility | SEI data insertion | | test | `test` | Utility | Test plugin | | mix | `mix` | Utility | Stream mixing | | live | `live` | Room | Live streaming rooms | | meeting | `meeting` | Room | Meeting rooms | | customer-service | `customer-service` | Room | Customer service | | homekit | `homekit` | Device | HomeKit integration | | v4l2 | `v4l2` | Device | V4L2 video capture | | alsa | `alsa` | Device | ALSA audio capture | ### Audio Transcoding Cross-protocol forwarding requires audio format conversion: | Protocol | Audio Format | |----------|-------------| | RTMP/FLV/HLS | AAC | | WebRTC | Opus | | Scenario | With transcode | Without transcode | |----------|---------------|-------------------| | WebRTC → RTMP | Opus → AAC auto | Skip audio, video only | | RTMP → WebRTC | AAC → Opus auto | Skip audio, video only | | Same format | Direct forward | Direct forward | System dependencies (when transcode enabled): ```bash # Ubuntu/Debian sudo apt install libopus-dev libfdk-aac-dev # macOS brew install opus fdk-aac ``` ### Plugin Build Supported platforms: | Platform | Extension | Target Triple | |----------|-----------|---------------| | macOS (Intel) | `.dylib` | `x86_64-apple-darwin` | | macOS (Apple Silicon) | `.dylib` | `aarch64-apple-darwin` | | Linux (x86_64) | `.so` | `x86_64-unknown-linux-gnu` | | Linux (ARM64) | `.so` | `aarch64-unknown-linux-gnu` | | Windows | `.dll` | `x86_64-pc-windows-gnu` | ```bash # Build all core plugins python scripts/build_plugins.py # Build specific plugins python scripts/build_plugins.py hls rtmp flv # Include advanced plugins python scripts/build_plugins.py --include-advanced ``` --- ## Protocol Support | Protocol | Publish | Subscribe | Default Port | Notes | |----------|---------|-----------|-------------|-------| | RTMP | Yes | Yes | 1935 | Full support | | RTSP | Yes | Yes | 554 | TCP/UDP transport | | HTTP-FLV | No | Yes | 8080 | Playback only | | HLS | No | Yes | 8080 | TS/fMP4 segments | | WebRTC | WHIP | WHEP | 8081 | H.264/H.265 + Opus | | SRT | Yes | Yes | - | Low-latency transport | | GB28181 | Yes | Yes | 5060 (SIP) | Chinese national standard for surveillance | | WebTransport | Yes | Yes | - | QUIC-based, requires TLS | ### Cluster Architecture QUIC-based low-latency cluster communication with origin cascading and edge distribution: ``` Origin Cluster (QUIC bidirectional) ├── Origin 1 (primary) ←→ Origin 2 (standby) │ ├── Edge 1 → Clients ├── Edge 2 → Clients └── Edge 3 → Clients ``` --- ## Room System Room uses an **engine built-in service + plugin callback** architecture: - **RoomService** (`src/room/`): Engine built-in, manages room core lifecycle - **Live/Meeting**: Independent plugins, register async callbacks via `RoomApi` trait - **No bridge layer**: Plugins directly operate rooms through `RoomApi` - **Async callbacks**: `BoxFuture<'static>` with owned data - **Shared room map**: `Arc>>` shared between `EngineRoomApi` and `RoomService` WebSocket connection: `ws://host/room/{room_id}?token=...` ### Live Room Features - Room CRUD, start/pause/resume/end live - Gift system with balance, rankings, history - Link-mic (co-streaming): request/accept/reject/end with WebRTC signaling - WebSocket signaling: link_mic_request, link_mic_accept, ice_candidate, etc. ### Meeting Room Features - Room CRUD with lock/unlock - User management: mute/unmute/kick - Recording: start/stop - Events and timeline tracking --- ## Configuration System ### Priority (high to low) 1. **Runtime modification** - via HTTP API 2. **Database config** - from database 3. **Environment variables** - `M7S_` prefixed 4. **Config file** - YAML 5. **Default values** - plugin-defined ### Config File Example ```yaml server: log_level: info dispatcher_workers: 8 # 0=per-stream, N=pool mode rtmp: enabled: true port: 1935 rtsp: enabled: true port: 554 webrtc: enabled: true port: 8081 ice_servers: - stun:stun.l.google.com:19302 cluster: enabled: true node_id: "node-1" peers: - "192.168.1.10:9000" database: enabled: true url: "sqlite://./monibuca.db" # url: "mysql://user:pass@localhost/monibuca" # url: "postgres://user:pass@localhost/monibuca" ``` ### Environment Variables Format: `M7S___` (double underscore separator) ```bash export M7S_global__log_level=debug export M7S_rtmp__port=1936 export M7S_webrtc__enabled=true ``` ### Config Framework (m7s-config-framework) Provides declarative config schema definition, validation, and dynamic form generation. Each plugin derives `ConfigSchema` for automatic schema generation. HTTP endpoints under `/config`: | Method | Path | Description | |--------|------|-------------| | GET | `/config/` | List all plugin configs | | GET | `/config/{plugin}` | Get plugin config | | PUT | `/config/{plugin}` | Update plugin config | | GET | `/config/schema/{plugin}` | Get plugin config schema | | POST | `/config/validate` | Validate config | | POST | `/config/reset/{plugin}` | Reset to defaults | | GET | `/config/page` | Global config page (HTML) | | GET | `/config/page/{plugin}` | Plugin config page (HTML) | --- ## HTTP API Reference ### Route Prefix Overview | Prefix | Purpose | Handler | |--------|---------|---------| | `/api` | V5 compat management API (legacy envelope) | V5CompatSurface | | `/v6/api` | Core REST API | V6Surface | | `/zego/api` | ZEGO Action API (feature: `api-compat-zego`) | ZegoCompatSurface | | `/config` | Config framework | ConfigHttpHandler | | `/api/config` | Runtime config (DB) | ConfigApiHandler | | `/api/auth` | Admin JWT login/refresh | AuthApiHandler | | `/annexb` | Annex-B video | AnnexBHandler | | `/flv` | FLV streaming | FlvHandler | | `/hls` | HLS streaming | HlsHandler | | `/webrtc` | WebRTC WHIP/WHEP | WebRtcHandler | | `/gb28181/api` | GB28181 device mgmt | Gb28181ApiHandler | | `/transcode/api` | Transcode mgmt | TranscodeHandler | | `/users/api` | User system | UserSystemHandler | | `/test` | Test endpoints | TestHandler | | `/mp4` | MP4 recording | Mp4Handler | | `/snap` | Video snapshots | SnapHandler | | `/admin` | Admin static files | ZipFileHandler | | `/room` | WebSocket rooms | RoomWsHandler | | `/live` | Live room REST | LiveApiHandler | | `/meeting/api` | Meeting plugin REST (`{plugin}/api`) | MeetingApiHandler | ### V5 Compat API (`/api/`) Legacy v5-compatible management surface. Success responses use `{ "code": 0, "message": "success", "data": … }`; errors use the same envelope with non-zero `code`. URLs are unchanged from Monibuca v5 — Admin UI and migrated integrations call `/api/*` directly. Shares `AppFacade` with `/v6/api`; admin JWT required on sensitive routes when `global.auth.secret` is set (same as V6 surface). #### System | Method | Path | Description | |--------|------|-------------| | GET | `/api/` | API root info | | GET | `/api/summary` | System resource summary | | GET | `/api/sysinfo` | System info | | GET | `/api/plugins` | Plugin list | | GET | `/api/plugins/disabled` | Disabled plugins | | POST | `/api/shutdown` | Shutdown server | | POST | `/api/restart` | Restart server | #### Streams | Method | Path | Description | |--------|------|-------------| | GET | `/api/streams` | Simple stream list | | GET | `/api/stream/list` | Detailed stream list | | GET | `/api/stream/info?path=` | Stream info (query param) | | GET | `/api/stream/info/{streamPath}` | Stream info (path param) | | GET | `/api/stream/waitlist` | Stream wait list | | GET | `/api/stream/alias/list` | Alias list | | POST | `/api/stream/alias` | Set stream alias | | POST | `/api/stream/stop/{streamPath}` | Stop stream | | POST | `/api/stream/speed/{streamPath}` | Set playback speed | | POST | `/api/stream/seek/{streamPath}` | Seek stream | | GET | `/api/subscribers/{streamPath}` | Subscriber list | | POST | `/api/subscriber/stop/{id}` | Stop subscriber | | POST | `/api/subscribe/change/{id}/{streamPath}` | Change subscriber stream | | GET | `/api/videotrack/snap/{streamPath}` | Video track snapshot | | GET | `/api/audiotrack/snap/{streamPath}` | Audio track snapshot | #### Tasks | Method | Path | Description | |--------|------|-------------| | GET | `/api/task/tree` | Task tree | | POST | `/api/task/stop/{id}` | Stop task | | POST | `/api/task/restart/{id}` | Restart task | #### Config (legacy paths under `/api/config/*`) | Method | Path | Description | |--------|------|-------------| | GET | `/api/config/file` | Config file content | | POST | `/api/config/file` | Update config file | | GET | `/api/config/get/{name}` | Get plugin config | | GET | `/api/config/formily/{name}` | Get Formily schema | | POST | `/api/config/modify` | Modify plugin config | #### Pull Proxy | Method | Path | Description | |--------|------|-------------| | GET | `/api/proxy/pull/list` | Pull proxy list | | GET | `/api/proxy/pull/runtime` | Pull proxy runtime status | | POST | `/api/pull-proxy/add` | Add pull proxy | | POST | `/api/pull-proxy/update/{id}` | Update pull proxy | | DELETE | `/api/pull-proxy/delete/{id}` | Delete pull proxy | | POST | `/api/pull-proxy/start/{id}` | Start pull proxy | | POST | `/api/pull-proxy/stop/{id}` | Stop pull proxy | | POST | `/api/pull-proxy/enable/{id}` | Enable pull proxy | | POST | `/api/pull-proxy/disable/{id}` | Disable pull proxy | #### Push Proxy | Method | Path | Description | |--------|------|-------------| | GET | `/api/proxy/push/list` | Push proxy list | | GET | `/api/proxy/push/runtime` | Push proxy runtime status | | POST | `/api/push-proxy/add` | Add push proxy | | POST | `/api/push-proxy/update/{id}` | Update push proxy | | DELETE | `/api/push-proxy/delete/{id}` | Delete push proxy | | POST | `/api/push-proxy/start/{id}` | Start push proxy | | POST | `/api/push-proxy/stop/{id}` | Stop push proxy | | POST | `/api/push-proxy/enable/{id}` | Enable push proxy | | POST | `/api/push-proxy/disable/{id}` | Disable push proxy | #### Recordings & Alarms | Method | Path | Description | |--------|------|-------------| | GET | `/api/record/list` | Recording list | | GET | `/api/record/event-list` | Event recording list | | GET | `/api/record/catalog` | Recording catalog | | DELETE | `/api/record/delete` | Delete recording | | GET | `/api/alarm/list` | Alarm list | | POST | `/api/arming/set` | Set arming | ### ZEGO Compat API (`/zego/api/`) Action-based API (feature `api-compat-zego`). All calls: `POST /zego/api/?Action=XXX&AppId=…&Signature=…` with MD5 signature. Shares `AppFacade` with other surfaces. | Action | Description | Status | |--------|-------------|--------| | `DescribeStreamList` | List streams | ✅ | | `DescribeStreamInfo` | Stream detail | ✅ | | `ForbidRTCStream` / `ForbidCDNLiveStream` | Stop stream | ✅ | | `DescribeUserNum` | Online user count | ✅ | | `ResumeRTCStream` | Resume stream | ❌ Not supported | | `StartCDNRecord` / `StopCDNRecord` | Recording | ❌ TODO | | `StartMix` / `StopMix` | Mix tasks | ❌ TODO | ### Core API (`/v6/api`) REST style: success returns resource JSON or `{ data, meta }` pagination; errors use RFC 7807 `application/problem+json`. #### Streams | Method | Path | Description | |--------|------|-------------| | GET | `/v6/api/streams?page=&per_page=` | Paginated stream list | | GET | `/v6/api/streams/{streamPath}` | Stream detail | | DELETE | `/v6/api/streams/{streamPath}` | Stop/dispose stream (204; may enter waiting-reconnect if `continue_push_timeout` set) | | GET | `/v6/api/streams/{streamPath}/subscribers?page=&per_page=` | Subscriber list (no per-subscriber kick API) | | GET | `/v6/api/streams/{streamPath}/tracks/video` | Video track snapshot | | GET | `/v6/api/streams/{streamPath}/tracks/audio` | Audio track snapshot | | GET | `/v6/api/streams/secret?stream_path=&type=&expire=&plugin=` | Generate publish/subscribe auth secret | **Not on `/v6/api/` (use `/api/` V5 compat instead):** stop/change subscriber by ID (`/api/subscriber/stop/{id}`). Use `DELETE /v6/api/streams/{streamPath}` to stop the whole stream. For on-demand pull use pull proxies below. #### Aliases | Method | Path | Description | |--------|------|-------------| | GET | `/v6/api/aliases` | Alias list | | PUT | `/v6/api/aliases` | Create/update alias (body: `alias`, `stream_path`, `auto_remove`) | | DELETE | `/v6/api/aliases/{alias}` | Remove alias | | POST | `/v6/api/aliases/{alias}/enable` | Enable alias | | POST | `/v6/api/aliases/{alias}/disable` | Disable alias | #### Tasks | Method | Path | Description | |--------|------|-------------| | GET | `/v6/api/tasks/tree` | Task tree | | POST | `/v6/api/tasks/{id}/stop` | Stop task | | POST | `/v6/api/tasks/{id}/restart` | Restart task | #### System | Method | Path | Description | |--------|------|-------------| | GET | `/v6/api/system/info` | System info | | GET | `/v6/api/system/summary` | Resource summary | | GET | `/v6/api/system/health` | Health check | | GET | `/v6/api/plugins` | Plugin list | #### Pull Proxy | Method | Path | Description | |--------|------|-------------| | GET | `/v6/api/proxies/pull` | Pull proxy list | | POST | `/v6/api/proxies/pull` | Add pull proxy | | PUT | `/v6/api/proxies/pull/{id}` | Update pull proxy | | DELETE | `/v6/api/proxies/pull/{id}` | Delete pull proxy | | POST | `/v6/api/proxies/pull/{id}/start` | Start pull proxy | | POST | `/v6/api/proxies/pull/{id}/stop` | Stop pull proxy | | POST | `/v6/api/proxies/pull/{id}/enable` | Enable pull proxy | | POST | `/v6/api/proxies/pull/{id}/disable` | Disable pull proxy | #### Push Proxy | Method | Path | Description | |--------|------|-------------| | GET | `/v6/api/proxies/push` | Push proxy list | | POST | `/v6/api/proxies/push` | Add push proxy | | PUT | `/v6/api/proxies/push/{id}` | Update push proxy | | DELETE | `/v6/api/proxies/push/{id}` | Delete push proxy | | POST | `/v6/api/proxies/push/{id}/start` | Start push proxy | | POST | `/v6/api/proxies/push/{id}/stop` | Stop push proxy | | POST | `/v6/api/proxies/push/{id}/enable` | Enable push proxy | | POST | `/v6/api/proxies/push/{id}/disable` | Disable push proxy | #### Admin Authentication (`/api/auth` — issue JWT here; other `/api/*` routes require it when secret configured) | Method | Path | Description | |--------|------|-------------| | POST | `/api/auth/login` | Admin login → `{ access_token, refresh_token, expires_in, token_type, username, role }` (legacy `{code,data}` envelope) | | POST | `/api/auth/refresh` | Refresh tokens with `{ refresh_token }` → same login response shape | | GET | `/api/auth/userinfo` | Current admin user (`Authorization: Bearer …`) | Configure via `global.auth.secret` / `M7S_AUTH_SECRET` and `global.auth.users`. Local dev bypass: `M7S_ADMIN_DEV_MODE=1`. Admin SPA stores tokens and attaches Bearer on `/api/*` and `/v6/api/*`. #### Runtime Config (`/api/config`, admin JWT) | Method | Path | Description | |--------|------|-------------| | GET | `/api/config/` | List plugin configs | | GET | `/api/config/{plugin}` | Get plugin config | | PUT | `/api/config/{plugin}` | Update plugin config | | POST | `/api/config/{plugin}/reload` | Reload from database | | POST | `/api/config/reload-all` | Reload all | ### FLV Streaming (`/flv`) | Method | Path | Description | |--------|------|-------------| | GET | `/flv/{streamPath}` | FLV stream playback | | GET | `/flv/{streamPath}.flv` | FLV stream (with extension) | ### HLS Streaming (`/hls`) | Method | Path | Description | |--------|------|-------------| | GET | `/hls/{streamPath}/index.m3u8` | HLS playlist | | GET | `/hls/{streamPath}/{segment}.ts` | HLS TS segment | ### WebRTC (`/webrtc`) #### Test Pages | Method | Path | Description | |--------|------|-------------| | GET | `/webrtc/test/publish` | WHIP test publish page | | GET | `/webrtc/test/subscribe` | WHEP test subscribe page | | GET | `/webrtc/test/screenshare` | Screen share test page | #### WHIP Publish | Method | Path | Description | |--------|------|-------------| | POST | `/webrtc/push/{streamPath}` | WHIP publish (SDP Offer) | | PATCH | `/webrtc/push/{sessionId}` | ICE Candidate update | | DELETE | `/webrtc/push/{sessionId}` | Stop publish session | #### WHEP Subscribe | Method | Path | Description | |--------|------|-------------| | POST | `/webrtc/play/{streamPath}` | WHEP subscribe (SDP Offer) | | PATCH | `/webrtc/play/{sessionId}` | ICE Candidate update | | DELETE | `/webrtc/play/{sessionId}` | Stop subscribe session | ### GB28181 (`/gb28181/api`) #### Device Management | Method | Path | Description | |--------|------|-------------| | GET | `/gb28181/api/devices` | Device list | | GET | `/gb28181/api/device/{id}` | Device details | | PUT | `/gb28181/api/device/{id}` | Update device | | DELETE | `/gb28181/api/device/{id}` | Delete device | | POST | `/gb28181/api/device/sync` | Sync device channels | #### Stream Control | Method | Path | Description | |--------|------|-------------| | POST | `/gb28181/api/invite/{deviceId}` | Invite device to stream | | POST | `/gb28181/api/bye/{deviceId}` | Stop device streaming | #### PTZ Control | Method | Path | Description | |--------|------|-------------| | POST | `/gb28181/api/ptz/control` | PTZ camera control | PTZ request body: ```json { "device_id": "34020000001110000001", "channel_id": "34020000001320000001", "cmd": "left|right|up|down|zoomin|zoomout|stop", "param": 1, "speed": 50 } ``` #### Record & Playback | Method | Path | Description | |--------|------|-------------| | POST | `/gb28181/api/record/query` | Query device recordings | #### Channels | Method | Path | Description | |--------|------|-------------| | GET | `/gb28181/api/channels` | Channel list | | POST | `/gb28181/api/channel/add` | Add custom channel | | DELETE | `/gb28181/api/channel/delete/{id}` | Delete channel | #### Cascade Platforms | Method | Path | Description | |--------|------|-------------| | GET | `/gb28181/api/platforms` | Platform list | | POST | `/gb28181/api/platform/add` | Add cascade platform | | POST | `/gb28181/api/platform/update` | Update platform | | DELETE | `/gb28181/api/platform/delete/{id}` | Delete platform | ### Transcode (`/transcode/api`) | Method | Path | Description | |--------|------|-------------| | GET | `/transcode/api/list` | Transcode task list | | GET | `/transcode/api/exist?target={target}` | Check task exists | | POST | `/transcode/api/launch` | Start transcode task | | POST | `/transcode/api/close` | Stop transcode task | ### User System (`/users/api`) | Method | Path | Description | |--------|------|-------------| | GET | `/users/api/users` | User list (paginated) | | GET | `/users/api/users/search?keyword=xxx` | Search users | | POST | `/users/api/users` | Create user | | GET | `/users/api/users/{userId}` | Get user | | PUT | `/users/api/users/{userId}` | Update user | | DELETE | `/users/api/users/{userId}` | Delete user | | GET | `/users/api/users/{userId}/rooms` | User room history | | POST | `/users/api/users/auth` | External token auth | ### MP4 Recording (`/mp4`) | Method | Path | Description | |--------|------|-------------| | GET | `/mp4/list` | Recording list | | POST | `/mp4/start/{streamPath}` | Start recording | | POST | `/mp4/stop/{streamPath}` | Stop recording | | GET | `/mp4/status/{streamPath}` | Recording status | | GET | `/mp4/api/list/{streamPath}` | Recording file list | | GET | `/mp4/api/catalog` | Recording catalog | | DELETE | `/mp4/api/delete/{streamPath}` | Delete recording | | GET | `/mp4/download/{streamPath}` | Download MP4 file | ### Snapshots (`/snap`) | Method | Path | Description | |--------|------|-------------| | GET/POST | `/snap/take/{streamPath}` | Take snapshot | | GET | `/snap/history` | All snapshot history | | GET | `/snap/history/{streamPath}` | Stream snapshot history | | DELETE | `/snap/history` | Clear history | ### Live Rooms (`/live`) Live room pause/resume are **business-layer** APIs (not engine stream pause/resume). | Method | Path | Description | |--------|------|-------------| | GET | `/live/rooms` | Live room list | | POST | `/live/rooms` | Create live room | | GET | `/live/rooms/{room_id}` | Get live room | | DELETE | `/live/rooms/{room_id}` | Delete live room | | POST | `/live/rooms/{room_id}/start` | Start live | | POST | `/live/rooms/{room_id}/pause` | Pause live (room) | | POST | `/live/rooms/{room_id}/resume` | Resume live (room) | | POST | `/live/rooms/{room_id}/end` | End live | | GET | `/live/rooms/{room_id}/linkmic` | Link-mic list | | POST | `/live/rooms/{room_id}/linkmic/{id}/accept` | Accept link-mic | | POST | `/live/rooms/{room_id}/linkmic/{id}/reject` | Reject link-mic | | POST | `/live/rooms/{room_id}/linkmic/{user_id}/end` | End link-mic | | GET | `/live/stats` | Live statistics | | POST | `/live/gifts/send` | Send gift | | GET | `/live/gifts/rankings` | Gift rankings | ### Meeting plugin REST (`/meeting/api`, same `{plugin}/api` pattern as e.g. `gb28181/api`) | Method | Path | Description | |--------|------|-------------| | GET | `/meeting/api/rooms` | Meeting room list | | POST | `/meeting/api/rooms` | Create meeting room (`room_id` in JSON body) | | GET | `/meeting/api/rooms/{room_id}` | Get meeting room summary; legacy alias `GET /meeting/api/room/{room_id}` | | DELETE | `/meeting/api/rooms/{room_id}` | Delete meeting room | | GET | `/meeting/api/rooms/{room_id}/users` | User list | | POST | `/meeting/api/rooms/{room_id}/lock` | Lock room | | POST | `/meeting/api/rooms/{room_id}/unlock` | Unlock room | | POST | `/meeting/api/control/mute` | Chat mute (`room_id`, `user_id`) | | POST | `/meeting/api/control/unmute` | Remove chat mute | | POST | `/meeting/api/control/kick` | Remove user from room | | GET | `/meeting/api/stats` | Meeting stats | | GET | `/meeting/api/features` | Registered feature metadata | | GET | `/meeting/api/reservations` | Reservation list | | POST | `/meeting/api/reservations` | Create reservation | | GET | `/meeting/api/templates` | Template list | | POST | `/meeting/api/templates` | Create template | | PUT | `/meeting/api/templates/{id}` | Update template | | DELETE | `/meeting/api/templates/{id}` | Delete template | | GET | `/meeting/api/recordings` | Recording catalog (may be empty until persistence wired) | | GET | `/meeting/api/recordings/{id}/play` | Play URL (404 if not found) | | GET | `/meeting/api/recordings/{id}/download` | Download | | DELETE | `/meeting/api/recordings/{id}` | Delete recording | ### Routing Mechanism All handlers implement `RouteHandler` trait. Router automatically strips the matched prefix before passing to handler: ``` Original: GET /gb28181/api/devices Router matches prefix "gb28181/api" Handler receives: GET /devices ``` --- ## Download & Run ```bash # Pre-built binary (Linux amd64) wget https://download.m7s.live/bin/monibuca_v6_linux_amd64.tar.gz tar -xzf monibuca_v6_linux_amd64.tar.gz chmod +x monibuca_linux_amd64 ./monibuca_linux_amd64 -c config.yaml # Docker docker pull langhuihui/monibuca:v6 docker run -d -p 8180:8180 -p 1935:1935 -p 8554:8554 langhuihui/monibuca:v6 ``` Pre-built binaries include all official plugins. Enable or disable them in `config.yaml` (see Configuration section). ### Pricing & services Monibuca is **permanently free** to download and use. There are no Free / Professional / Enterprise edition tiers for sale. Paid options are only **technical support** and **custom development**. Contact `support@monibuca.com`. See `/guides/license-and-editions/`. ### Plugin loading modes (runtime) | Mode | Description | |------|-------------| | Static (default in official binaries) | All official plugins built into the binary | | Dynamic | Load `.so` / `.dylib` / `.dll` from `plugins_dir` | | WASM (experimental) | Sandboxed WebAssembly plugins | --- ## Performance | Metric | Value | |--------|-------| | RingBuffer write latency | ~100ns/op | | RingBuffer read latency | ~50ns/op (Arc::clone only) | | Dispatcher fan-out latency | <1ms | | Audio transcode latency | <5ms | | Concurrent streams per node | 10,000+ | | Subscribers per stream | 10,000+ | --- ## Tech Stack | Component | Technology | |-----------|-----------| | Runtime | Tokio (async) | | Concurrency | parking_lot, dashmap, arc-swap | | Networking | tokio, rustrtc, quinn | | Serialization | serde, prost (protobuf) | | Database | sqlx (SQLite, MySQL, PostgreSQL) | | Logging | tracing | | HTTP | Custom router + maud templates | | WebSocket | tokio-tungstenite | | CLI | clap | | Template | maud | --- ## License Proprietary - All Rights Reserved