lrf402788946 há 4 anos atrás
pai
commit
37457b6c69
4 ficheiros alterados com 271 adições e 3 exclusões
  1. 1 0
      package.json
  2. 2 0
      src/store/index.js
  3. 50 3
      src/views/teaching/live.vue
  4. 218 0
      src/views/teaching/liveCheck.vue

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
     "lodash": "^4.17.15",
     "moment": "^2.26.0",
     "naf-core": "^0.1.2",
+    "trtc-js-sdk": "^4.6.1",
     "vue": "^2.6.11",
     "vue-meta": "^2.3.2",
     "vue-router": "^3.1.5",

+ 2 - 0
src/store/index.js

@@ -23,6 +23,7 @@ import chatroom from '@frame/store/chatroom';
 import answerchat from '@frame/store/answerchat';
 import trainvideo from '@frame/store/trainvideo';
 import group from '@frame/store/group';
+import gensign from '@frame/store/gensign';
 import personalscore from '@frame/store/personalscore';
 import groupscore from '@frame/store/groupscore';
 import * as ustate from '@frame/store/user/state';
@@ -61,5 +62,6 @@ export default new Vuex.Store({
     group,
     personalscore,
     groupscore,
+    gensign,
   },
 });

+ 50 - 3
src/views/teaching/live.vue

@@ -13,7 +13,7 @@
           </el-col>
         </el-col>
         <el-col :span="24" class="live">
-          <el-col :span="24" class="liveInfo">
+          <el-col :span="24" class="liveInfo" id="liveScreen">
             直播
           </el-col>
         </el-col>
@@ -23,10 +23,12 @@
 </template>
 
 <script>
+import TRTC from 'trtc-js-sdk';
 import detailFrame from '@frame/layout/admin/detail-frame';
 import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions: subject } = createNamespacedHelpers('subject');
 const { mapActions: liveroom } = createNamespacedHelpers('liveroom');
+const { mapActions: gensign } = createNamespacedHelpers('gensign');
 export default {
   metaInfo: { title: '在线直播' },
   name: 'live',
@@ -40,15 +42,25 @@ export default {
       info: {},
       // 科目列表
       subjectList: [],
+      // 直播相关变量
+      sdkAppId: '1400414461',
+      client: null,
+      userMainId: '',
+      cameras: [],
+      microphones: [],
+      localStream_: [], //流
     };
   },
-  created() {
+  async created() {
     this.getOtherList();
     if (this.id) {
       this.search();
     }
+    await this.initclient();
+    await this.getDevices();
   },
   methods: {
+    ...gensign(['gensignFetch']),
     ...subject({ getSubjectList: 'query' }),
     ...liveroom(['fetch', 'create', 'update']),
     // 查詢詳情
@@ -80,7 +92,7 @@ export default {
             message: '开始直播',
             type: 'success',
           });
-          this.search();
+          this.toStart();
         }
       } else {
         let res = await this.update(data);
@@ -93,6 +105,41 @@ export default {
         }
       }
     },
