/* eslint-disable require-jsdoc */ class RtcClient { constructor(options) { this.sdkAppId_ = options.sdkAppId; this.userId_ = options.userId; this.userSig_ = options.userSig; this.roomId_ = options.roomId; this.isJoined_ = false; this.isPublished_ = false; this.localStream_ = null; this.remoteStreams_ = []; // check if browser is compatible with TRTC TRTC.checkSystemRequirements().then(result => { if (!result) { alert('Your browser is not compatible with TRTC! Please download Chrome M72+'); } }); } async join() { document.getElementById('agora_remote_video').style.height = 409 + 'px'; if (this.isJoined_) { console.warn('duplicate RtcClient.join() observed'); return; } // create a client for RtcClient this.client_ = TRTC.createClient({ mode: 'videoCall', // 实时通话模式 sdkAppId: this.sdkAppId_, userId: this.userId_, userSig: this.userSig_ }); // 处理 client 事件 this.handleEvents(); try { // join the room await this.client_.join({ roomId: this.roomId_ }); this.isJoined_ = true; } catch (error) { $('#spthWarnWin').hide(); console.error('failed to join room because: ' + error); alert( '进房失败原因:' + error + '\r\n\r\n请确保您的网络连接是正常的,您可以先体验一下我们的Demo以确保网络连接是正常的:' + '\r\n https://trtc-1252463788.file.myqcloud.com/web/demo/official-demo/index.html ' + '\r\n\r\n另外,请确保您的账号信息是正确的。' + '\r\n请打开链接:https://cloud.tencent.com/document/product/647/34342 查询详细错误信息!' ); return; } try { // 采集摄像头和麦克风视频流 await this.createLocalStream({ audio: true, video: true }); } catch (error) { console.error('createLocalStream with audio/video failed: ' + error); /*alert( '请确认已连接摄像头和麦克风并授予其访问权限!\r\n\r\n 如果您没有连接摄像头或麦克风,您可以通过调整第60行代码来关闭未连接设备的采集请求!' );*/ showFailureInfo_BigScreen_vido('请确认是否已连接摄像头和麦克风并授予其访问权限!'); try { // fallback to capture camera only await this.createLocalStream({ audio: false, video: true }); } catch (error) { console.error('createLocalStream with video failed: ' + error); $('#spthWarnWin').hide(); return; } $('#spthWarnWin').hide(); } this.localStream_.on('player-state-changed', event => { if (event.type === 'video' && event.state === 'PLAYING') { // dismiss the remote user UI placeholder } else if (event.type === 'video' && event.state === 'STOPPPED') { // show the remote user UI placeholder } }); // 在名为 ‘local_stream’ 的 div 容器上播放本地音视频 this.localStream_.play('agora_remote_video'); // publish local stream by default after join the room await this.publish(); } async leave() { if (!this.isJoined_) { console.warn('leave() - leave without join()d observed'); return; } if (this.isPublished_) { // ensure the local stream has been unpublished before leaving. await this.unpublish(true); } try { // leave the room await this.client_.leave(); this.isJoined_ = false; } catch (error) { console.error('failed to leave the room because ' + error); location.reload(); } finally { // 停止本地流,关闭本地流内部的音视频播放器 try { this.localStream_.stop(); } catch (error) { console.error('failed to stop local stream because ' + error); } finally { // 关闭本地流,释放摄像头和麦克风访问权限 this.localStream_.close(); this.localStream_ = null; } } } async publish() { if (!this.isJoined_) { console.warn('publish() - please join() firstly'); return; } if (this.isPublished_) { console.warn('duplicate RtcClient.publish() observed'); return; } try { // 发布本地流 await this.client_.publish(this.localStream_); this.isPublished_ = true; } catch (error) { console.error('failed to publish local stream ' + error); this.isPublished_ = false; } } async unpublish(isLeaving) { if (!this.isJoined_) { console.warn('unpublish() - please join() firstly'); return; } if (!this.isPublished_) { console.warn('RtcClient.unpublish() called but not published yet'); return; } try { // 停止发布本地流 await this.client_.unpublish(this.localStream_); this.isPublished_ = false; } catch (error) { console.error('failed to unpublish local stream because ' + error); if (!isLeaving) { console.warn('leaving the room because unpublish failure observed'); this.leave(); } } } async createLocalStream(options) { this.localStream_ = TRTC.createStream({ audio: options.audio, // 采集麦克风 video: options.video, // 采集摄像头 userId: this.userId_ // cameraId: getCameraId(), // microphoneId: getMicrophoneId() }); // 设置视频分辨率帧率和码率 this.localStream_.setVideoProfile('480p'); await this.localStream_.initialize(); } handleEvents() { // 处理 client 错误事件,错误均为不可恢复错误,建议提示用户后刷新页面 this.client_.on('error', err => { console.error(err); // location.reload(); }); // 处理用户被踢事件,通常是因为房间内有同名用户引起,这种问题一般是应用层逻辑错误引起的 // 应用层请尽量使用不同用户ID进房 this.client_.on('client-banned', err => { console.error('client has been banned for ' + err); // location.reload(); }); // 远端用户进房通知 - 仅限主动推流用户 this.client_.on('peer-join', evt => { const userId = evt.userId; }); // 远端用户退房通知 - 仅限主动推流用户 this.client_.on('peer-leave', evt => { const userId = evt.userId; closeVideoCall(); // alert('对方已挂断。') }); window.onbeforeunload = function(e) { closeVideoCall(); } // 处理远端流增加事件 this.client_.on('stream-added', evt => { const remoteStream = evt.stream; const id = remoteStream.getId(); const userId = remoteStream.getUserId(); // 远端流默认已订阅所有音视频,此处可指定只订阅音频或者音视频,不能仅订阅视频。 // 如果不想观看该路远端流,可调用 this.client_.unsubscribe(remoteStream) 取消订阅 this.client_.subscribe(remoteStream); }); // 远端流订阅成功事件 this.client_.on('stream-subscribed', evt => { const remoteStream = evt.stream; const id = remoteStream.getId(); this.remoteStreams_.push(remoteStream); $('#spth_win').show(); addViewId(id); window.isVideoConnect = true; // 在指定的 div 容器上播放音视频 remoteStream.play(id); $('#spthWarnWin').hide(); }); // 处理远端流被删除事件 this.client_.on('stream-removed', evt => { const remoteStream = evt.stream; const id = remoteStream.getId(); // 关闭远端流内部的音视频播放器 remoteStream.stop(); this.remoteStreams_ = this.remoteStreams_.filter(stream => { return stream.getId() !== id; }); removeView(id); }); // 处理远端流更新事件,在音视频通话过程中,远端流音频或视频可能会有更新 this.client_.on('stream-updated', evt => { const remoteStream = evt.stream; console.log( 'type: ' + remoteStream.getType() + ' stream-updated hasAudio: ' + remoteStream.hasAudio() + ' hasVideo: ' + remoteStream.hasVideo() ); }); // 远端流音频或视频mute状态通知 this.client_.on('mute-audio', evt => { console.log(evt.userId + ' mute audio'); }); this.client_.on('unmute-audio', evt => { console.log(evt.userId + ' unmute audio'); }); this.client_.on('mute-video', evt => { console.log(evt.userId + ' mute video'); }); this.client_.on('unmute-video', evt => { console.log(evt.userId + ' unmute video'); }); // 信令通道连接状态通知 this.client_.on('connection-state-changed', evt => { console.log(`RtcClient state changed to ${evt.state} from ${evt.prevState}`); }); } }