|
@@ -1,592 +0,0 @@
|
|
-<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>
|
|
|