import Common from "./common"; import { message} from "antd"; export default class RtcClient { constructor(options) { 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.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(); } 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 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 }); } else { // not to specify cameraId/microphoneId to avoid OverConstrainedError this.localStream_ = TRTC.createStream({ audio: true, video: true, userId: this.userId_, mirror: true }); } 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}`); }); // publish the local stream await this.publish(); this.localStream_.play("main-video"); 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_.muteAudio(); } unmuteLocalAudio() { this.localStream_.unmuteAudio(); } muteLocalVideo() { this.localStream_.muteVideo(); } unmuteLocalVideo() { this.localStream_.unmuteVideo(); } resumeStreams() { this.localStream_.resume(); for (let stream of this.remoteStreams_) { stream.resume(); } } handleEvents() { this.client_.on("error", (err) => { console.error(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 ); } }); // fired when a remote peer is joining the room //有好友进来 this.client_.on("peer-join", (evt) => { const userId = evt.userId; console.log("peer-join " + userId); console.log(this.common) console.log(this.common.shareUserId) // if (userId !== this.common.shareUserId) { if (userId !== this.shareUserId) { this.common.addMemberView(userId); } }); // fired when a remote peer is leaving the room this.client_.on("peer-leave", (evt) => { const userId = evt.userId; this.common.removeView(userId); console.log("peer-leave " + userId); }); // fired when a remote stream is added this.client_.on("stream-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); } }); // fired when a remote stream has been subscribed this.client_.on("stream-subscribed", (evt) => { const uid = evt.userId; const remoteStream = evt.stream; const id = remoteStream.getId(); this.remoteStreams_.push(remoteStream); remoteStream.on("player-state-changed", (event) => { console.log(`${event.type} player is ${event.state}`); if (event.type == "video" && event.state == "STOPPED") { console.log(remoteStream.getId()) console.log(remoteStream.getUserId) console.log(document.getElementById("mask_" + remoteStream.getId())) // document.getElementById( // "mask_" + remoteStream.getId() // ).style.display = "flex"; // document // .getElementById(remoteStream.getUserId()) // .getElementsByClassName("member-video-btn").forEach((element, index) => { // element.setAttribute( // "src", // require("../../../assets/images/prevention/camera-off.png") // ); // }) //这个是为了清除与会者列表(自己加的) // document.getElementById(remoteStream.getId()).remove() // document.getElementById(remoteStream.userId_).remove() // $("#mask_" + remoteStream.getId()).show(); // $("#" + remoteStream.getUserId()) // .find(".member-video-btn") // .attr("src", "img/camera-off.png"); } if (event.type == "video" && event.state == "PLAYING") { document.getElementById( "mask_" + remoteStream.getId() ).style.display = "none"; document .getElementById(remoteStream.getUserId()) .getElementsByClassName("member-video-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/camera-on.png") ); }) // $("#mask_" + remoteStream.getId()).hide(); // $("#" + remoteStream.getUserId()) // .find(".member-video-btn") // .attr("src", "img/camera-on.png"); } }); this.common.addVideoView(id); // objectFit 为播放的填充模式,详细参考:https://trtc-1252463788.file.myqcloud.com/web/docs/Stream.html#play remoteStream.play(id, { objectFit: "contain" }); //添加“摄像头未打开”遮罩 // let mask = $("#mask_main").clone(); let mask = document.getElementById("mask_main").cloneNode(true); mask.setAttribute("id", "mask_" + id); // mask.attr("id", "mask_" + id); // mask.appendTo($("#player_" + id)); document.getElementById("player_" + id).appendChild(mask); // mask.hide(); mask.style.display = "hide"; if (!remoteStream.hasVideo()) { // mask.show(); mask.style.display = "show"; document .getElementById(remoteStream.getUserId()) .getElementsByClassName("member-video-btn").forEach((element, index) => { element.setAttribute( "src", require("../../../assets/images/prevention/camera-off.png") ); }) // $("#" + remoteStream.getUserId()) // .find(".member-video-btn") // .attr("src", "img/camera-off.png"); } console.log("stream-subscribed ID: ", id); }); // fired when the remote stream is removed, e.g. the remote user called Client.unpublish() 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; }); this.common.removeView(id); console.log(`stream-removed ID: ${id} type: ${remoteStream.getType()}`); }); this.client_.on("stream-updated", (evt) => { 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(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(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"); 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"); 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; } } } }