/** * 阿里云RTC * */ class AliRtc { constructor(channelId, userId, username, apiHost, uid) { console.log('AliRtc constructor') this.channelId = channelId; this.username = username; this.aliWebrtc = null; this.userId = userId; this.publisherList = []; this.apiHost = apiHost; // api接口域名 this.uid = uid; // 客户ID } init(callback) { console.log('AliRtc init') this.aliWebrtc = new AliRtcEngine(); this.aliWebrtc.setAudioOnlyMode(true); // 纯音频模式 // 初始化订阅状态 this.aliWebrtc.configRemoteAudio(this.userId, false); this.generateAliRtcAuthInfo( authInfo => { this.aliWebrtc.isSupport().then(re => { // console.log('support1', re); //let authInfo = this.generateAliRtcAuthInfo(); console.log('authinfo:', authInfo) this.aliWebrtc.joinChannel(authInfo, this.username).then(() => { console.log("加入房间成功", authInfo); $("#myName").text(`${this.username}, UserId:${authInfo.userid}`); // 发布本地流 this.aliWebrtc.configLocalAudioPublish = true; this.aliWebrtc.publish().then((res) => { console.log("发布流成功", res); // 回调函数 if (typeof callback === 'function') { callback() } this.event(); setInterval(() => { let userList = this.aliWebrtc.getUserList(); // console.log("UserList:", userList); }, 5000); }, (error) => { console.log("推流失败", error.message); }); // setInterval(() => { // this.refreshUserList(); // }, 2000); }).catch((error) => { console.log("加入房间失败", error.message); return false; }) }).catch(error => { alert(error.message); return false; }) }) } /** * 事件处理 */ event() { /** * remote用户加入房间 onJoin * 更新在线用户列表 */ this.aliWebrtc.on("onJoin", (publisher) => { console.log("onJoin", publisher); }); // 订阅onPublisher回调。当远程用户推流时,在SDK里会触发onPublisher回调,通过订阅这个回调,能够得到频道里已经推流的用户。 this.aliWebrtc.on('onPublisher', (publisher) => { console.log("onPublisher", publisher); }); // 订阅onUnPublisher回调。当远程用户结束推流时,会触发这个回调。 this.aliWebrtc.on('onUnPublisher', (publisher) => { console.log("onUnPublisher", publisher); let userId = publisher.userId; // 初始化订阅状态 this.aliWebrtc.configRemoteAudio(userId, false); }); /** * 收到订阅 */ $(document).on('click', '.sub', () => { let userId = $('.sub').attr('data-uid'); let userList = this.aliWebrtc.getUserList(); let index = this.getIndexByProprety2(userList, userId, "userId"); console.log('userList', userList); console.log('userId', userId); // 初始化订阅状态 this.aliWebrtc.configRemoteAudio(userId, false); let publisher = userList[index]; console.log('publisher', publisher) if (publisher.userId) { this.receivePublishManual(publisher.userId).then(re => { console.log("订阅成功 - .sub"); }); } }) /** * 页面刷新时调用离会 */ window.onbeforeunload = function (e) { if (!this.aliWebrtc) { showAlert("isSupport失败,未能初始化aliWebrtc", "danger"); return } this.aliWebrtc.leaveChannel(); this.aliWebrtc.dispose(); }; } // 创建授权信息 generateAliRtcAuthInfo(callback) { $.ajax({ url: `/analytics.php?act=get_rtc_token&uid=${this.uid}&userid=${this.userId}&channel=${this.channelId}`, async: false, method: 'GET', success: data => { data = JSON.parse(data) console.log('generateAliRtcAuthInfo'); if (data.code != 0) { alert(data.msg); return 1; } // 回调函数 if (typeof callback === 'function') { callback(data.data) } } }) } // 刷新用户列表 refreshUserList() { let html = '', userList = this.aliWebrtc.getUserList(); console.log('refreshUserList', userList); userList.forEach(val => { if (val.userId !== this.userId) { html += `

姓名:${val.displayName}, UserId:${val.userId} 订阅

`; } }); $("#userList").html(html); } getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } /** * 更新推流状态 * 当远端流发生变化时,通过onPublisher回调接收到信息 * 远端流不可用时其state值为inactive * 通过对比本地维护的publisherList来进行dom的删除 * 并且更新本地维护的publisherList */ updatePublisherStream(publisher, index){ let oldStreamConfigs = JSON.parse(JSON.stringify(this.publisherList[index].streamConfigs)); let newStreamConfigs = publisher.streamConfigs; let subscribeInfo = getSubscribeInfo(publisher.userId); oldStreamConfigs.forEach((v, i, a) => { let newStream = newStreamConfigs.getObjByProprety(v.label, "label"); // 判断流状态改变了 但不确定我们是否订阅了该流 if (v.state != newStream.state) { console.log("流的状态变了" + v.label, v, v.type, ">" + v.state + ">>" + newStream.state + ">", newStream, subscribeInfo); //并且要取消订阅某个流,不然就不能再次订阅了 subscribeInfo.subscribeInfoArr.forEach(sv => { if (v.label === sv.label) { console.log("setConfigRemote取消订阅调用[api]:subscribe", publisher.userId, sv.type, sv.label); setConfigRemote(publisher.userId, sv.type, sv.label).then(re => { // 移除dom this.removeDom(publisher.userId, v.label); }).catch(error => { console.error("流的状态变了重新订阅出问题", error); }); } }); } }); this.publisherList.splice(index, 1, publisher); } /** * 移除dom */ removeDom(userId, label) { if (userId) { if (!label) { $("#" + userId + "_camera").remove(); $("#" + userId + "_screen").remove(); } else { label = label === "sophon_video_camera_large" ? "camera" : "screen"; $("#" + userId + "_" + label).remove(); } } } /** * 用户停止推流时 删除用户列表中该用户 */ detelePublisher(userId) { console.log('detelePublisher publisherList', this.publisherList); let publisherList = this.publisherList; let index = getIndexByProprety2(publisherList, userId, "userId"); if (index != -1) { this.publisherList.splice(index, 1); this.detelePublisher(userId); } else { console.log("未找到之前的推流数据"); //删除推流用户 } } /** * 创建获取订阅的remote的video标签 */ getDisplayRemoteVideo(userId) { console.log('getDisplayRemoteVideo - userId:', userId); let id = userId + "_" + 'audio'; let videoWrapper = $("#" + id); if (videoWrapper.length == 0) { videoWrapper = $(` `); $(".video-container1").append(videoWrapper); } let dom = videoWrapper.find("audio")[0]; this.aliWebrtc.setDisplayRemoteVideo(userId, dom, 1); } /** * 订阅设置 */ receivePublishManual(userId) { console.log("订阅 - receivePublishManual this", this); console.log("订阅 - receivePublishManual Sub UserId", userId); return new Promise((resolve, reject) => { this.aliWebrtc.configRemoteAudio(userId, true); this.aliWebrtc.subscribe(userId).then(re => { console.log("订阅成功 - receivePublishManual"); this.getDisplayRemoteVideo(userId); resolve(); }).catch((error) => { reject(error); console.log("[订阅失败]" + error.message); }); }) } /** * 取消订阅设置 * @param v */ cancelPublishManual(userId) { console.log("取消订阅 - userId:", userId); this.aliWebrtc.configRemoteAudio(userId, false); return new Promise((resolve, reject) => { this.aliWebrtc.subscribe(userId).then(re => { $(".video-container1").empty(); resolve(); }).catch((error) => { reject(error); console.log("[取消订阅失败]" + error.message); }); }) } getIndexByProprety2(arr, val, proprety) { var index = -1; arr.forEach((v, i, a) => { if (v[proprety] == val) { index = i; } }); return index; } }