roomDetail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <template>
  2. <div id="roomsDetail">
  3. <el-row>
  4. <el-col :span="24" class="video"> </el-col>
  5. </el-row>
  6. <van-overlay :show="show" style="{ height: oheight, width: '100%' }">
  7. <div id="transformid" class="wrapper" :style="{ transform: transform, height: vheight, width: vwidth, padding: vpadding, position: 'absolute' }">
  8. <div :style="{ height: lheight, width: lwidth }" id="look-video-left" class="video-box col-div look-video-left"></div>
  9. <div id="look-video-right" :style="{ height: rheight, width: rwidth }" class="video-box col-div look-video-right"></div>
  10. </div>
  11. <div class="videoBtn" id="videobtnid" :style="{ top: btop, right: bright }">
  12. <el-button type="warning" round @click="full()" size="mini"><i class="el-icon-rank"></i></el-button>
  13. </div>
  14. </van-overlay>
  15. <el-row>
  16. <el-col :span="24" class="info">
  17. <el-col :span="24" class="title">
  18. <span>{{ roomInfos.title }}</span>
  19. </el-col>
  20. <el-col :span="24" class="num">
  21. <span>观看:{{ total }}</span>
  22. </el-col>
  23. <el-col :span="24" class="advert">
  24. <el-col :span="24">
  25. <van-swipe :autoplay="3000">
  26. <van-swipe-item v-for="(advert, index) in roomInfos.adverts" :key="index">
  27. <img width="100%" height="100px" v-lazy="advert.imgdir" @click="imgclick(advert.imgurl)" />
  28. </van-swipe-item>
  29. </van-swipe>
  30. </el-col>
  31. </el-col>
  32. <el-col :span="24" class="chat">
  33. <el-col :span="24" class="chatInfo" id="chatSell">
  34. <el-col :span="24" class="list" v-for="(item, index) in dataList" :key="index">
  35. <p>
  36. <span :class="item.sendname == user.name ? 'selfColor' : ''">{{ item.sendname }}:</span>
  37. <span>{{ item.content }}</span>
  38. </p>
  39. </el-col>
  40. </el-col>
  41. <el-col :span="24" class="submit">
  42. <el-col :span="19" class="input">
  43. <el-input type="textarea" maxlength="5000" show-word-limit v-model="content"></el-input>
  44. </el-col>
  45. <el-col :span="5" class="btn">
  46. <el-button type="primary" size="mini" @click="chatCreate">发送</el-button>
  47. </el-col>
  48. </el-col>
  49. </el-col>
  50. </el-col>
  51. </el-row>
  52. </div>
  53. </template>
  54. <script>
  55. import TRTC from 'trtc-js-sdk';
  56. import { mapState, createNamespacedHelpers } from 'vuex';
  57. import Vue from 'vue';
  58. import { Swipe, SwipeItem, Lazyload } from 'vant';
  59. import { Image as VanImage } from 'vant';
  60. Vue.use(Swipe);
  61. Vue.use(SwipeItem);
  62. Vue.use(VanImage);
  63. Vue.use(Lazyload);
  64. const { mapActions: gensign } = createNamespacedHelpers('gensign');
  65. const { mapActions: room } = createNamespacedHelpers('room');
  66. const { mapActions: chat } = createNamespacedHelpers('chat');
  67. export default {
  68. name: 'roomsDetail',
  69. props: {},
  70. components: {},
  71. data: function() {
  72. return {
  73. client_: null,
  74. localStream_: null,
  75. sdkAppId_: '1400380125',
  76. userId_: '',
  77. roomInfos: {},
  78. sendmemo: '',
  79. total: 0,
  80. transform: 'rotate(0)',
  81. oheight: '200px',
  82. vwidth: '100%',
  83. vheight: '200px',
  84. rheight: '200px',
  85. rwidth: '30%',
  86. lheight: '200px',
  87. lwidth: '70%',
  88. show: true,
  89. vpadding: '0',
  90. btop: '167px',
  91. bright: '10px',
  92. isscreen: false,
  93. content: '',
  94. dataList: [],
  95. };
  96. },
  97. created() {
  98. this.initclient();
  99. this.lookuserSearch();
  100. this.lookusercountsel();
  101. this.chatSearch();
  102. },
  103. mounted() {
  104. this.channel();
  105. },
  106. methods: {
  107. ...gensign(['gensignFetch']),
  108. ...room(['lookuserFetch', 'fetch', 'lookusercount']),
  109. ...chat(['query', 'create']),
  110. async chatSearch({ skip = 0, limit = 1000 } = {}) {
  111. const info = { roomid: this.id };
  112. let res = await this.query({ skip, limit, ...info });
  113. this.$set(this, `dataList`, res.data);
  114. },
  115. async chatCreate() {
  116. let data = {};
  117. data.roomid = this.id;
  118. data.type = '0';
  119. data.content = this.content;
  120. data.sendid = this.user.uid;
  121. data.sendname = this.user.name;
  122. const res = await this.create(data);
  123. if (this.$checkRes(res)) {
  124. //this.$message('发送成功');
  125. this.content = '';
  126. }
  127. },
  128. channel() {
  129. console.log('in function:');
  130. this.$stomp({
  131. [`/exchange/public_chat_` + this.id]: this.onMessage,
  132. });
  133. },
  134. onMessage(message) {
  135. // console.log('receive a message: ', message.body);
  136. let body = _.get(message, 'body');
  137. if (body) {
  138. body = JSON.parse(body);
  139. this.dataList.push(body);
  140. this.content = '';
  141. }
  142. this.$nextTick(() => {
  143. document.getElementById('chatSell').scrollTop = document.getElementById('chatSell').scrollHeight + 275;
  144. });
  145. },
  146. async lookuserSearch() {
  147. let data = {};
  148. data.roomid = this.id;
  149. data.roomname = this.roomname;
  150. data.userid = this.user.userid;
  151. data.username = this.user.name;
  152. const res = await this.lookuserFetch(data);
  153. // 根据房间id查询房间详细信息
  154. let result = await this.fetch(this.id);
  155. if (this.$checkRes(result)) {
  156. console.log(result.data);
  157. this.$set(this, `roomInfos`, result.data);
  158. }
  159. },
  160. async lookusercountsel() {
  161. // 根据房间id查询房间详细信息
  162. let result = await this.lookusercount({ roomname: this.roomname });
  163. if (this.$checkRes(result)) {
  164. console.log(result.total);
  165. this.$set(this, `total`, result.total);
  166. }
  167. },
  168. onSubmit() {
  169. console.log(this.sendmemo);
  170. },
  171. async initclient() {
  172. this.userId_ = this.user.uid;
  173. const res = await this.gensignFetch({ userid: this.userId_ });
  174. if (this.$checkRes(res)) {
  175. this.client_ = TRTC.createClient({
  176. mode: 'live',
  177. sdkAppId: this.sdkAppId_,
  178. userId: this.userId_,
  179. userSig: res.data,
  180. });
  181. await this.client_.join({ roomId: this.roomname, role: 'audience' });
  182. this.client_.on('stream-subscribed', event => {
  183. const remoteStream = event.stream;
  184. // 远端流订阅成功,播放远端音视频流
  185. console.log(remoteStream);
  186. this.show = true;
  187. console.log('111' + remoteStream.getType());
  188. console.log('111' + remoteStream.getUserId());
  189. console.log('111' + remoteStream.getId());
  190. const userid_ = remoteStream.getUserId();
  191. const res_ = userid_.indexOf('-');
  192. if (res_ === -1) {
  193. this.rvideoid_ = 'video_' + remoteStream.getId();
  194. remoteStream
  195. .play('look-video-right')
  196. .then(() => {
  197. // autoplay success
  198. })
  199. .catch(e => {
  200. const errorCode = e.getCode();
  201. if (errorCode === 0x4043) {
  202. // PLAY_NOT_ALLOWED,引导用户手势操作恢复音视频播放
  203. remoteStream.resume();
  204. }
  205. });
  206. } else {
  207. this.lvideoid_ = 'video_' + remoteStream.getId();
  208. remoteStream
  209. .play('look-video-left')
  210. .then(() => {
  211. // autoplay success
  212. })
  213. .catch(e => {
  214. const errorCode = e.getCode();
  215. if (errorCode === 0x4043) {
  216. // PLAY_NOT_ALLOWED,引导用户手势操作恢复音视频播放
  217. remoteStream.resume();
  218. }
  219. });
  220. }
  221. });
  222. // 监听远端流增加事件
  223. this.client_.on('stream-added', event => {
  224. const remoteStream = event.stream;
  225. console.log('222' + remoteStream.getType());
  226. // 订阅远端音频和视频流
  227. this.client_.subscribe(remoteStream, { audio: true, video: true }).catch(e => {
  228. console.error('failed to subscribe remoteStream');
  229. });
  230. });
  231. this.client_.on('stream-removed', event => {
  232. const remoteStream = event.stream;
  233. console.log('stop----');
  234. remoteStream.stop();
  235. });
  236. }
  237. },
  238. imgclick(url) {
  239. location.href = url;
  240. },
  241. full() {
  242. this.show = true;
  243. const width = document.documentElement.clientWidth;
  244. const height = document.documentElement.clientHeight;
  245. if (!this.isscreen) {
  246. console.log('全屏');
  247. this.isscreen = true;
  248. this.oheight = height;
  249. const transformid_ = document.getElementById('transformid');
  250. let style = 'width:' + height + 'px;';
  251. style += 'height:' + width + 'px;';
  252. style += '-webkit-transform: rotate(90deg); transform: rotate(90deg);';
  253. // 注意旋转中点的处理
  254. style += '-webkit-transform-origin: ' + width / 2 + 'px ' + width / 2 + 'px;';
  255. style += 'transform-origin: ' + width / 2 + 'px ' + width / 2 + 'px;';
  256. transformid_.style.cssText = style;
  257. this.transform = 'rotate(90deg)';
  258. // this.vwidth = height;
  259. console.log(height);
  260. this.vheight = `${width}px`;
  261. this.vwidth = `${height}px`;
  262. this.lheight = `${width}px`;
  263. this.rheight = `${width}px`;
  264. this.btop = `${height - 40}px`;
  265. this.bright = `${width - 50}px`;
  266. } else {
  267. console.log('退出全屏');
  268. this.isscreen = false;
  269. this.oheight = '200px';
  270. const transformid_ = document.getElementById('transformid');
  271. let style = 'width:' + width + 'px;';
  272. style += 'height: 200px;';
  273. transformid_.style.cssText = style;
  274. this.transform = 'rotate(0deg)';
  275. // this.vwidth = height;
  276. console.log(height);
  277. this.vheight = `200px`;
  278. this.vwidth = `${width}px`;
  279. this.lheight = `200px`;
  280. this.rheight = `200px`;
  281. this.btop = `167px`;
  282. this.bright = `10px`;
  283. }
  284. },
  285. },
  286. computed: {
  287. ...mapState(['user']),
  288. id() {
  289. return this.$route.query.id;
  290. },
  291. roomname() {
  292. return this.$route.query.roomname;
  293. },
  294. pageTitle() {
  295. return `${this.$route.meta.title}`;
  296. },
  297. },
  298. metaInfo() {
  299. return { title: this.$route.meta.title };
  300. },
  301. };
  302. </script>
  303. <style lang="less" scoped>
  304. .video {
  305. top: 0;
  306. left: 0;
  307. width: 100%;
  308. height: 200px;
  309. }
  310. .info {
  311. .title {
  312. text-align: center;
  313. padding: 10px 0;
  314. font-size: 16px;
  315. font-weight: bold;
  316. }
  317. .num {
  318. padding: 10px 0;
  319. font-size: 16px;
  320. }
  321. .advert {
  322. background: #fff;
  323. padding: 10px;
  324. }
  325. .chat {
  326. height: 260px;
  327. .chatInfo {
  328. height: 185px;
  329. overflow-y: auto;
  330. padding: 0 10px;
  331. margin: 0 0 10px 0;
  332. .list {
  333. margin: 0 0 10px 0;
  334. span:first-child {
  335. float: left;
  336. width: 17%;
  337. text-align: center;
  338. overflow: hidden;
  339. text-overflow: ellipsis;
  340. white-space: nowrap;
  341. // font-weight: bold;
  342. }
  343. span:last-child {
  344. float: right;
  345. width: 82%;
  346. }
  347. }
  348. }
  349. .submit {
  350. position: absolute;
  351. bottom: 0;
  352. .el-button {
  353. width: 100%;
  354. padding: 20px 0;
  355. }
  356. }
  357. }
  358. }
  359. .my-swipe .van-swipe-item {
  360. color: #fff;
  361. font-size: 20px;
  362. line-height: 120px;
  363. text-align: center;
  364. background-color: #39a9ed;
  365. }
  366. /deep/.video-js {
  367. height: 190px !important;
  368. border-radius: 10px;
  369. }
  370. .look-video-left {
  371. float: left;
  372. background: #000;
  373. grid-area: 1/1/3/4;
  374. justify-content: flex-end;
  375. }
  376. .look-video-right {
  377. float: right;
  378. background: #000;
  379. grid-area: 1/1/3/4;
  380. justify-content: flex-end;
  381. }
  382. .wrapper {
  383. background: #000;
  384. position: absolute;
  385. width: 100%;
  386. }
  387. .van-overlay {
  388. position: fixed;
  389. top: 0;
  390. left: 0;
  391. z-index: 1;
  392. width: 100%;
  393. height: 200px;
  394. background-color: rgba(0, 0, 0, 0.7);
  395. }
  396. .videoBtn {
  397. z-index: 999;
  398. position: absolute;
  399. }
  400. </style>