+    // 初始化
+    async initclient() {
+      this.userMainId = 'mainr-' + this.user.userid;
+      const res = await this.gensignFetch({ userid: this.userMainId });
+      if (this.$checkRes(res)) {
+        this.client = await TRTC.createClient({
+          mode: 'live',
+          sdkAppId: this.sdkAppId,
+          userId: this.userMainId,
+          userSig:
+            'eJwtzTEPgjAQBeD-0lXFtl5pS*KgMhmjg6AOLtUWchIQgRCN8b9LgPG*l-fuS6Ld0WtdRQLCPUqm-Y3WFQ0m2HNusKhmIuE3KZ2Gu1loIzQFxazw9diobWbKEi0JGFAKDMBnQ*LeJVaucyEEp5QO2mDem1ZMUyH5uIJp9zAtTo8zbGMVrlQYqfUpzSIdTzaHV8t8eZ3nUkFtn59kf8mW5PcHFLs3aw__',
+        });
+      }
+    },
+    // 调用设备
+    async getDevices() {
+      this.cameras = await TRTC.getCameras();
+      this.microphones = await TRTC.getMicrophones();
+    },
+    // 开始直播
+    async toStart() {
+      await this.client.join({ roomId: 980890, role: 'anchor' });
+      this.localStream_ = await TRTC.createStream({
+        audio: true,
+        video: true,
+        cameraId: this.cameras[0].deviceId,
+        microphoneId: this.microphones[0].deviceId,
+        userId: this.userMainId,
+      });
+      this.localStream_.setVideoProfile('480p');
+      await this.localStream_.initialize();
+      console.log('initialize local stream success');
+      await this.client_.publish(this.localStream_);
+      this.localStream_.play('liveScreen');
+    },
   },
   computed: {
     ...mapState(['user']),

+ 218 - 0
src/views/teaching/liveCheck.vue

@@ -0,0 +1,218 @@
+<template>
+  <div id="livecheck">
+    <el-row id="test-content" class="container">
+      <div class="header">
+        <h2 class="title">WEBRTC 能力测试</h2>
+        <el-button class="btn btn-info btn-circle btn-xl" type="danger" size="mini" @click="checkstart">开始</el-button>
+      </div>
+      <div class="header">
+        <div id="main-video" class="video-box col-div" style="justify-content: flex-end"></div>
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: gensign } = createNamespacedHelpers('gensign');
+import TRTC from 'trtc-js-sdk';
+export default {
+  name: 'livecheck',
+  props: {},
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {
+    ...gensign(['gensignFetch']),
+    async checkstart() {
+      TRTC.checkSystemRequirements().then(result => {
+        if (!result) {
+          alert('Your browser is not compatible with TRTC');
+        }
+      });
+      await this.initclient();
+    },
+    async initclient() {
+      const userid_ = 'testlivecheck';
+      const res = await this.gensignFetch({ userid: userid_ });
+      if (this.$checkRes(res)) {
+        console.log(res.data);
+        const client_ = TRTC.createClient({
+          mode: 'live',
+          sdkAppId: '1400414461',
+          userId: userid_,
+          userSig: res.data,
+        });
+        await client_.join({ roomId: 9999, role: 'anchor' });
+        const localStream_ = await TRTC.createStream({
+          audio: true,
+          video: true,
+          userId: userid_,
+        });
+        localStream_.setVideoProfile('480p');
+        await localStream_.initialize();
+        await client_.publish(localStream_);
+        localStream_.play('main-video');
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+body {
+  /* padding: 50px; */
+  font: 14px 'Lucida Grande', Helvetica, Arial, sans-serif;
+}
+
+a {
+  color: #00b7ff;
+}
+
+.box {
+  width: 100%;
+  align-items: center;
+}
+.detail-box {
+  max-width: 640px;
+  width: 100%;
+  height: auto;
+  background: #e2e2e2;
+  margin-top: 2px;
+  font-family: Consolas;
+  font-size: 16px;
+  padding-top: 15px;
+  padding-left: 15px;
+  padding-bottom: 15px;
+  margin: auto;
+}
+#main-video {
+  width: 700px;
+  height: 500px;
+  grid-area: 1/1/3/4;
+  background-color: #000;
+}
+
+#test-content {
+  display: flex;
+  display: -webkit-flex;
+  align-items: center;
+  flex-direction: column;
+}
+
+.title {
+  width: 600px;
+  height: 70px;
+  color: white;
+  align-items: center;
+  display: flex;
+  padding-left: 20px;
+}
+.container {
+  padding: 0 !important;
+}
+.header {
+  display: flex;
+  flex-direction: row;
+  background: #4f7dc9;
+  max-width: 700px;
+  margin-bottom: 20px;
+  align-items: center;
+  width: 100%;
+  margin: auto;
+  padding: 0 10px;
+}
+.btn-circle {
+  width: 30px;
+  height: 30px;
+  text-align: center;
+  padding: 6px 0;
+  font-size: 12px;
+  line-height: 1.428571429;
+  border-radius: 15px;
+}
+.btn-circle.btn-lg {
+  width: 50px;
+  height: 50px;
+  padding: 10px 16px;
+  font-size: 18px;
+  line-height: 1.33;
+  border-radius: 25px;
+}
+.btn-circle.btn-xl {
+  width: 70px;
+  height: 70px;
+  padding: 10px 16px;
+  font-size: 24px;
+  line-height: 1.33;
+  border-radius: 35px;
+}
+
+#start-btn {
+  display: flex;
+  font-size: 20px;
+  color: black;
+  background: #99dd99;
+}
+
+#detail-info {
+  display: flex;
+  display: -webkit-flex;
+  -webkit-flex-direction: column;
+}
+
+.title {
+  color: black;
+  font-size: 20px;
+}
+
+#stunserver {
+}
+
+div#meters {
+  padding: 10px;
+}
+
+div#meters > div {
+  margin: 0 0 0 0;
+}
+
+div#meters div.label {
+  display: inline-block;
+  font-weight: 400;
+  margin: 0 0.5em 0 0;
+  width: 5em;
+  color: #000;
+}
+
+div#meters div.value {
+  display: inline-block;
+}
+
+meter {
+  width: 50%;
+}
+
+meter#clip {
+  color: #db4437;
+}
+
+meter#slow {
+  color: #f4b400;
+}
+
+meter#instant {
+  color: #0f9d58;
+}
+</style>