本文将介绍如何快速实现一个简单的实时音视频通话。
相关概念解释:
更多相关概念请参考 术语说明。
在实现基本的实时音视频功能之前,请确保:
本产品本平台的功能不是默认开启的,使用前请在 ZEGO 控制台 自助接入服务开通(开通步骤请参考 控制台 - 项目管理 中的“服务接入”),或联系 ZEGO 技术支持开通。
以用户 A 拉取用户 B 的流为例,流程如下图:
整个推拉流过程的 API 调用时序如下图:
1. (可选)创建界面
在创建引擎之前,推荐开发者添加以下界面元素,方便实现基本的实时音视频功能。
2. 创建引擎
创建 ZegoExpressEngine 引擎实例,将申请到的 AppID 传入参数 “appID”,将获取到的 Server 地址传入参数 “server”。
// 初始化实例
const zg = new ZegoExpressEngine(appID, server);
3. (可选)监听事件回调
如果需要注册回调,开发者可根据实际需要,实现 ZegoEvent 中的某些方法,创建引擎后可通过调用 on 接口设置回调。
zg.on('roomStateUpdate', (roomID, state, errorCode, extendedData) => {
if (state == 'DISCONNECTED') {
// 与房间断开了连接
// ...
}
if (state == 'CONNECTING') {
// 与房间尝试连接中
// ...
}
if (state == 'CONNECTED') {
// 与房间连接成功
// ...
}
})
1. 获取登录 Token
登录房间需要用于验证身份的 Token,获取方式请参考 用户权限控制。如需快速调试,建议使用控制台生成的临时 Token。
2. 登录房间
调用 SDK 的 loginRoom 接口,传入房间 ID 参数 “roomID”、“token” 和用户参数 “user”,登录房间。
// 登录房间,成功则返回 true
const result = await zg.loginRoom(roomID, token, {userID, userName});
3. 监听登录房间后的事件回调
根据实际应用需要,在登录房间前监听想要关注的事件通知,比如房间状态更新、用户状态更新、流状态更新等。
roomStateUpdate:房间状态更新回调。登录房间后,当房间连接状态发生变更(如出现房间断开,登录认证失败等情况),SDK 会通过该回调通知。
roomUserUpdate:用户状态更新回调。登录房间后,当房间内有用户新增或删除时,SDK 会通过该回调通知。
只有调用 loginRoom 接口登录房间时传入 ZegoRoomConfig 配置,且 “isUserStatusNotify” 参数取值为 “true” 时,用户才能收到 onRoomUserUpdate 回调。
// 房间状态更新回调
zg.on('roomStateUpdate', (roomID,state,errorCode,extendedData) => {
if (state == 'DISCONNECTED') {
// 与房间断开了连接
}
if (state == 'CONNECTING') {
// 与房间尝试连接中
}
if (state == 'CONNECTED') {
// 与房间连接成功
}
})
// 用户状态更新回调
zg.on('roomUserUpdate', (roomID, updateType, userList) => {
console.warn(
`roomUserUpdate: room ${roomID}, user ${updateType === 'ADD' ? 'added' : 'left'} `,
JSON.stringify(userList),
);
});
// 流状态更新回调
zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {
if (updateType == 'ADD') {
// 流新增,开始拉流
} else if (updateType == 'DELETE') {
// 流删除,停止拉流
}
});
1. 开始推流
触发推流后,调用 SDK 的 startPublishingStream 接口,传入流 ID 参数 “streamID”,获取 “streamID” 对应的推流地址。
调用微信小程序的 wx.createLivePusherContext 创建 live-pusher,将获取到的推流地址设置为 live-pusher 的 “url” 属性,然后调用 live-pusher 的 start 录制视频。
“streamID” 的参数取值需要在整个 AppID 内全局唯一,是自定义的、长度不超过 256 字节的字符串。仅支持数字,英文字符和 “~”,“!”,“@”,“$”,“%”,“^”,“&”,“*”,“(”,“)”,“_”,“+”,“=”,“-”,“`”,“;”,“’”,“,”,“.”,“<”,“>”,“/”,“\”。
// 1. 推流方登录房间成功后触发推流。
// 调用 SDK 的 startPublishingStream 获取 streamID 对应的推流地址。
let { streamID, url } = await zg.startPublishingStream(streamID);
// 2. 调用微信小程序的 wx.createLivePusherContext 创建 live-pusher。
// 将步骤 1 中获取的推流流地址设置为 live-pusher 的 url。
// 然后调用 live-pusher 的 start 录制视频。
try {
this.setData(
{
livePusherUrl: url,
livePusher: wx.createLivePusherContext(),
},
() => {
this.data.livePusher.start();
}
);
} catch (error) {
console.error("error", error);
}
2. 推流事件处理
微信小程序会在 live-pusher 的 bindstatechange 绑定的方法中通知出推流状态事件,开发者需要:
a. 在 bindstatechange 绑定的回调函数中,调用 SDK 的 updatePlayerState 接口将推流状态事件透传给 SDK。
b. 在 SDK 的 publisherStateUpdate 回调中处理推流的开始、失败状态。
// live-pusher 绑定推流事件
onPushStateChange(e) {
// 透传推流事件给 SDK
zg.updatePlayerState(this.data.publishStreamID, e);
},
// 推流后,服务器主动推过来的,流状态更新
// NO_PUBLISH:未推流状态,PUBLISH_REQUESTING:正在请求推流状态,PUBLISHING:正在推流状态
// state: "PUBLISHING" | "NO_PUBLISH" | "PUBLISH_REQUESTING";
zg.on("publisherStateUpdate", (result) => {
console.log("publishStateUpdate", result.state);
});
微信小程序会在 live-pusher 的 bindnetstatus 绑定的方法中通知出推流网络事件,开发者需要在对应的小程序回调中,调用 SDK 的 updatePlayerNetStatus 接口将推流网络事件透传给 SDK。
// live-pusher 绑定网络状态事件
onPushNetStateChange(e) {
//透传网络状态事件给 SDK,type 1 推流
zg.updatePlayerNetStatus(this.data.publishStreamID, e);
},
// SDK 推流网络质量回调
zg.on("publishQualityUpdate", (streamID, publishStats) => {
console.log("publishQualityUpdate", streamID, publishStats);
});
1. 开始拉流
触发拉流后,调用 SDK 的 startPlayingStream 接口,根据传入的流 ID 参数 “streamID”,获取 streamID 对应的拉流地址。
远端用户推送的 “streamID” 可以从 roomStreamUpdate 回调中获得。
调用微信小程序的 wx.createLivePlayerContext 创建 live-player,将获取到的拉流地址设置为 live-player 的 “src” 属性,然后调用 live-player 的 play 播放视频。开发者也可以设置 live-player 为 autoplay,播放器会自动播放,无需再手动调用 play。
// 1. 在 SDK 的回调 roomStreamUpdate 中获取拉流streamID。
// 当用户加入或离开房间时,该事件被触发。
zg.on("roomStreamUpdate", (roomID, updateType, streamList) => {
console.log("roomStreamUpdate", roomID, updateType, streamList);
if (updateType === "ADD") {
// to play ......
} else {
// to stopPlay .....
}
});
// 2. 开始拉流
let { streamID, url } = await zg.startPlayingStream(playStreamID,{ sourceType: "BGP" });
// 3. 调用微信小程序的 wx.createLivePlayerContext 创建 live-player。
// 将步骤 2 中获取的拉流地址设置为 live-player 的 src.
// 然后调用 live-player 的 play() 播放视频。
// 此步骤也可以设置 live-player 为 autoplay,此时播放器会自动播放,无需再手动调用 play()。
try {
this.setData(
{
playUrl: url,
playContext: wx.createLivePlayerContext(),
},
() => {
this.data.playContext.play();
}
);
} catch (error) {
console.error("error", error);
}
2. 拉流事件处理
微信小程序会在 live-player 的 bindstatechange 绑定的方法中通知出拉流状态事件,开发者需要:
a. 在 bindstatechange 绑定的回调函数中,调用 SDK 的 updatePlayerState 接口将拉流状态事件透传给 SDK。
b. 在 SDK 提供的 playerStateUpdate 回调中处理拉流的开始、失败状态。
// live-player 绑定的拉流事件
onPlayStateChange(e) {
// 透传拉流事件给 SDK
zg.updatePlayerState(e.currentTarget.id, e);
},
// 服务端主动推过来的 流的播放状态
// 视频播放状态通知;state: "NO_PLAY" | "PLAY_REQUESTING" | "PLAYING";
zg.on("playerStateUpdate", (result) => {
console.log("playStateUpdate", result.state);
});
微信小程序会在 live-player 的 bindnetstatus 绑定的方法中通知出拉流网络事件,开发者需要在对应的小程序回调中,调用 SDK 的 updatePlayerNetStatus 接口将推流网络事件透传给 SDK。
// live-player 绑定网络状态事件
onPlayNetStateChange(e) {
// 透传网络状态事件给 SDK
zg.updatePlayerNetStatus(playStreamID, e);
},
// SDK 拉流网络质量回调
zg.on("playQualityUpdate", (playStreamID, playStats) => {
console.log("playQualityUpdate", playStreamID, playStats);
});
在真机中运行项目,运行成功后,可以看到本端视频画面。
为方便体验,ZEGO 提供了一个 Web 端调试示例 ,在该页面下,输入相同的 AppID、RoomID,输入不同的 UserID、以及对应的 Token,即可加入同一房间与真机设备互通。当成功开始音视频通话时,可以听到远端的音频,看到远端的视频画面。
1. 停止推流
调用 SDK 的 stopPublishingStream 接口清空推流状态。
调用微信小程序 live-pusher 的 stop 停止推流。
一定要清空推流状态,否则可能导致 SDK 状态异常。
// 停止推流
zg.stopPublishingStream(publishStreamID);
this.data.pusherVideoContext.stop();
3. 停止拉流
调用 SDK 的 stopPlayingStream 接口清空拉流状态。
调用微信小程序 live-player 的 stop 停止拉流。
一定要清空拉流状态,否则可能导致 SDK 状态异常。
// 停止拉流
zg.stopPlayingStream(playStreamID);
this.data.playContext && this.data.playContext.stop();
调用 SDK 的 logoutRoom 接口退出房间。
zg.logoutRoom(roomID)
联系我们
文档反馈