在直播中应用层可以根据业务需求,监听房间中的抛出的事件做合适的处理,保证音视频的正常交互。
myClient.on("stream-added", (data) => {...}) //远端推流 myClient.on("stream-subscribed", (data) => {...}) //订阅流成功 myClient.on("stream-removed", (data) => {...}) //远端结束推流 myClient.on("mute-video", (data) => {...}) //远端关掉摄像头 myClient.on("unmute-video", (data)=> {...}) //远端打开摄像头 myClient.on("mute-audio", (data) => {...}) //远端关掉麦克风 myClient.on("unmute-audio", (data)=> {...}) //远端打开麦克风 myClient.on("error", (error)=> {...}) //房间内错误,重新进入房间 myClient.on("client-banned", ()=> {...}) //相同userid在其他端登陆,被踢出 myClient.on("user-kicked", () => {...}) //被提出房间 myClient.on("peer-joined", (data) => {...}) //其他用户进入房间通知 myClient.on("peer-leaved", (data) => {...}) //用户退出房间通知 myClient.on("token-expire", (data)=> {...}) //token已经过期 myClient.on("room-closed", (data)=> {...}) //房间关闭通知
rtc-sdk 内部有自动重进房间、恢复音视频的推拉流的逻辑。实际上网络环境较为复杂、主播和观众的设备状况差异较大,重进教室可能还是会失败,所以需要应用层监听 Client 对象的 error 事件,重进直播房间。
myClient.on("error", (error) => { this.myClient.destroy() this.myClient = BLive.createClient({ codec: "h264", appId: this.appId, comments: "brtc-js-demo-web", useBplayer: false, mode:'rtc' }); registeListeners() let count = 0; const reconnect = () => { this.rtcJoin().catch(() => { if (count < 3) { count++ reconnect() }else { this.myClient.leave() } }) } reconnect() }) rtcJoin() { return new Promise((resolve, reject) => { this.client.join( this.roomId, this.userId, this.mainSig, { role: "anchor", } ).then(() => { //成功加入房间 resolve(); }) .catch((error) => { reject(); }) }) }
由于市场上设备的多样性,在打开摄像头设备,初始化本地流对象时,可能会出现各种问题,需要对抛出的各种问题做相应的逻辑处理。sdk 会抛出包含详细错误信息的事件。应用层可以对这些不同错误原因的事件添加合适的处理逻辑, 保障正常的音视频互动。
在发布流出错时,间隔 2 秒后尝试重新发布数据流避免一些设备被占用没有释放的问题。
publishCameraStream() { let camera = getCurrentCamera(); let mic = getCurrentMic(); if (camera || mic) { let options = { video: !!camera, audio: !!mic, autoGainControl: false, }; if (camera) { options.cameraId = camera.deviceId; } if (mic) { options.microphoneId = mic.deviceId; } let publishStream; try { publishStream = BLive.createStream(options); } catch (error) { let code = error && error.getCode(); let name = ""; switch (code) { case "0x1003": name = "DevicesNotFoundError"; //未找到设备,添加报错、或者其他处理逻辑 break; } reject({ name: name, error: error, }); return; } publishStream .init() .then(() => { this.publishStream = publishStream; this.client .publish(this.publishStream) .catch((error) => { //重新推流 this.republishCameraStream() }); this.publishStream.on("connect-error", () => { //推流中断,重新推流 this.republishStreamTimer = setTimeout(() => { this.republishCameraStream(); }, 2000); }); publishStream.on("player-state-changed", (data) => { //处理播放器状态改变,添加处理逻辑、或者忽略 }); }) .catch((error) => { switch (error.name) { case "NotReadableError": case "TrackStartError": //could not start audio sourse,或者could not start video sourse // 设备被占用,暂时无法访问摄像头/麦克风 //添加报错或者其他处理逻辑 break; case "NotAllowedError": //未授权摄像头/麦克风访问 //添加报错或者其他处理逻辑 break; case "AbortError": //由于未知原因导致设备无法被使用"; //添加报错或者其他处理逻辑 break; case "NotFoundError": case "DevicesNotFoundError": // 未找到音频或者视频设备 //添加报错或者其他处理逻辑 break; case "OverconstrainedError": // 参数不支持 //添加报错或者其他处理逻辑 break; default: //其他错误,添加报错或者其他处理逻辑 break; } }); } else { //未找到摄像头和麦克风,添加报错逻辑 } } republishCameraStream() { this.client.publish(this.publishStream).then( () => { if(this.republishStreamTimer){ clearTimeout(this.republishStreamTimer) } }, () => { this.republishStreamTimer = setTimeout(() => { this.republishCameraStream(); }, 2000); } ) }
房间和设备容错处理
房间中事件监听
在直播中应用层可以根据业务需求,监听房间中的抛出的事件做合适的处理,保证音视频的正常交互。
重进直播房间
rtc-sdk 内部有自动重进房间、恢复音视频的推拉流的逻辑。实际上网络环境较为复杂、主播和观众的设备状况差异较大,重进教室可能还是会失败,所以需要应用层监听 Client 对象的 error 事件,重进直播房间。
设备错误事件处理
由于市场上设备的多样性,在打开摄像头设备,初始化本地流对象时,可能会出现各种问题,需要对抛出的各种问题做相应的逻辑处理。sdk 会抛出包含详细错误信息的事件。应用层可以对这些不同错误原因的事件添加合适的处理逻辑, 保障正常的音视频互动。
在发布流出错时,间隔 2 秒后尝试重新发布数据流避免一些设备被占用没有释放的问题。