detailInfo copy.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <template>
  2. <div id="detailInfo">
  3. <el-row>
  4. <el-col :span="24" class="info">
  5. <el-col :span="14" class="left">
  6. <el-col :span="24" class="top">
  7. <el-col :span="4" class="image">
  8. <el-image :src="roomInfo.filedir"></el-image>
  9. </el-col>
  10. <el-col :span="20" class="title">
  11. <p class="one">
  12. <span>{{ roomInfo.title }}</span>
  13. <span>房间号:{{ roomInfo.name }}</span>
  14. </p>
  15. <div class="two">
  16. <el-col :span="16" class="select">
  17. <el-select v-model="cameraId" filterable placeholder="请选择摄像头">
  18. <el-option v-for="item in cameras" :key="item.deviceId" :label="item.label" :value="item.deviceId"> </el-option>
  19. </el-select>
  20. <el-select v-model="microphoneId" filterable placeholder="请选择麦克风">
  21. <el-option v-for="item in microphones" :key="item.deviceId" :label="item.label" :value="item.deviceId"> </el-option>
  22. </el-select>
  23. </el-col>
  24. <el-col :span="8" class="btn">
  25. <span @click="shareon"><i class="iconfont iconfenxiang"></i>分享</span>
  26. <span @click="liveon"><i class="iconfont iconshexiangtou"></i>摄像头</span>
  27. <span @click="liveclose">关闭</span>
  28. </el-col>
  29. </div>
  30. </el-col>
  31. </el-col>
  32. <el-col :span="24" class="video">
  33. <div id="main-video" class="video-box col-div" style="justify-content: flex-end"></div>
  34. </el-col>
  35. </el-col>
  36. <el-col :span="10" class="right">
  37. <el-col :span="24" class="chat">
  38. 聊天页面
  39. </el-col>
  40. </el-col>
  41. </el-col>
  42. </el-row>
  43. </div>
  44. </template>
  45. <script>
  46. import { mapState, createNamespacedHelpers } from 'vuex';
  47. const { mapActions: gensign } = createNamespacedHelpers('gensign');
  48. import TRTC from 'trtc-js-sdk';
  49. export default {
  50. name: 'detailInfo',
  51. props: {
  52. roomInfo: null,
  53. },
  54. components: {},
  55. data: function() {
  56. return {
  57. client_: '',
  58. localStream_: '',
  59. sdkAppId_: '1400380125',
  60. cameras: [],
  61. microphones: [],
  62. cameraId: '',
  63. microphoneId: '',
  64. userId_: '1111',
  65. open_: false,
  66. };
  67. },
  68. created() {
  69. this.initclient();
  70. this.getDevices();
  71. },
  72. methods: {
  73. ...gensign(['gensignFetch']),
  74. async getDevices() {
  75. this.cameras = await TRTC.getCameras();
  76. this.microphones = await TRTC.getMicrophones();
  77. },
  78. async initclient() {
  79. console.log(this.user.uid);
  80. this.userId_ = this.user.uid;
  81. const res = await this.gensignFetch({ userid: this.userId_ });
  82. if (this.$checkRes(res)) {
  83. console.log(res.data);
  84. this.client_ = TRTC.createClient({
  85. mode: 'live',
  86. sdkAppId: this.sdkAppId_,
  87. userId: this.userId_,
  88. userSig: res.data,
  89. });
  90. }
  91. },
  92. async liveon() {
  93. this.open_ = true;
  94. console.log('8888--' + this.userId_);
  95. if (this.cameraId === '' || this.microphoneId === '') {
  96. this.$message({
  97. message: '请选择摄像头和麦克风',
  98. type: 'warning',
  99. });
  100. return;
  101. }
  102. await this.client_.join({ roomId: this.name, role: 'anchor' });
  103. this.localStream_ = await TRTC.createStream({
  104. audio: true,
  105. video: true,
  106. cameraId: this.cameraId,
  107. microphoneId: this.microphoneId,
  108. userId: this.userId_,
  109. });
  110. await this.localStream_.initialize();
  111. console.log('initialize local stream success');
  112. // publish the local stream
  113. await this.client_.publish(this.localStream_);
  114. this.localStream_.play('main-video');
  115. //$('#mask_main').appendTo($('#player_' + this.localStream_.getId()));
  116. },
  117. async shareon() {
  118. const shareId = 'share-' + this.userId_;
  119. const res = await this.gensignFetch({ userid: shareId });
  120. if (this.$checkRes(res)) {
  121. const shareClient = TRTC.createClient({
  122. mode: 'videoCall',
  123. sdkAppId: this.sdkAppId_,
  124. userId: shareId,
  125. userSig: res.data,
  126. });
  127. shareClient.setDefaultMuteRemoteStreams(true);
  128. await shareClient.join({ roomId: this.name });
  129. const localStream = TRTC.createStream({ audio: false, screen: true });
  130. await localStream.initialize();
  131. console.log('initialize share stream success');
  132. await shareClient.publish(localStream);
  133. this.client_.on('stream-added', event => {
  134. const remoteStream = event.stream;
  135. const remoteUserId = remoteStream.getUserId();
  136. if (remoteUserId === shareId) {
  137. // 取消订阅自己的屏幕分享流
  138. this.client_.unsubscribe(remoteStream);
  139. } else {
  140. // 订阅其他一般远端流
  141. this.client_.subscribe(remoteStream);
  142. }
  143. });
  144. }
  145. },
  146. async liveclose() {
  147. // 关闭视频通话
  148. console.log(this.open_);
  149. if (this.open_) {
  150. const videoTrack = this.localStream_.getVideoTrack();
  151. if (videoTrack) {
  152. this.localStream_.removeTrack(videoTrack).then(() => {
  153. console.log('remove video call success');
  154. // 关闭摄像头
  155. videoTrack.stop();
  156. this.client_.unpublish(localStream).then(() => {
  157. // 取消发布本地流成功
  158. });
  159. });
  160. }
  161. }
  162. },
  163. },
  164. computed: {
  165. ...mapState(['user']),
  166. id() {
  167. return this.$route.query.id;
  168. },
  169. name() {
  170. return this.$route.query.name;
  171. },
  172. pageTitle() {
  173. return `${this.$route.meta.title}`;
  174. },
  175. },
  176. metaInfo() {
  177. return { title: this.$route.meta.title };
  178. },
  179. };
  180. </script>
  181. <style lang="less" scoped>
  182. .info {
  183. border-style: double;
  184. border-color: #ff0000 #00ff00 #0000ff rgb(250, 0, 255);
  185. padding: 20px;
  186. .left {
  187. background-color: #f5f5f5;
  188. min-height: 800px;
  189. border: 1px solid blueviolet;
  190. .top {
  191. position: relative;
  192. border: 1px solid red;
  193. padding: 10px;
  194. .image {
  195. text-align: center;
  196. .el-image {
  197. width: 80px;
  198. height: 80px;
  199. border-radius: 90px;
  200. }
  201. }
  202. .title {
  203. .one {
  204. padding: 0 0 10px 0;
  205. span {
  206. display: inline-block;
  207. width: 50%;
  208. }
  209. span:last-child {
  210. text-align: right;
  211. }
  212. }
  213. .two {
  214. position: absolute;
  215. right: 10px;
  216. bottom: 10px;
  217. .select {
  218. .el-select {
  219. float: left;
  220. width: 47%;
  221. margin: 0 10px 0 0;
  222. }
  223. }
  224. .btn {
  225. height: 40px;
  226. line-height: 40px;
  227. text-align: right;
  228. span {
  229. margin: 0 10px 0 0;
  230. }
  231. span:last-child {
  232. margin: 0;
  233. }
  234. span:hover {
  235. cursor: pointer;
  236. }
  237. }
  238. }
  239. }
  240. }
  241. }
  242. .right {
  243. width: 39%;
  244. min-height: 800px;
  245. border: 1px solid cyan;
  246. margin: 0 0 0 20px;
  247. }
  248. #main-video {
  249. float: left;
  250. width: 100%;
  251. height: 600px;
  252. min-height: 600px;
  253. grid-area: 1/1/3/4;
  254. }
  255. }
  256. </style>