Web SDK Adapters - Agora & Zego API Compatible
Monibuca Web SDK provides API adapter layers for Agora and Zego. These adapters expose the exact same API interfaces as the original vendor SDKs, but use Monibuca’s own WHIP/WHEP/WebSocket protocol stack under the hood — enabling zero cloud service costs with self-hosted deployment. Developers can migrate existing projects to Monibuca by changing just one import line.
Why Replace Agora/Zego with Monibuca?
Section titled “Why Replace Agora/Zego with Monibuca?”| Comparison | Agora / Zego | Monibuca Adapter |
|---|---|---|
| Cost Model | Per-minute billing, grows with scale | One-time deployment, zero recurring costs |
| Data Sovereignty | Data routes through third-party cloud | Fully self-owned, never leaves your server |
| Migration Cost | — | Change one import line, zero code changes |
| Private Deployment | Enterprise license required | Out-of-the-box |
| Customization | Limited by vendor API | Fully controllable, extensible |
| Protocol Standard | Proprietary | WHIP/WHEP open standards |
Architecture
Section titled “Architecture”User Code (Agora API) User Code (Zego API) ↓ ↓@monibuca/adapter-agora @monibuca/adapter-zego ↓ ↓ └────────── @monibuca/sdk ───────────┘ ↓ WHIPClient / WHEPClient / RoomService ↓ Monibuca ServerInstallation
Section titled “Installation”# Agora compatibility layerpnpm add @monibuca/adapter-agora
# Zego compatibility layerpnpm add @monibuca/adapter-zegoBoth adapters depend on @monibuca/sdk, which will be installed automatically.
Agora Adapter
Section titled “Agora Adapter”Migration
Section titled “Migration”// Before (using Agora)import AgoraRTC from "agora-rtc-sdk-ng";
// After (using Monibuca)import { AgoraRTC } from "@monibuca/adapter-agora";Full Example
Section titled “Full Example”import { AgoraRTC } from "@monibuca/adapter-agora";
// Create clientconst client = AgoraRTC.createClient({ mode: "rtc", codec: "h264" });
// Listen for remote user publishingclient.on("user-published", async (user, mediaType) => { const track = await client.subscribe(user, mediaType); if (mediaType === "video") { track.play("remote-video-container"); } if (mediaType === "audio") { track.play(); }});
client.on("user-left", (user) => { console.log("User left:", user.uid);});
// Join channel (appid = Monibuca server WebSocket URL)const uid = await client.join("ws://your-server:8080", "channel-1", null, "user-1");
// Create local audio/video tracksconst [audioTrack, videoTrack] = await AgoraRTC.createMicrophoneAndCameraTracks();
// Preview local videovideoTrack.play("local-video-container");
// Publish to channelawait client.publish([audioTrack, videoTrack]);Supported APIs
Section titled “Supported APIs”AgoraRTC Static Methods
Section titled “AgoraRTC Static Methods”| Method | Description |
|---|---|
createClient(config) | Create RTC client |
createMicrophoneAudioTrack(config?) | Create microphone audio track |
createCameraVideoTrack(config?) | Create camera video track |
createScreenVideoTrack(config?) | Create screen share track |
createMicrophoneAndCameraTracks() | Create audio + video tracks together |
getCameras() | Get camera device list |
getMicrophones() | Get microphone device list |
getPlaybackDevices() | Get playback device list |
checkSystemRequirements() | Check system requirements |
IAgoraRTCClient Methods
Section titled “IAgoraRTCClient Methods”| Method | Description |
|---|---|
join(appid, channel, token, uid?) | Join channel |
leave() | Leave channel |
publish(tracks) | Publish local tracks |
unpublish(tracks?) | Unpublish tracks |
subscribe(user, mediaType) | Subscribe to remote user |
unsubscribe(user, mediaType?) | Unsubscribe |
Client Events
Section titled “Client Events”| Event | When Triggered |
|---|---|
user-joined | Remote user joined channel |
user-left | Remote user left channel |
user-published | Remote user published audio/video |
user-unpublished | Remote user unpublished |
connection-state-change | Connection state changed |
exception | Error occurred |
Track Methods
Section titled “Track Methods”| Method | Description |
|---|---|
play(element?) | Play/render track |
stop() | Stop playback |
close() | Close track and release resources |
setEnabled(enabled) | Enable/disable track |
setVolume(volume) | Set volume (audio tracks) |
setDevice(deviceId) | Switch device |
getMediaStreamTrack() | Get underlying MediaStreamTrack |
Parameter Mapping
Section titled “Parameter Mapping”| Agora Parameter | Monibuca Mapping |
|---|---|
appid | Monibuca WebSocket URL (e.g., ws://localhost:8180) |
channel | Room ID (roomId) |
uid | User ID (userId) |
token | Not used, pass null |
Zego Adapter
Section titled “Zego Adapter”Migration
Section titled “Migration”// Before (using Zego)import { ZegoExpressEngine } from "zego-express-engine-webrtc";
// After (using Monibuca)import { ZegoExpressEngine } from "@monibuca/adapter-zego";Full Example
Section titled “Full Example”import { ZegoExpressEngine } from "@monibuca/adapter-zego";
// Create engine (appID is just an identifier, server = Monibuca server URL)const zg = new ZegoExpressEngine(0, "ws://your-server:8080");
// Listen for room stream updateszg.on("roomStreamUpdate", async (roomID, updateType, streamList) => { if (updateType === "ADD") { for (const stream of streamList) { const remoteStream = await zg.startPlayingStream(stream.streamID); document.getElementById("remote-video").srcObject = remoteStream; } } if (updateType === "DELETE") { for (const stream of streamList) { zg.stopPlayingStream(stream.streamID); } }});
// Listen for user updateszg.on("roomUserUpdate", (roomID, updateType, userList) => { console.log(`Users ${updateType}:`, userList);});
// Login to roomconst result = await zg.loginRoom("room-1", "", { userID: "user-1", userName: "John",});
if (result.errorCode === 0) { // Create local stream const localStream = await zg.createZegoStream({ camera: { audio: true, video: true }, });
// Preview document.getElementById("local-video").srcObject = localStream.stream;
// Publish stream zg.startPublishingStream("stream-1", localStream);}Supported APIs
Section titled “Supported APIs”ZegoExpressEngine Methods
Section titled “ZegoExpressEngine Methods”| Method | Description |
|---|---|
loginRoom(roomID, token, user, config?) | Login to room |
logoutRoom(roomID?) | Logout from room |
createZegoStream(source?) | Create local stream (ZegoLocalStream) |
createStream(source?) | Create MediaStream |
startPublishingStream(streamID, stream) | Start publishing |
stopPublishingStream(streamID) | Stop publishing |
startPlayingStream(streamID, option?) | Start playing |
stopPlayingStream(streamID) | Stop playing |
enumDevices() | Enumerate devices |
useAudioDevice(stream, deviceID) | Switch audio device |
useVideoDevice(stream, deviceID) | Switch video device |
sendBroadcastMessage(roomID, message) | Send broadcast message |
destroyEngine() | Destroy engine |
ZegoLocalStream Methods
Section titled “ZegoLocalStream Methods”| Method | Description |
|---|---|
enableCamera(enable) | Enable/disable camera |
enableMicrophone(enable) | Enable/disable microphone |
replaceVideoTrack(track) | Replace video track |
replaceAudioTrack(track) | Replace audio track |
destroy() | Destroy stream |
Engine Events
Section titled “Engine Events”| Event | When Triggered |
|---|---|
roomStateChanged | Room connection state changed |
roomUserUpdate | User joined/left room |
roomStreamUpdate | Remote stream added/removed |
publisherStateUpdate | Publisher state changed |
playerStateUpdate | Player state changed |
publishQualityUpdate | Publish quality stats (every 2s) |
playQualityUpdate | Play quality stats (every 2s) |
IMRecvBroadcastMessage | Received broadcast message |
roomOnlineUserCountUpdate | Online user count changed |
Parameter Mapping
Section titled “Parameter Mapping”| Zego Parameter | Monibuca Mapping |
|---|---|
appID | App identifier (for identification only, doesn’t affect connection) |
server | Monibuca WebSocket URL (e.g., ws://localhost:8180) |
roomID | Room ID |
userID | User ID |
streamID | Stream path (streamPath) |
token | Not used, pass empty string |
Event Mapping
Section titled “Event Mapping”Both adapters use Monibuca SDK’s RoomService for signaling, WHIPClient for publishing, and WHEPClient for subscribing. The event mapping is:
| Internal Event | Agora Event | Zego Event |
|---|---|---|
REMOTE_USER_ENTER | user-joined | roomUserUpdate(ADD) |
REMOTE_USER_EXIT | user-left | roomUserUpdate(DELETE) |
user-publish | user-published | roomStreamUpdate(ADD) |
user-unpublish | user-unpublished | roomStreamUpdate(DELETE) |
CONNECTION_STATE_CHANGED | connection-state-change | roomStateChanged |
| WHIPClient state | — | publisherStateUpdate |
| WHEPClient state | — | playerStateUpdate |
chat | — | IMRecvBroadcastMessage |
- Server URL: The Agora adapter’s
appidand Zego adapter’sserverparameters should be set to the Monibuca server’s WebSocket URL - Token Auth: Token authentication is not enforced in the current version; pass
nullor empty string - Unsupported Features: Cloud recording, CDN relay, and other cloud service features are outside the adapter scope
- Quality Stats: Stream quality data comes from WebRTC native
getStats()API, reported every 2 seconds - Device Management: Device enumeration and switching uses the browser’s native
mediaDevicesAPI