123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- <template>
- <div class="trtccom" v-if="show">
- <Device @switchDevice="switchDevice" @canUseDevice="canUseDevice" />
- <div
- class="local"
- :class="{ disabledlocal: role == 'customer' || !videoDeviceId }"
- id="local"
- v-if="isJoined"
- >
- <div class="micBox">
- <img
- v-if="muteAudioLeader"
- :src="require('@/assets/images/rtcLive/mic_off@2x.png')"
- alt=""
- />
- <i v-else class="speak_mic"></i>
- </div>
- </div>
- <template v-if="isJoined && invitedRemoteStreams.length > 0">
- <div
- class="local"
- :data-role="item.userId_"
- :class="{
- disabledlocal:
- item.userId_.indexOf('customer') > -1 || !videoDeviceId,
- }"
- v-for="item in invitedRemoteStreams"
- :id="item.userId_"
- :key="item.userId_"
- >
- <div class="micBox">
- <img
- v-if="muteAudioLeader"
- :src="require('@/assets/images/rtcLive/mic_off@2x.png')"
- alt=""
- />
- <i v-else class="speak_mic"></i>
- </div>
- </div>
- </template>
- <div
- class="videoBox userVideo"
- v-show="props.videoMuted || muteVideoLeader"
- v-if="false"
- >
- <img
- :src="require('@/assets/images/rtcLive/avatar_small@2x.png')"
- alt=""
- />
- <div class="micBox">
- <img
- v-if="muteAudioLeader"
- :src="require('@/assets/images/rtcLive/mic_off@2x.png')"
- alt=""
- />
- <i v-else class="speak_mic"></i>
- </div>
- </div>
- </div>
- </template>
- <script setup>
- import TRTC, { Client, LocalStream } from "trtc-js-sdk";
- import { Dialog } from "@/global_components/";
- import {
- ref,
- computed,
- watch,
- defineEmits,
- defineProps,
- nextTick,
- onUnmounted,
- } from "vue";
- import Device from "./trtc/Device";
- import { useStore } from "vuex";
- import browser from "@/utils/browser";
- // import * as apis from "@/apis/index.js";
- const emit = defineEmits(["audioMuted", "videoMuted", "closeSocket"]);
- const store = useStore();
- const show = ref(false);
- const invitedRemoteStreams = ref([]);
- const role = ref(browser.getURLParam("role"));
- const muteAudioLeader = ref(false);
- const muteVideoLeader = ref(false);
- const isJoined = computed(() => store.getters["rtc/isJoined"]);
- const isPublished = computed(() => store.getters["rtc/isPublished"]);
- const videoDeviceId = computed(() => store.getters["rtc/videoDeviceId"]);
- const initParamsStates = computed(
- () =>
- !!(
- store.getters["rtc/sdkAppId"] &&
- store.getters["rtc/secretKey"] &&
- store.getters["rtc/roomId"] &&
- store.getters["rtc/userId"]
- )
- );
- const userSig = computed(() => store.getters["rtc/userSig"]);
- let localClient = "";
- let localStream = "";
- let shareClient = "";
- const props = defineProps({
- audioMuted: {
- default: false,
- },
- videoMuted: {
- default: false,
- },
- });
- watch(
- () => props.audioMuted,
- () => {
- if (props.audioMuted) {
- localStream.muteAudio();
- } else {
- localStream.unmuteAudio();
- }
- if (role.value == "leader") {
- muteAudioLeader.value = props.audioMuted;
- }
- }
- );
- watch(
- () => props.videoMuted,
- () => {
- if (props.videoMuted) {
- localStream.muteVideo();
- } else {
- localStream.unmuteVideo();
- }
- }
- );
- // watch(
- // () => isJoined.value,
- // () => {
- // if (!isJoined.value) {
- // handleLeave();
- // }
- // }
- // );
- TRTC.checkSystemRequirements().then((checkResult) => {
- if (!checkResult.result) {
- Dialog.toast({ content: `您的设备不支持音视频通讯`, type: "error" });
- } else {
- show.value = true;
- }
- });
- async function createLocalStream() {
- try {
- localStream = TRTC.createStream({
- userId: store.getters["rtc/userId"],
- audio: true,
- video: false,
- microphoneId: store.getters["rtc/audioDeviceId"],
- });
- await localStream.initialize();
- if(props.audioMuted){
- localStream.muteAudio();
- }
- } catch (error) {
- console.log(error, "createStream");
- }
- }
- async function handleJoin() {
- if (!initParamsStates.value) {
- return;
- }
- try {
- // let res = await apis.getSign({ userId: store.getters["rtc/userId"] });
- localClient = TRTC.createClient({
- mode: "rtc",
- sdkAppId: parseInt(store.getters["rtc/sdkAppId"], 10),
- userId: store.getters["rtc/userId"],
- userSig: userSig.value,
- useStringRoomId: true,
- enableAutoPlayDialog: false,
- });
- installEventHandlers();
- await localClient.join({ roomId: store.getters["rtc/roomId"] });
- store.commit("rtc/setIsJoined", true);
- // inviteLink.value = store.commit("rtc/createShareLink");
- } catch (error) {
- console.error(error, "error-----------");
- }
- await createLocalStream();
- await handlePublish();
- localStream
- .play("local")
- .then(() => {
- // addLocalControlView();
- })
- .catch((e) => {
- console.log(stream);
- });
- localStream.on("error", (error) => {
- if (error.getCode() === 0x4043) {
- // 自动播放受限导致播放失败,此时引导用户点击页面。
- // 在点击事件的回调函数中,执行 stream.resume();
- Dialog.confirm({
- showCloseIcon: false,
- okText: "确定",
- content:
- "<span style='font-size: 16px; line-height: 1.5;'>在用户与网页产生交互(例如点击、触摸页面等)之前,网页将被禁止播放带有声音的媒体。点击恢复播放<span/>",
- title: "隐私条款:",
- single: true,
- func: (state) => {
- if (state == "ok") {
- localStream.resume();
- }
- },
- });
- }
- });
- }
- async function handlePublish() {
- if (!isJoined.value) {
- return;
- }
- if (isPublished.value) {
- return;
- }
- if (role.value != "leader") {
- return;
- }
- try {
- await localClient.publish(localStream);
- store.commit("rtc/setIsPublished", true);
- } catch (error) {
- console.error(error, "---------------handlePublish--------------------");
- }
- }
- async function handleStartShare() {
- shareClient = new ShareClient({
- sdkAppId: parseInt(store.getters["rtc/sdkAppId"], 10),
- userId: `share${store.getters["rtc/userId"]}`,
- roomId: store.getters["rtc/roomId"],
- secretKey: store.getters["rtc/secretKey"],
- useStringRoomId: true,
- });
- try {
- await shareClient.join();
- await shareClient.publish();
- console.log("Start share screen success");
- store.isShared = true;
- } catch (error) {
- console.error(`Start share error: ${error.message_}`);
- }
- }
- async function handleUnpublish() {
- if (!isJoined.value) {
- return;
- }
- if (!isPublished.value) {
- return;
- }
- try {
- await localClient.unpublish(localStream);
- store.commit("rtc/setIsPublished", false);
- } catch (error) {
- console.error(error, "-----------handleUnpublish--------------");
- }
- }
- async function handleLeave() {
- if (isPublished.value) {
- await handleUnpublish();
- }
- try {
- uninstallEventHandlers();
- await localClient.leave();
- localClient.destroy();
- localClient = null;
- invitedRemoteStreams.value.forEach((item) => {
- item.stop();
- });
- invitedRemoteStreams.value = [];
- store.commit("rtc/setVideoDeviceId", "");
- store.commit("rtc/setAudioDeviceId", "");
- if (localStream) {
- localStream.stop();
- localStream.close();
- localStream = null;
- console.log("有执行到这里-------------");
- }
- } catch (error) {
- console.error(error, "-----------handleLeave--------------");
- }
- }
- function installEventHandlers() {
- if (!localClient) {
- return;
- }
- localClient.on("error", handleError);
- localClient.on("client-banned", handleBanned);
- localClient.on("peer-join", handlePeerJoin);
- localClient.on("peer-leave", handlePeerLeave);
- localClient.on("stream-added", handleStreamAdded);
- localClient.on("stream-subscribed", handleStreamSubscribed);
- localClient.on("stream-removed", handleStreamRemoved);
- localClient.on("stream-updated", handleStreamUpdated);
- localClient.on("mute-video", handleMuteVideo);
- localClient.on("mute-audio", handleMuteAudio);
- localClient.on("unmute-video", handleUnmuteVideo);
- localClient.on("unmute-audio", handleUnmuteAudio);
- }
- function uninstallEventHandlers() {
- if (!localClient) {
- return;
- }
- localClient.off("error", handleError);
- localClient.off("error", handleError);
- localClient.off("client-banned", handleBanned);
- localClient.off("peer-join", handlePeerJoin);
- localClient.off("peer-leave", handlePeerLeave);
- localClient.off("stream-added", handleStreamAdded);
- localClient.off("stream-subscribed", handleStreamSubscribed);
- localClient.off("stream-removed", handleStreamRemoved);
- localClient.off("stream-updated", handleStreamUpdated);
- localClient.off("mute-video", handleMuteVideo);
- localClient.off("mute-audio", handleMuteAudio);
- localClient.off("unmute-video", handleUnmuteVideo);
- localClient.off("unmute-audio", handleUnmuteAudio);
- }
- function handleMuteVideo(event) {
- console.log(`[${event.userId}] mute video`);
- if (event.userId.indexOf("leader") > -1) {
- muteVideoLeader.value = true;
- }
- }
- function handleMuteAudio(event) {
- if (event.userId.indexOf("leader") > -1) {
- muteAudioLeader.value = true;
- }
- console.log(event, `[] mute audio`);
- }
- function handleUnmuteVideo(event) {
- console.log(`[${event.userId}] unmute video`);
- if (event.userId.indexOf("leader") > -1) {
- muteVideoLeader.value = false;
- }
- }
- function handleUnmuteAudio(event) {
- console.log(`[${event.userId}] unmute audio`);
- if (event.userId.indexOf("leader") > -1) {
- muteAudioLeader.value = false;
- }
- }
- function handleError(error) {
- console.log(`LocalClient error: ${error.message_}`);
- }
- function handleBanned(error) {
- console.log(`Client has been banned for ${error.message_}`);
- }
- function handlePeerJoin(event) {
- const { userId } = event;
- if (userId !== "local-screen") {
- console.log(`Peer Client [${userId}] joined`);
- }
- }
- function handlePeerLeave(event) {
- const { userId } = event;
- if (userId !== "local-screen") {
- console.log(`[${userId}] leave`);
- }
- }
- function handleStreamAdded(event) {
- const remoteStream = event.stream;
- const id = remoteStream.getId();
- const userId = remoteStream.getUserId();
- console.log(remoteStream, "-------------remoteStream");
- if (remoteStream.getUserId() === store.getters["rtc/userId"]) {
- // don't need to screen shared by us
- localClient.unsubscribe(remoteStream).catch((error) => {
- console.info(`unsubscribe failed: ${error.message_}`);
- });
- } else {
- console.log(
- `remote stream added: [${userId}] ID: ${id} type: ${remoteStream.getType()}`
- );
- localClient.subscribe(remoteStream).catch((error) => {
- console.info(`subscribe failed: ${error.message_}`);
- });
- }
- }
- async function handleStreamSubscribed(event) {
- const remoteStream = event.stream;
- if (remoteStream.userId_ == store.getters["rtc/userId"]) {
- return;
- }
- console.info(
- remoteStream.userId_,
- store.getters["rtc/userId"],
- "handleStreamSubscribedhandleStreamSubscribed.value"
- );
- if (
- !invitedRemoteStreams.value.some(
- (item) => item.userId_ == remoteStream.userId_
- )
- ) {
- invitedRemoteStreams.value.push(remoteStream);
- }
- console.log(invitedRemoteStreams.value, "invitedRemoteStreams.value");
- await nextTick();
- setTimeout(() => {
- console.log(remoteStream.userId_, "remoteStream.getId()");
- remoteStream
- .play(remoteStream.userId_)
- .then(() => {
- console.log(`RemoteStream play success`, 88888888888888888888);
- })
- .catch((error) => {
- console.log(`RemoteStream play failed: error: ${error.message_}`);
- });
- }, 100);
- // const remoteStream = event.stream;
- // const userId = remoteStream.getUserId();
- // console.log(`RemoteStream subscribed: [${userId}]`);
- }
- function handleStreamRemoved(event) {
- const remoteStream = event.stream;
- const userId = remoteStream.getUserId();
- console.log(`RemoteStream removed: [${userId}]`);
- }
- function handleStreamUpdated(event) {
- const remoteStream = event.stream;
- const userId = remoteStream.getUserId();
- console.log(
- `RemoteStream updated: [${userId}] audio:${remoteStream.hasAudio()} video:${remoteStream.hasVideo()}`
- );
- }
- let switchDevice = async ({ videoId, audioId }) => {
- console.log()
- if (!isJoined.value) {
- return;
- }
- if (videoId) {
- try {
- await localStream.switchDevice("video", videoId);
- } catch (error) {}
- }
- if (audioId) {
- try {
- await localStream.switchDevice("audio", audioId);
- } catch (error) {}
- }
- };
- onUnmounted(() => {
- handleLeave();
- });
- let canUseDevice = () => {
- console.log("可用");
- handleJoin();
- };
- </script>
- <style lang="scss" scoped>
- .trtccom {
- .local {
- width: 70px;
- height: 70px;
- position: fixed;
- z-index: 9999;
- top: 20px;
- left: 20px;
- border-radius: 50%;
- overflow: hidden;
- background: url(~@/assets/images/rtcLive/avatar_small@2x.png) center center
- no-repeat;
- }
- .videoBox {
- width: 72px;
- height: 72px;
- top: 19px;
- left: 19px;
- position: fixed;
- z-index: 99999;
- border-radius: 50%;
- overflow: hidden;
- .loadingTip {
- position: absolute;
- z-index: 101;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0;
- animation: Rotate 1.5s infinite;
- @keyframes Rotate {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(360deg);
- }
- }
- }
- > img {
- width: 100%;
- height: 100%;
- }
- }
- .micBox {
- width: 100%;
- height: 16px;
- background: rgba(0, 0, 0, 0.3);
- position: absolute;
- left: 0;
- bottom: 0;
- z-index: 100;
- display: flex;
- align-items: center;
- justify-content: center;
- .speak_mic {
- display: block;
- background-size: 720px auto;
- width: 12px;
- height: 12px;
- background-image: url(~@/assets/images/rtcLive/speed.png);
- // width: 0.69rem;
- // height: 0.69rem;
- animation: myAnimation 3s steps(59) infinite;
- }
- > img {
- width: 12px;
- }
- }
- .disabledlocal {
- opacity: 0 !important;
- visibility: hidden !important;
- }
- }
- @keyframes myAnimation {
- 0% {
- background-position: 0px 0px;
- }
- 100% {
- background-position: -708px 0px;
- }
- }
- </style>
|