|
@@ -0,0 +1,258 @@
|
|
|
+<template>
|
|
|
+ <div id="detailInfo">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="24" class="info">
|
|
|
+ <el-col :span="14" class="left">
|
|
|
+ <el-col :span="24" class="top">
|
|
|
+ <el-col :span="4" class="image">
|
|
|
+ <el-image :src="roomInfo.filedir"></el-image>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="20" class="title">
|
|
|
+ <p class="one">
|
|
|
+ <span>{{ roomInfo.title }}</span>
|
|
|
+ <span>房间号:{{ roomInfo.name }}</span>
|
|
|
+ </p>
|
|
|
+ <div class="two">
|
|
|
+ <el-col :span="16" class="select">
|
|
|
+ <el-select v-model="cameraId" filterable placeholder="请选择摄像头">
|
|
|
+ <el-option v-for="item in cameras" :key="item.deviceId" :label="item.label" :value="item.deviceId"> </el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-select v-model="microphoneId" filterable placeholder="请选择麦克风">
|
|
|
+ <el-option v-for="item in microphones" :key="item.deviceId" :label="item.label" :value="item.deviceId"> </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8" class="btn">
|
|
|
+ <span @click="shareon"><i class="iconfont iconfenxiang"></i>分享</span>
|
|
|
+ <span @click="liveon"><i class="iconfont iconshexiangtou"></i>摄像头</span>
|
|
|
+ <span @click="liveclose">关闭</span>
|
|
|
+ </el-col>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="24" class="video">
|
|
|
+ <div id="main-video" class="video-box col-div" style="justify-content: flex-end"></div>
|
|
|
+ </el-col>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10" class="right">
|
|
|
+ <el-col :span="24" class="chat">
|
|
|
+ 聊天页面
|
|
|
+ </el-col>
|
|
|
+ </el-col>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapState, createNamespacedHelpers } from 'vuex';
|
|
|
+const { mapActions: gensign } = createNamespacedHelpers('gensign');
|
|
|
+import TRTC from 'trtc-js-sdk';
|
|
|
+export default {
|
|
|
+ name: 'detailInfo',
|
|
|
+ props: {
|
|
|
+ roomInfo: null,
|
|
|
+ },
|
|
|
+ components: {},
|
|
|
+ data: function() {
|
|
|
+ return {
|
|
|
+ client_: '',
|
|
|
+ localStream_: '',
|
|
|
+ sdkAppId_: '1400380125',
|
|
|
+ cameras: [],
|
|
|
+ microphones: [],
|
|
|
+ cameraId: '',
|
|
|
+ microphoneId: '',
|
|
|
+ userId_: '1111',
|
|
|
+ open_: false,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.initclient();
|
|
|
+ this.getDevices();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ ...gensign(['gensignFetch']),
|
|
|
+ async getDevices() {
|
|
|
+ this.cameras = await TRTC.getCameras();
|
|
|
+ this.microphones = await TRTC.getMicrophones();
|
|
|
+ },
|
|
|
+ async initclient() {
|
|
|
+ console.log(this.user.uid);
|
|
|
+ this.userId_ = this.user.uid;
|
|
|
+ const res = await this.gensignFetch({ userid: this.userId_ });
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ console.log(res.data);
|
|
|
+ this.client_ = TRTC.createClient({
|
|
|
+ mode: 'live',
|
|
|
+ sdkAppId: this.sdkAppId_,
|
|
|
+ userId: this.userId_,
|
|
|
+ userSig: res.data,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async liveon() {
|
|
|
+ this.open_ = true;
|
|
|
+ console.log('8888--' + this.userId_);
|
|
|
+ if (this.cameraId === '' || this.microphoneId === '') {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择摄像头和麦克风',
|
|
|
+ type: 'warning',
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ await this.client_.join({ roomId: this.name, role: 'anchor' });
|
|
|
+ this.localStream_ = await TRTC.createStream({
|
|
|
+ audio: true,
|
|
|
+ video: true,
|
|
|
+ cameraId: this.cameraId,
|
|
|
+ microphoneId: this.microphoneId,
|
|
|
+ userId: this.userId_,
|
|
|
+ });
|
|
|
+ await this.localStream_.initialize();
|
|
|
+ console.log('initialize local stream success');
|
|
|
+ // publish the local stream
|
|
|
+ await this.client_.publish(this.localStream_);
|
|
|
+ this.localStream_.play('main-video');
|
|
|
+ //$('#mask_main').appendTo($('#player_' + this.localStream_.getId()));
|
|
|
+ },
|
|
|
+ async shareon() {
|
|
|
+ const shareId = 'share-' + this.userId_;
|
|
|
+ const res = await this.gensignFetch({ userid: shareId });
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ const shareClient = TRTC.createClient({
|
|
|
+ mode: 'videoCall',
|
|
|
+ sdkAppId: this.sdkAppId_,
|
|
|
+ userId: shareId,
|
|
|
+ userSig: res.data,
|
|
|
+ });
|
|
|
+ shareClient.setDefaultMuteRemoteStreams(true);
|
|
|
+ await shareClient.join({ roomId: this.name });
|
|
|
+ const localStream = TRTC.createStream({ audio: false, screen: true });
|
|
|
+ await localStream.initialize();
|
|
|
+ console.log('initialize share stream success');
|
|
|
+ await shareClient.publish(localStream);
|
|
|
+ this.client_.on('stream-added', event => {
|
|
|
+ const remoteStream = event.stream;
|
|
|
+ const remoteUserId = remoteStream.getUserId();
|
|
|
+ if (remoteUserId === shareId) {
|
|
|
+ // 取消订阅自己的屏幕分享流
|
|
|
+ this.client_.unsubscribe(remoteStream);
|
|
|
+ } else {
|
|
|
+ // 订阅其他一般远端流
|
|
|
+ this.client_.subscribe(remoteStream);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async liveclose() {
|
|
|
+ // 关闭视频通话
|
|
|
+ console.log(this.open_);
|
|
|
+ if (this.open_) {
|
|
|
+ const videoTrack = this.localStream_.getVideoTrack();
|
|
|
+ if (videoTrack) {
|
|
|
+ this.localStream_.removeTrack(videoTrack).then(() => {
|
|
|
+ console.log('remove video call success');
|
|
|
+ // 关闭摄像头
|
|
|
+ videoTrack.stop();
|
|
|
+ this.client_.unpublish(localStream).then(() => {
|
|
|
+ // 取消发布本地流成功
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['user']),
|
|
|
+ id() {
|
|
|
+ return this.$route.query.id;
|
|
|
+ },
|
|
|
+ name() {
|
|
|
+ return this.$route.query.name;
|
|
|
+ },
|
|
|
+ pageTitle() {
|
|
|
+ return `${this.$route.meta.title}`;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ metaInfo() {
|
|
|
+ return { title: this.$route.meta.title };
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.info {
|
|
|
+ border-style: double;
|
|
|
+ border-color: #ff0000 #00ff00 #0000ff rgb(250, 0, 255);
|
|
|
+ padding: 20px;
|
|
|
+ .left {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ min-height: 800px;
|
|
|
+ border: 1px solid blueviolet;
|
|
|
+ .top {
|
|
|
+ position: relative;
|
|
|
+ border: 1px solid red;
|
|
|
+ padding: 10px;
|
|
|
+ .image {
|
|
|
+ text-align: center;
|
|
|
+ .el-image {
|
|
|
+ width: 80px;
|
|
|
+ height: 80px;
|
|
|
+ border-radius: 90px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .title {
|
|
|
+ .one {
|
|
|
+ padding: 0 0 10px 0;
|
|
|
+ span {
|
|
|
+ display: inline-block;
|
|
|
+ width: 50%;
|
|
|
+ }
|
|
|
+ span:last-child {
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .two {
|
|
|
+ position: absolute;
|
|
|
+ right: 10px;
|
|
|
+ bottom: 10px;
|
|
|
+ .select {
|
|
|
+ .el-select {
|
|
|
+ float: left;
|
|
|
+ width: 47%;
|
|
|
+ margin: 0 10px 0 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .btn {
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ text-align: right;
|
|
|
+ span {
|
|
|
+ margin: 0 10px 0 0;
|
|
|
+ }
|
|
|
+ span:last-child {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ span:hover {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .right {
|
|
|
+ width: 39%;
|
|
|
+ min-height: 800px;
|
|
|
+ border: 1px solid cyan;
|
|
|
+ margin: 0 0 0 20px;
|
|
|
+ }
|
|
|
+ #main-video {
|
|
|
+ float: left;
|
|
|
+ width: 100%;
|
|
|
+ height: 600px;
|
|
|
+ min-height: 600px;
|
|
|
+ grid-area: 1/1/3/4;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|