跳转到内容

Web SDK 适配层 - 声网/即构 API 兼容

Monibuca Web SDK 提供了针对声网 (Agora)即构 (Zego) 的 API 适配层。这些适配层暴露与原厂 SDK 完全一致的 API 接口,但底层使用 Monibuca 自有的 WHIP/WHEP/WebSocket 协议栈,实现零云服务费用的私有化部署。开发者可以 只修改一行 import 即可将现有项目从声网或即构迁移到 Monibuca。

为什么选择 Monibuca 替代声网/即构?

Section titled “为什么选择 Monibuca 替代声网/即构?”
对比项声网 Agora / 即构 ZegoMonibuca 适配层
费用模式按分钟计费,成本随规模增长一次部署,零持续费用
数据主权数据经过第三方云数据完全自有,不出服务器
迁移成本只改一行 import,零代码改动
私有化部署需企业版授权开箱即用
自定义能力受限于厂商 API完全可控,可按需扩展
协议标准私有协议WHIP/WHEP 开放标准
用户代码 (Agora API) 用户代码 (Zego API)
↓ ↓
@monibuca/adapter-agora @monibuca/adapter-zego
↓ ↓
└────────── @monibuca/sdk ──────────┘
WHIPClient / WHEPClient / RoomService
Monibuca Server
Terminal window
# Agora 兼容层
pnpm add @monibuca/adapter-agora
# Zego 兼容层
pnpm add @monibuca/adapter-zego

两个适配层均依赖 @monibuca/sdk,会自动安装。


