import Common from "./common"; import { message} from "antd"; import {searchDeptUser} from "../../../services/api_command" import { recordAudioInsert } from "./recordRTC" export default class RtcClient { constructor(options,_this) { this.common = Common.call(this); this.sdkAppId_ = options.sdkAppId; this.userId_ = options.userId; this.userSig_ = options.userSig; this.roomId_ = options.roomId; this.shareUserId='share_'+this.userId_ this.isJoined_ = false; this.isPublished_ = false; this.isAudioMuted = false; this.isVideoMuted = false; this.localStream_ = null; this.remoteStreams_ = []; this._this = _this; // 这里的 this 指向调用者类,可使用 props, state 等属性 this.members_ = new Map(); // create a client for RtcClient this.client_ = TRTC.createClient({ mode: "rtc", sdkAppId: this.sdkAppId_, userId: this.userId_, userSig: this.userSig_, userDefineRecordId: this.userId_ }); this.handleEvents(_this); } async join() { if (this.isJoined_) { console.warn("duplicate RtcClient.join() observed"); return; } try { // join the room await this.client_.join({ roomId: this.roomId_, }); console.log("join room success"); this.isJoined_ = true; // create a local stream with audio/video from microphone/camera // 当模式为视频上拉时,不需调用摄像头 let createJSON = { audio: true, userId: this.userId_, }; // // 功能类型 0: 视频调度(一对多) 1: 视频上拉(一对一) if (this._this.props.videoGenre == 0) { createJSON.video = true createJSON.mirror=true // 是否开启本地视频镜像预览。 } else { createJSON.video = false createJSON.mirror = false } if (this.common.getCameraId() && this.common.getMicrophoneId()) { // this.localStream_ = TRTC.createStream({ // audio: true, // video: true, // userId: this.userId_, // cameraId: this.common.getCameraId(), // // cameraId:getCameraId(), // microphoneId: this.common.getMicrophoneId(), // // microphoneId: getMicrophoneId(), // mirror: true // }); createJSON.microphoneId = this.common.getMicrophoneId() createJSON.cameraId = this.common.getCameraId() } else { // not to specify cameraId/microphoneId to avoid OverConstrainedError // this.localStream_ = TRTC.createStream({ // audio: true, // video: true, // userId: this.userId_, // mirror: true // }); } console.log('createJSON', createJSON); this.localStream_ = TRTC.createStream(createJSON); try { // initialize the local stream and the stream will be populated with audio/video await this.localStream_.initialize(); console.log("initialize local stream success"); this.localStream_.on("player-state-changed", (event) => { console.log(`local stream ${event.type} player is ${event.state}`); }); window.recordStream.localStream = this.localStream_; // publish the local stream await this.publish(); this.localStream_.play("main-video"); if (this._this.props.videoGenre == 1) { this.common.isMicOn = false; this.muteLocalAudio(); } document.getElementById("main-video-btns").style.display = "flex"; document .getElementById("player_" + this.localStream_.getId()) .appendChild(document.getElementById("mask_main")); // $('#main-video-btns').show(); // $('#mask_main').appendTo($('#player_' + this.localStream_.getId())); // var videoDiv = document.createElement("div"); // videoDiv.id = "player_" + this.localStream_.getId(); // document.getElementById("mask_main").appendChild(videoDiv) // $('#main-video-btns').show(); // $('#mask_main').appendTo($('#player_' + this.localStream_.getId())); } catch (e) { document.getElementById("main-video-btns").style.display = "none"; document.getElementById("mask_main").style.display = "flex"; console.error("failed to initialize local stream - " + e); } } catch (e) { console.error("join room failed! " + e); } //更新成员状态 let states = this.client_.getRemoteMutedState(); for (let state of states) { if (state.audioMuted) { document .getElementById(state.userId) .getElementsByClassName("member-audio-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/mic-off.png") ); }) // $("#" + state.userId) // .find(".member-audio-btn") // .attr("src", "./img/mic-off.png"); } if (state.videoMuted) { document .getElementById(state.userId) .getElementsByClassName("member-video-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/camera-off.png") ); }) document.getElementById( "mask_" + this.members_.get(state.userId).getId() ).style.display = "flex"; // $("#" + state.userId) // .find(".member-video-btn") // .attr("src", "./img/camera-off.png"); // $("#mask_" + this.members_.get(state.userId).getId()).show(); } } } async leave() { if (!this.isJoined_) { console.warn("leave() - please join() firstly"); return; } // ensure the local stream is unpublished before leaving. await this.unpublish(); // leave the room await this.client_.leave(); this.localStream_.stop(); this.localStream_.close(); this.localStream_ = null; this.isJoined_ = false; // resetView(); // this.common.resetView() } 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_); } catch (e) { console.error("failed to publish local stream " + e); this.isPublished_ = false; } this.isPublished_ = true; } async unpublish() { if (!this.isJoined_) { console.warn("unpublish() - please join() firstly"); return; } if (!this.isPublished_) { console.warn("RtcClient.unpublish() called but not published yet"); return; } await this.client_.unpublish(this.localStream_); this.isPublished_ = false; } muteLocalAudio() { this.localStream_ && this.localStream_.muteAudio(); } unmuteLocalAudio() { this.localStream_ && this.localStream_.unmuteAudio(); } muteLocalVideo() { this.localStream_ && this.localStream_.muteVideo(); } unmuteLocalVideo() { this.localStream_ && this.localStream_.unmuteVideo(); } resumeStreams() { this.localStream_ && this.localStream_.resume(); for (let stream of this.remoteStreams_) { stream.resume(); } } handleEvents(_this) { this.client_.on("error", (err) => { console.error('client_handleEvents', err); alert(err); // location.reload(); }); // 用户被踢出房间通知 this.client_.on("client-banned", (err) => { console.error("client has been banned for " + err); if (!this.common.isHidden()) { message.warning('您已被踢出房间'); // alert("您已被踢出房间"); // location.reload(); } else { document.addEventListener( "visibilitychange", () => { if (!this.common.isHidden()) { message.warning('您已被踢出房间'); // alert("您已被踢出房间"); // location.reload(); } }, false ); } }); // 远端用户进房通知 //有好友进来 this.client_.on("peer-join", (evt) => { const userId = evt.userId; // console.log("peer-join " + userId); // console.log(this.common) // console.log(this.common.shareUserId) // console.log(_this.props.dispatch) // if (userId !== this.common.shareUserId) { if (userId !== this.shareUserId) { this.common.addMemberView(userId); console.log('client_join', 'fetchVideoMemberList'); // _this.props.dispatch({ // type:'command/fetchVideoMemberList', // payload:{ // type:'peerJoin', // memberList:{ // mobilePhone:userId, // status:'yes', // id:userId+'yes' // } // } // }) } }); // 远端用户退房通知 this.client_.on("peer-leave", (evt) => { const userId = evt.userId; this.common.removeView(userId); console.log("peer-leave " + userId); console.log('client_leave', 'fetchVideoMemberList'); _this.props.dispatch({ type:'command/fetchVideoMemberList', payload:{ type:'leave', memberList:{ mobilePhone:userId, status:'leave', id:userId+'leave' } } }) }); // 远端流添加事件,当远端用户发布流后会收到该通知。 this.client_.on("stream-added", (evt) => { console.log('client_added', evt); const remoteStream = evt.stream; const id = remoteStream.getId(); const userId = remoteStream.getUserId(); this.members_.set(userId, remoteStream); console.log( `remote stream added: [${userId}] ID: ${id} type: ${remoteStream.getType()}` ); if (remoteStream.getUserId() === this.shareUserId) { // don't need screen shared by us this.client_.unsubscribe(remoteStream); } else { console.log("subscribe to this remote stream"); this.client_.subscribe(remoteStream); } }); // SDK和腾讯云的连接状态变化事件,您可以利用该事件从全景上监听SDK与腾讯云的连接状态。 // 'DISCONNECTED':连接断开 // 'CONNECTING':正在连接中 // 'RECONNECTING':自动重连中 // 'CONNECTED':已连接 this.client_.on('connection-state-changed', event => { console.log(' TRTC 连接状态', event); return; if (event.prevState == "CONNECTING") { // 模拟用户进入,进行测试开发 let videoMember = [];//用于记录是否已经进入房间使用 setTimeout(()=>{ for (let index = 1; index < 52; index++) { console.log('client_-changed', 'fetchVideoMemberList', event); const userId = 179901648+index; const id = new Date().getTime()+"_000000000"; const userName = '测试'+index; this.common.addMemberView(userId); console.log('client_join', 'fetchVideoMemberList'); videoMember.push({ videoId: id, hasVideo: false, userName: userName, mobilePhone:userId, status:'yes', id:userId+'yes' }) } _this.props.dispatch({ type:'command/fetchVideoMemberList', payload:{ type:'add', memberList:videoMember } }) }, 5000) } }); // 最后流订阅成功事件,调用订阅()成功后会触发该事件。 this.client_.on("stream-subscribed", async(evt) => { console.log(evt) console.log('client_subscribed', 'fetchVideoMemberList'); console.log('evt.stream', evt.stream) if (evt.stream.hasAudio) { const track = evt.stream.getAudioTrack(); console.log('evt.track', track) setTimeout(()=>{ recordAudioInsert(evt.stream); }, 700); } const remoteStream = evt.stream; const id = remoteStream.getId(); const uid = remoteStream.userId_; const data = await searchDeptUser({ keyWord: remoteStream.userId_ }) // console.log('searchDeptUser', data) let userName = "" if (data && data.data && data.data.length > 0){ userName = data.data[0].item_securityname } _this.props.dispatch({ type:'command/fetchVideoMemberList', payload:{ type:'peerJoin', memberList:{ videoId: id, hasVideo: remoteStream.hasVideo(), userName: userName, mobilePhone:uid, status:'yes', id:uid+'yes' } } }) this.remoteStreams_.push(remoteStream); remoteStream.play(id, { objectFit: "contain" }); remoteStream.on("player-state-changed", (event) => { console.log("player-state-changed", `${event.type} player is ${event.state}`); if (event.type == "video" && event.state == "PLAYING") { _this.props.dispatch({ type:'command/fetchVideoMemberList', payload:{ type:'peerJoin', memberList:{ videoId: id, hasVideo: true, userName: userName, mobilePhone:uid, status:'yes', id:uid+'yes' } } }) } }); }); // 远端流移除事件,当远端用户取消发布流后会收到通知。 this.client_.on("stream-removed", (evt) => { console.log('client_removed', 'fetchVideoMemberList'); const remoteStream = evt.stream; const id = remoteStream.getId(); remoteStream.stop(); this.remoteStreams_ = this.remoteStreams_.filter((stream) => { return stream.getId() !== id; }); this.common.removeView(id); console.log(`stream-removed ID: ${id} type: ${remoteStream.getType()}`); }); // 远端流更新事件,当远端用户添加、移除或缺失音视频轨道后会收到该通知。 this.client_.on("stream-updated", (evt) => { console.log('client_updated', 'fetchVideoMemberList'); const remoteStream = evt.stream; let uid = this.getUidByStreamId(remoteStream.getId()); if (!remoteStream.hasVideo()) { document .getElementById(uid) .getElementsByClassName("member-video-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/camera-off.png") ); }) // $("#" + uid) // .find(".member-video-btn") // .attr("src", "img/camera-off.png"); } // console.log( // "type: " + // remoteStream.getType() + // " stream-updated hasAudio: " + // remoteStream.hasAudio() + // " hasVideo: " + // remoteStream.hasVideo() + // " uid: " + // uid // ); }); // 远端用户禁用音频通知。 this.client_.on("mute-audio", (evt) => { console.log('client_audio', 'fetchVideoMemberList'); console.log(evt.userId + " mute audio"); document .getElementById(evt.userId)&& document .getElementById(evt.userId) .getElementsByClassName("member-audio-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/mic-off.png") ); }) // $("#" + evt.userId) // .find(".member-audio-btn") // .attr("src", "img/mic-off.png"); }); // 远端用户启用音频通知。 this.client_.on("unmute-audio", (evt) => { console.log('client_unmute', 'fetchVideoMemberList'); console.log(evt.userId + " unmute audio"); document .getElementById(evt.userId) .getElementsByClassName("member-audio-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/mic-on.png") ); }) // $("#" + evt.userId) // .find(".member-audio-btn") // .attr("src", "img/mic-on.png"); }); // 远端用户禁用视频通知。 this.client_.on("mute-video", (evt) => { console.log(evt.userId + " mute video"); console.log('client-video', 'fetchVideoMemberList'); document .getElementById(evt.userId) .getElementsByClassName("member-video-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/camera-off.png") ); }) // $("#" + evt.userId) // .find(".member-video-btn") // .attr("src", "img/camera-off.png"); console.log(this.members_.get(evt.userId)) let streamId = this.members_.get(evt.userId).getId(); if (streamId) { document.getElementById("mask_" + streamId).style.display = "flex"; // $("#mask_" + streamId).show(); } }); // 远端用户启用视频通知。 this.client_.on("unmute-video", (evt) => { console.log(evt.userId + " unmute video"); console.log('client-unmute-v', 'fetchVideoMemberList'); document .getElementById(evt.userId)&&document .getElementById(evt.userId) .getElementsByClassName("member-video-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/camera-on.png") ); }) // $("#" + evt.userId) // .find(".member-video-btn") // .attr("src", "img/camera-on.png"); const stream = this.members_.get(evt.userId); if (stream) { let streamId = stream.getId(); if (streamId) { //这里不行 console.log("mask_" + streamId) console.log(document.getElementById("mask_" + streamId)); document.getElementById("mask_" + streamId)?document.getElementById("mask_" + streamId).style.display = "none":''; // $("#mask_" + streamId).hide(); } } }); } showStreamState(stream) { console.log( "has audio: " + stream.hasAudio() + " has video: " + stream.hasVideo() ); } getUidByStreamId(streamId) { for (let [uid, stream] of this.members_) { if (stream.getId() == streamId) { return uid; } } } }