// 迁移前(使用 Agora)
import AgoraRTC from "agora-rtc-sdk-ng";
// 迁移后(使用 Monibuca)
import { AgoraRTC } from "@monibuca/adapter-agora";
import { AgoraRTC } from "@monibuca/adapter-agora";
// 创建客户端
const client = AgoraRTC.createClient({ mode: "rtc", codec: "h264" });
// 监听远端用户发布
client.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.uid);
});
// 加入频道(appid 参数传入 Monibuca 服务器 WebSocket 地址)
const uid = await client.join("ws://your-server:8080", "channel-1", null, "user-1");
// 创建本地音视频轨道
const [audioTrack, videoTrack] = await AgoraRTC.createMicrophoneAndCameraTracks();
// 预览本地视频
videoTrack.play("local-video-container");
// 发布到频道
await client.publish([audioTrack, videoTrack]);
方法说明
createClient(config)创建 RTC 客户端
createMicrophoneAudioTrack(config?)创建麦克风音频轨道
createCameraVideoTrack(config?)创建摄像头视频轨道
createScreenVideoTrack(config?)创建屏幕共享轨道
createMicrophoneAndCameraTracks()同时创建音频+视频轨道
getCameras()获取摄像头列表
getMicrophones()获取麦克风列表
getPlaybackDevices()获取播放设备列表
checkSystemRequirements()检查系统要求
方法说明
join(appid, channel, token, uid?)加入频道
leave()离开频道
publish(tracks)发布本地轨道
unpublish(tracks?)取消发布
subscribe(user, mediaType)订阅远端用户
unsubscribe(user, mediaType?)取消订阅
事件触发时机
user-joined远端用户加入频道
user-left远端用户离开频道
user-published远端用户发布音频/视频
user-unpublished远端用户取消发布
connection-state-change连接状态变更
exception异常错误
方法说明
play(element?)播放/渲染轨道
stop()停止播放
close()关闭轨道并释放资源
setEnabled(enabled)启用/禁用轨道
setVolume(volume)设置音量 (音频轨道)
setDevice(deviceId)切换设备
getMediaStreamTrack()获取底层 MediaStreamTrack
Agora 参数Monibuca 映射
appidMonibuca WebSocket URL (如 ws://localhost:8180)
channel房间 ID (roomId)
uid用户 ID (userId)
token暂不使用,传 null

// 迁移前(使用 Zego)
import { ZegoExpressEngine } from "zego-express-engine-webrtc";
// 迁移后(使用 Monibuca)
import { ZegoExpressEngine } from "@monibuca/adapter-zego";
import { ZegoExpressEngine } from "@monibuca/adapter-zego";
// 创建引擎(appID 仅作标识,server 为 Monibuca 服务器地址)
const zg = new ZegoExpressEngine(0, "ws://your-server:8080");
// 监听房间流更新
zg.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);
}
}
});
// 监听用户进出
zg.on("roomUserUpdate", (roomID, updateType, userList) => {
console.log(`用户 ${updateType}:`, userList);
});
// 登录房间
const result = await zg.loginRoom("room-1", "", {
userID: "user-1",
userName: "张三",
});
if (result.errorCode === 0) {
// 创建本地流
const localStream = await zg.createZegoStream({
camera: { audio: true, video: true },
});
// 预览
document.getElementById("local-video").srcObject = localStream.stream;
// 推流
zg.startPublishingStream("stream-1", localStream);
}
方法说明
loginRoom(roomID, token, user, config?)登录房间
logoutRoom(roomID?)退出房间
createZegoStream(source?)创建本地流 (ZegoLocalStream)
createStream(source?)创建 MediaStream
startPublishingStream(streamID, stream)开始推流
stopPublishingStream(streamID)停止推流
startPlayingStream(streamID, option?)开始拉流
stopPlayingStream(streamID)停止拉流
enumDevices()枚举设备
useAudioDevice(stream, deviceID)切换音频设备
useVideoDevice(stream, deviceID)切换视频设备
sendBroadcastMessage(roomID, message)发送广播消息
destroyEngine()销毁引擎
方法说明
enableCamera(enable)开启/关闭摄像头
enableMicrophone(enable)开启/关闭麦克风
replaceVideoTrack(track)替换视频轨道
replaceAudioTrack(track)替换音频轨道
destroy()销毁流
事件触发时机
roomStateChanged房间连接状态变更
roomUserUpdate用户加入/离开房间
roomStreamUpdate远端流新增/删除
publisherStateUpdate推流状态变更
playerStateUpdate拉流状态变更
publishQualityUpdate推流质量统计 (每 2 秒)
playQualityUpdate拉流质量统计 (每 2 秒)
IMRecvBroadcastMessage收到广播消息
roomOnlineUserCountUpdate在线人数变更
Zego 参数Monibuca 映射
appID应用标识(仅做标识,不影响连接)
serverMonibuca WebSocket URL (如 ws://localhost:8180)
roomID房间 ID
userID用户 ID
streamID流路径 (streamPath)
token暂不使用,传空字符串

两个适配层底层统一使用 Monibuca SDK 的 RoomService 进行信令通信,WHIPClient 推流,WHEPClient 拉流。事件映射关系如下:

底层事件Agora 事件Zego 事件
REMOTE_USER_ENTERuser-joinedroomUserUpdate(ADD)
REMOTE_USER_EXITuser-leftroomUserUpdate(DELETE)
user-publishuser-publishedroomStreamUpdate(ADD)
user-unpublishuser-unpublishedroomStreamUpdate(DELETE)
CONNECTION_STATE_CHANGEDconnection-state-changeroomStateChanged
WHIPClient 状态publisherStateUpdate
WHEPClient 状态playerStateUpdate
chatIMRecvBroadcastMessage

  1. 服务器地址: Agora 适配层的 appid 参数和 Zego 适配层的 server 参数都应传入 Monibuca 服务器的 WebSocket 地址
  2. Token 认证: 当前版本不强制 Token 认证,可传 null 或空字符串
  3. 不支持的功能: 云端录制、CDN 转推、旁路推流等云服务相关功能不在适配层范围内
  4. 质量统计: 推拉流质量数据来自 WebRTC 原生 getStats() API,每 2 秒上报一次
  5. 设备管理: 设备枚举和切换均使用浏览器原生 mediaDevices API,与平台无关

联系我们

微信公众号:不卡科技 微信公众号二维码
腾讯频道:流媒体技术 腾讯频道二维码
QQ 频道:p0qq0crz08 QQ 频道二维码
QQ 群:751639168 QQ 群二维码