live-detail.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. <!-- 直播间 -->
  2. <template>
  3. <view class="detail live-detail">
  4. <div class="body">
  5. <detailHeader :roomInfo="roomInfo" v-if="roomInfo.title"></detailHeader>
  6. <div v-html="inputHtml"></div>
  7. <div class="no-live" v-if="!liveSign">
  8. <detailFollow :matchDetail="matchDetail" :roomInfo="roomInfo" @success="getLiveDetail1" :userInfo="userInfo"></detailFollow>
  9. <div class="down-box" v-if="roomInfo.down > 0 && roomInfo.islive == 0">
  10. <div>
  11. <div>
  12. <!-- Match starts in -->
  13. {{ $t("match.lab76") }}
  14. </div>
  15. <div class="down">
  16. {{ countdownFun(roomInfo.down / 1000) }}
  17. </div>
  18. </div>
  19. </div>
  20. <img :src="roomInfo.thumb" width="100%" style="display:block" />
  21. <!-- <image class="home_logo" v-if="roomInfo.home_logo && roomInfo.away_logo" :src="roomInfo.home_logo" mode="aspectFill" alt=""></image> -->
  22. <!-- <image class="away_logo" v-if="roomInfo.home_logo && roomInfo.away_logo" :src="roomInfo.away_logo" mode="aspectFill" alt=""></image> -->
  23. </div>
  24. <view v-else class="video" @click="play(1)">
  25. <view class="" style="z-index: 9997">
  26. <lff-barrage
  27. ref="lffBarrage"
  28. :maxTop="240"
  29. type="leftToRight"
  30. ></lff-barrage>
  31. <lff-barrage ref="lffBarrage2"></lff-barrage>
  32. </view>
  33. <view class="thumb video-js" ref="video" id="player-con">
  34. <detailDownload @cancel="downloadTimerFun" v-if="downloadShow"></detailDownload>
  35. <view class="video-mask" v-if="videoMask">
  36. <detailFollow v-if="!isFullScreen" :matchDetail="matchDetail" :roomInfo="roomInfo" @success="getLiveDetail1" :userInfo="userInfo"></detailFollow>
  37. <!-- <view class="top font24" @click="setting(5)">
  38. {{ qualityIndex[qualityIndex] || "quality" }}
  39. </view> -->
  40. <div class="ranking-box" @click="screenMatchShow = true" v-if="isFullScreen && roomInfo.match_id">
  41. <img class="ranking" src="/static/image/live/ranking.png" alt="">
  42. </div>
  43. <view class="foot flex-end" :class="{'full': isFullScreen}">
  44. <image
  45. src="/static/image/live/reset.png"
  46. mode=""
  47. @click="setting(1)"
  48. ></image>
  49. <screenChat :messageList="messageList" v-if="isFullScreen" :giftList="giftList" @addMesg="addMesg" :roomInfo="roomInfo" ref="detail1" :userInfo="userInfo"></screenChat>
  50. <image
  51. style="width: 78rpx"
  52. :src="
  53. danmu
  54. ? '/static/image/live/danmu.png'
  55. : '/static/image/live/danm-false.png'
  56. "
  57. @click="setting(2)"
  58. mode=""
  59. ></image>
  60. <u-icon v-if="isVolume" @click="play(2)" name="volume" color="#fff" size="36rpx"></u-icon>
  61. <u-icon v-else @click="play(2)" name="volume-off" color="#fff" size="36rpx"></u-icon>
  62. <!-- <image src="/static/image/live/danmu.png" mode=""></image> -->
  63. <!-- <image src="/static/image/live/set.png" mode="" @click="setting(3)"></image> -->
  64. <image
  65. src="/static/image/live/quanping.png"
  66. mode=""
  67. @click="setting(4)"
  68. ></image>
  69. </view>
  70. </view>
  71. <div class="screen-match" v-if="screenMatchShow && isFullScreen">
  72. <screenMatch @cancel="screenMatchShow = false" :list="competition_list" :matchDetail="matchDetail" :livePath="matchDetail.live_path"></screenMatch>
  73. </div>
  74. <!-- 设置画质 -->
  75. <view class="quality-mask" v-if="isQuality">
  76. <view class="quality-nav">
  77. <view class="quality-del flex-end" @click="isQuality = false">
  78. <image src="/static/image/live/del.png" mode=""></image>
  79. </view>
  80. <view class="quality-title font32">
  81. {{ $t("live.definition") }}
  82. </view>
  83. <view class="quality-list flex">
  84. <view
  85. class=""
  86. v-for="(item, index) in qualityArr"
  87. :key="index"
  88. @click="setting(6, index)"
  89. >
  90. {{ item.name }}
  91. </view>
  92. </view>
  93. </view>
  94. </view>
  95. </view>
  96. <image
  97. class="thumb"
  98. v-if="roomInfo && !videoPlay"
  99. :src="roomInfo.thumb"
  100. mode="aspectFill"
  101. ></image>
  102. </view>
  103. <div class="adver-box">
  104. <img class="ad" v-if="roomInfo.adver_img_one" @click="adClick(roomInfo)" :src="roomInfo.adver_img_one" alt="">
  105. <img class="qr_img" v-if="roomInfo.qr_img" @click.stop="adClick1(roomInfo)" :src="roomInfo.qr_img" alt="">
  106. </div>
  107. <view class="tabs" v-if="liveType != 'game'">
  108. <u-tabs
  109. :list="tabList"
  110. lineHeight="3px"
  111. lineWidth="35px"
  112. lineColor="#DC3C23"
  113. :scrollable="true"
  114. :activeStyle="{
  115. color: '#DC3C23',
  116. fontSize: '15px',
  117. fontWeight: '700',
  118. }"
  119. :itemStyle="{height: '40px'}"
  120. :inactiveStyle="{ color: '#000', fontSize: '15px' }"
  121. :current="current"
  122. @change="change"
  123. >
  124. </u-tabs>
  125. </view>
  126. </div>
  127. <detailList v-if="current == 0" :liveList="liveList"/>
  128. <detailChat :liveType="liveType" @uodateMsg="uodateMsg" v-show="current == 1" :giftList="giftList" @addMesg="addMesg" :roomInfo="roomInfo" ref="detail1" :userInfo="userInfo"/>
  129. <!-- <detailAnimation v-if="current == 2" :livePath="matchDetail.live_path" /> -->
  130. <detailLive v-if="current == 2" :matchDetail="matchDetail" />
  131. <detailInfo v-if="current == 3" :matchDetail="matchDetail" />
  132. <detailScorecard v-if="current == 4" :list="competition_list" :matchDetail="matchDetail" />
  133. <detailSquad v-if="current == 5" :matchDetail="matchDetail" />
  134. </view>
  135. </template>
  136. <script>
  137. import detailInfo from './compontent/detail-info.vue'
  138. import detailChat from './compontent/detail-chat.vue'
  139. import detailAnimation from './compontent/detail-animation.vue'
  140. import detailList from './compontent/detail-list.vue'
  141. import detailLive from './compontent/detail-live.vue'
  142. import detailScorecard from './compontent/detail-scorecard.vue'
  143. import detailSquad from './compontent/detail-squad.vue'
  144. import screenChat from './compontent/screen-chat.vue'
  145. import screenMatch from './compontent/screen-match.vue'
  146. import bus from '@/utils/bus'
  147. import detailHeader from './compontent/detail-header.vue'
  148. import detailFollow from './compontent/detail-follow.vue'
  149. import detailDownload from './compontent/detail-download.vue'
  150. export default {
  151. components: {
  152. detailHeader,
  153. detailFollow,
  154. detailInfo,
  155. detailChat,
  156. detailList,
  157. detailLive,
  158. detailScorecard,
  159. detailSquad,
  160. detailAnimation,
  161. screenChat,
  162. screenMatch,
  163. detailDownload
  164. },
  165. data() {
  166. return {
  167. nativeShare: null,
  168. videoMask: false,
  169. timer: null, //定时器
  170. i: 0, //计数
  171. show: false,
  172. quality: ["540", "720", "1080"],
  173. bg: {
  174. backgroundColor: "transparent",
  175. },
  176. tabList: [
  177. {
  178. name: this.$t("live.detailTab1"),
  179. },
  180. {
  181. name: this.$t("live.detailTab2"),
  182. },
  183. // {
  184. // name: this.$t('live.lab39'),
  185. // },
  186. {
  187. name: this.$t("live.detailTab3"),
  188. },
  189. {
  190. name: this.$t("live.detailTab4"),
  191. },
  192. {
  193. name: this.$t("live.detailTab5"),
  194. },
  195. {
  196. name: this.$t("live.detailTab6"),
  197. },
  198. ],
  199. groupID: "",
  200. id: '',
  201. roomInfo: {},
  202. matchDetail: {},
  203. competition_list: [],
  204. player: null,
  205. current: 1,
  206. userInfo: {},
  207. giftList: [],
  208. isPlay: false,
  209. isVolume: true, //是否播放声音
  210. videoBar: false,
  211. videoPlay: true,
  212. isQuality: false,
  213. isFullScreen: false,
  214. screenMatchShow: false,
  215. qualityIndex: 0,
  216. qualityArr: [], //画质数组
  217. quality: [], //画质
  218. setType: 0,
  219. liveList: [],
  220. liveType: '',
  221. danmu: true,
  222. time1: null,
  223. downTimer: null,
  224. liveSign: true,
  225. userClick: false,
  226. downloadShow: false,
  227. downloadTimer: null,
  228. messageList: [],
  229. inputHtml: '<input type="text" id="copy-input" style="opacity: 0;position: fixed;top: 0;z-index: -1;" readonly="readonly">'
  230. };
  231. },
  232. onLoad(option) {
  233. this.id = option.ID;
  234. // this.getUserGiftList()
  235. this.liveType = option.type
  236. if (this.liveType != 'game') {
  237. this.getList();
  238. }
  239. this.$store.state.timMessage = [];
  240. // let watchingOutSign = localStorage.getItem('watchingOutSign')
  241. // if (watchingOutSign && this.isLogin != 1) {
  242. // this.$r.loginBox();
  243. // this.$store.state.loginShowSign = true;
  244. // this.$store.state.loginShowCloseSign = false;
  245. // } else {
  246. this.getIsLogin();
  247. // }
  248. },
  249. deactivated() {
  250. this.isFullScreen = false
  251. },
  252. onUnload() {
  253. bus.$off('chatLogin')
  254. // this.player = null
  255. this.time1 && clearInterval(this.time1);
  256. this.downTimer && clearInterval(this.downTimer);
  257. this.downloadTimer && clearTimeout(this.downloadTimer);
  258. window.removeEventListener('touchstart', this.owerPlay1)
  259. this.player && this.player.dispose();
  260. /* 退出群组 */
  261. this.time1 = null;
  262. this.downTimer = null;
  263. // this.$store.dispatch('quitGroup',{groupID:this.groupID})
  264. uni.$TUIKit
  265. .quitGroup(this.groupID)
  266. .then((imResponse) => {})
  267. .catch((imError) => {
  268. console.warn("joinGroup error:", imError); // 申请加群失败的相关信息
  269. });
  270. },
  271. onShow() {
  272. },
  273. onHide() {
  274. // this.player = null
  275. // this.player.dispose();
  276. },
  277. mounted() {
  278. this.downloadTimerFun()
  279. this.getLiveDetail();
  280. window.addEventListener('touchstart', this.owerPlay1)
  281. document.getElementById('palyevent').addEventListener('click',this.owerPlay)
  282. },
  283. computed: {
  284. infos() {
  285. return this.$store.state.info;
  286. },
  287. isLogin() {
  288. return this.$store.state.isLogin;
  289. },
  290. system() {
  291. return this.$store.state.system;
  292. },
  293. },
  294. methods: {
  295. videoInit(data) {
  296. var $this = this
  297. this.player = new Aliplayer(
  298. {
  299. id: "player-con",
  300. source: data.pull || 'https://ss247.life/demoapi/Nstreamapi.php?chid=1029&ip=113.89.8.22',
  301. // source: 'https://crm.wisex.io/video/5.mp4',
  302. width: "100%",
  303. height: "100%",
  304. autoplay: true,
  305. isLive: true,
  306. rePlay: true,
  307. showBarTime: '3000',
  308. // cover: data.thumb,
  309. videoHeight: "100%",
  310. keyShortCuts: true,
  311. playsinline: true,
  312. "language": "en-us",
  313. preload: true,
  314. controlBarVisibility: "hover",
  315. videoWidth: "100%",
  316. useH5Prism: true,
  317. skinLayout: [
  318. // {
  319. // name: "bigPlayButton",
  320. // align: "blabs",
  321. // x: 30,
  322. // y: 80,
  323. // },
  324. {
  325. name: "H5Loading",
  326. align: "cc",
  327. },
  328. {
  329. name: "errorDisplay",
  330. align: "tlabs",
  331. x: 0,
  332. y: 0,
  333. },
  334. {
  335. name: "infoDisplay",
  336. },
  337. {
  338. name: "tooltip",
  339. align: "blabs",
  340. x: 0,
  341. y: 56,
  342. },
  343. {
  344. name: "thumbnail",
  345. },
  346. ],
  347. },
  348. function (player) {
  349. setTimeout(() => {
  350. $this.clickPlay()
  351. }, 1000)
  352. }
  353. );
  354. this.player.on('requestFullScreen', () => {
  355. this.isFullScreen = true
  356. })
  357. this.player.on('cancelFullScreen', () => {
  358. this.isFullScreen = false
  359. })
  360. },
  361. getLiveDetail1() {
  362. uni.$u.http.post("/api/Live_streaming/getRoomInfo", {
  363. id: this.id,
  364. }).then(res => {
  365. this.roomInfo = res.info || {};
  366. if (this.roomInfo.islive == 0) {
  367. this.getDown()
  368. }
  369. this.userInfo = res.userData;
  370. })
  371. },
  372. /* 获取详情 */
  373. cricket_match_detail() {
  374. let time = new Date();
  375. let timeZone = time.toLocaleTimeString('en-us',{timeZoneName:'short'}); //'1:12:38 PM GMT+8'
  376. let timeZoneId = Intl.DateTimeFormat().resolvedOptions().timeZone; //'Asia/Shanghai'
  377. uni.$u.http.post('/api/Cricket/cricket_match_detail',{
  378. match_id: this.roomInfo.match_id,
  379. // match_id: 39497509,
  380. timezone:timeZoneId
  381. }).then(res=>{
  382. this.matchDetail = res;
  383. this.competition_list = res.competition_list || []
  384. }).catch(res=>{})
  385. },
  386. /* 发布弹幕 */
  387. addMesg(e) {
  388. if (!this.$refs.lffBarrage) {
  389. return
  390. }
  391. this.$refs.lffBarrage.add({
  392. item: e,
  393. });
  394. this.$refs.lffBarrage2.add({
  395. item: e,
  396. });
  397. },
  398. /* 获取直播 */
  399. getList() {
  400. // 全部赛事
  401. // uni.$u.http.post('/api/hot_match/all_match', {}).then(res => {
  402. // this.bannerList = res.data
  403. // })
  404. // 正在直播
  405. uni.$u.http.get("/api/live_streaming/getLiveList", {}).then((res) => {
  406. this.liveList = res;
  407. });
  408. },
  409. getHistoryMsg(msg) {
  410. uni.$u.http.get("/api/LivePlayBack/getSimple", {
  411. params: {
  412. id: this.groupID
  413. }
  414. }).then((res) => {
  415. let RspMsgList = res.RspMsgList || [];
  416. let msgList = []
  417. RspMsgList.forEach(item => {
  418. let MsgBody = item.MsgBody || []
  419. if (Array.isArray(MsgBody)) {
  420. MsgBody.forEach(item1 => {
  421. msgList.unshift({
  422. conversationType: 'GROUP',
  423. conversationID: 'GROUP' + this.groupID,
  424. from: item.From_Account,
  425. nick: item.From_Account,
  426. payload: {
  427. data: item1.MsgContent.Data
  428. }
  429. })
  430. })
  431. }
  432. })
  433. if (msg) {
  434. msgList.push(msg)
  435. }
  436. let arr = {
  437. data: msgList,
  438. };
  439. this.$refs.detail1.$onMessageReceived(arr);
  440. });
  441. },
  442. /* 设置 */
  443. setting(type, i) {
  444. if (type == 1) {
  445. this.player.replay()
  446. } else if (type == 2) {
  447. //关闭显示弹幕
  448. this.danmu = !this.danmu;
  449. } else if (type == 3) {
  450. //设置
  451. } else if (type == 4) {
  452. if (this.isFullScreen) {
  453. this.player.fullscreenService.cancelFullScreen()
  454. } else {
  455. this.player.fullscreenService.requestFullScreen()
  456. }
  457. } else if (type == 5) {
  458. //切换画质
  459. if (this.$store.state.isLogin != 1) {
  460. // this.$toUrl('/pages/login/login')
  461. return
  462. }
  463. this.isQuality = true;
  464. this.videoMask = false;
  465. } else if (type == 6) {
  466. this.isQuality = false;
  467. if (this.qualityIndex == i) return;
  468. this.player.dispose();
  469. this.qualityIndex = i;
  470. this.videoInit({pull: this.qualityArr[this.qualityIndex]})
  471. }
  472. if (type == 7) {
  473. }
  474. },
  475. // 显示隐藏
  476. play(type) {
  477. //视频进度
  478. if (type == 1) {
  479. this.videoMask = !this.videoMask;
  480. // if (this.videoMask) {
  481. // this.setInter();
  482. // } else {
  483. // clearTimeout(this.timer);
  484. // }
  485. } else if (type == 2) {
  486. //解除声音(100%
  487. if (this.isVolume) {
  488. this.player.setVolume(0);
  489. } else {
  490. this.player.setVolume(1);
  491. }
  492. this.isVolume = !this.isVolume;
  493. } else if (type == 3) {
  494. //播放/暂停
  495. if (this.isPlay) {
  496. this.userClick = true;
  497. this.player.pause();
  498. } else {
  499. this.player.play();
  500. }
  501. } else if (type == 4) {
  502. //刷新重置
  503. this.player.pause();
  504. this.player.loadByUrl(this.qualityArr[this.qualityIndex]);
  505. this.player.play();
  506. }
  507. },
  508. setInter() {
  509. //s后自动关闭 自定义进度条
  510. this.timer = setTimeout((res) => {
  511. this.videoMask = false
  512. }, 5000);
  513. },
  514. timerStart() {
  515. if (!this.downTimer) {
  516. this.downTimer = setInterval(() => {
  517. this.$set(this.roomInfo, 'down', this.roomInfo.down - 1000)
  518. if (this.roomInfo.down < 0) {
  519. clearInterval(this.downTimer)
  520. this.downTimer = null
  521. }
  522. }, 1000);
  523. }
  524. },
  525. // 获取直播详情
  526. getLiveDetail(id) {
  527. let _this = this;
  528. uni.showLoading({
  529. title: this.$t('common.lab'),
  530. });
  531. uni.$u.http
  532. .post("/api/Live_streaming/getRoomInfo", {
  533. id: this.id,
  534. })
  535. .then((res) => {
  536. this.userInfo = res.userData || {};
  537. // 编辑主播公告
  538. // res.userData.announcement1 = []
  539. // res.userData.announcement1.push(res.userData.announcement)
  540. this.roomInfo = res.info || {};
  541. if (this.roomInfo.islive == 0) {
  542. this.getDown()
  543. this.timerStart()
  544. }
  545. this.groupID = this.roomInfo.id + '';
  546. // this.$store.dispatch('joinGroup',{id:id})
  547. if (this.roomInfo.match_id && this.roomInfo.islive == 1) {
  548. if (this.liveType != 'game') {
  549. this.cricket_match_detail()
  550. }
  551. } else {
  552. this.tabList = [
  553. {
  554. name: this.$t("live.detailTab1"),
  555. },
  556. {
  557. name: this.$t("live.detailTab2"),
  558. }
  559. ]
  560. }
  561. localStorage.liveId =this.id;
  562. if (JSON.stringify(res.info.clarity) == "{}") {
  563. this.quality = ["原画"];
  564. } else {
  565. this.quality = ["流畅", "标清", "高清"];
  566. // 重组清晰画质连接
  567. let qualityArr = [];
  568. for (let var1 in res.info.clarity) {
  569. let name = var1;
  570. // if(var1 == 'smooth') {
  571. // name = '540'
  572. // }else if(var1 == 'sd') {
  573. // name = '720'
  574. // }else if(var1 == 'hd') {
  575. // name = '1080'
  576. // }
  577. qualityArr.push({
  578. name,
  579. src: res.info.clarity[var1],
  580. });
  581. }
  582. qualityArr.unshift({
  583. src: res.info.pull,
  584. name: this.$t("live.standard"),
  585. });
  586. this.qualityArr = qualityArr;
  587. }
  588. this.loginTim()
  589. if (this.roomInfo.islive == 1) {
  590. this.liveSign = true
  591. this.$nextTick(() => {
  592. this.videoInit(res.info)
  593. })
  594. } else {
  595. this.liveSign = false
  596. }
  597. }).finally(() => {
  598. uni.hideLoading();
  599. });
  600. },
  601. getDown() {
  602. let starttime = new Date(this.$common.parseTime(this.roomInfo.starttime * 1000, '{y}/{m}/{d} {h}:{i}:{s}') + ' UTC+5:30')
  603. let nowTime = new Date().getTime()
  604. if (starttime.getTime() - nowTime < 0) {
  605. starttime.setDate(new Date().getDate())
  606. starttime.setMonth(new Date().getMonth())
  607. }
  608. var down = starttime.getTime() - nowTime;
  609. this.$set(this.roomInfo, 'down', down)
  610. },
  611. loginTim() {
  612. if (this.isLogin == 1) {
  613. this.$store.dispatch('loginTim', this.infos).then(() => {
  614. this.joinGroup(this.infos)
  615. })
  616. } else {
  617. bus.$on('chatLogin', this.joinGroup)
  618. let youkeInfo = JSON.parse(sessionStorage.getItem('youkeInfo'))
  619. if (youkeInfo) {
  620. this.$store.dispatch('loginTim', {
  621. ...youkeInfo,
  622. types: 'youke'
  623. }).then(() => {
  624. this.joinGroup(youkeInfo)
  625. })
  626. } else {
  627. uni.$u.http.post("/api/Universal/imTouristAccount").then(res => {
  628. sessionStorage.setItem('youkeInfo', JSON.stringify(res))
  629. this.$store.dispatch('loginTim', {
  630. ...res,
  631. types: 'youke'
  632. }).then(() => {
  633. this.joinGroup(res)
  634. })
  635. })
  636. }
  637. }
  638. },
  639. joinGroup(info, sign) {
  640. this.$refs.detail1.messageList = [];
  641. uni.$TUIKit.joinGroup({
  642. groupID: this.groupID,
  643. type: "TIM.TYPES.GRP_AVCHATROOM",
  644. }).then((imResponse) => {
  645. switch (imResponse.data.status) {
  646. case uni.$TUIKitTIM.TYPES.JOIN_STATUS_WAIT_APPROVAL:
  647. // 等待管理员同意
  648. break;
  649. case uni.$TUIKitTIM.TYPES.JOIN_STATUS_SUCCESS:
  650. // 加群成功
  651. this.$nextTick(() => {
  652. this.login(info)
  653. });
  654. break;
  655. case "AlreadyInGroup":
  656. // 加群成功
  657. this.$nextTick(() => {
  658. if (sign) {
  659. this.login(info)
  660. } else {
  661. this.getHistoryMsg()
  662. }
  663. });
  664. break;
  665. case uni.$TUIKitTIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP:
  666. // 已经在群中
  667. break;
  668. default:
  669. break;
  670. }
  671. });
  672. },
  673. login(infos) {
  674. let data = {
  675. type: 102,
  676. nobel: {
  677. level: 1,
  678. // 贵族图标guard_icon || 等级图标exp_icon || 房主图标
  679. exp_icon: infos.exp_icon,
  680. is_guard: infos.is_guard,
  681. guard_swf: infos.is_guard == 1 ? infos.guard.swf : "",
  682. guard_name: infos.is_guard == 1 ? infos.guard.swf_name : "",
  683. is_room: infos.id == this.groupID ? 1 : 0,
  684. guard_icon: infos.is_guard == 1 ? infos.guard.icon : "",
  685. },
  686. };
  687. let to = this.groupID;
  688. const message = uni.$TUIKit.createCustomMessage({
  689. to,
  690. conversationType: "GROUP",
  691. payload: {
  692. data: JSON.stringify(data),
  693. },
  694. });
  695. uni.$TUIKit
  696. .sendMessage(message)
  697. .then((res) => {
  698. this.getHistoryMsg()
  699. })
  700. .catch((error) => {});
  701. },
  702. back() {
  703. uni.switchTab({
  704. url: '/pages/Live/Live'
  705. })
  706. },
  707. /* 判断是否登录 未登录情况下只能停留3分钟 180秒 */
  708. getIsLogin() {
  709. let that = this;
  710. if (this.isLogin == 1) return;
  711. uni.$u.http.get('/api/universal/getHot', {}).then(res => {
  712. this.$store.state.system = res;
  713. if (!this.system.login_remind || Number(this.system.login_remind) > 5000) return;
  714. this.time1 = setTimeout((res) => {
  715. if (this.isLogin == 1) {
  716. return
  717. }
  718. localStorage.setItem('watchingOutSign', true)
  719. this.$toast("Please log in to continue watching the live broadcast");
  720. setTimeout((res1) => {
  721. // this.$toUrl('/pages/login/login')
  722. }, 1500);
  723. }, this.system.login_remind * 60000);
  724. })
  725. },
  726. change(e) {
  727. this.current = e.index;
  728. if (e == 2) {
  729. setTimeout((res) => {
  730. this.$refs.detail3.getList({
  731. uid: this.userInfo.uid,
  732. type: 0,
  733. });
  734. }, 100);
  735. }
  736. },
  737. clickPlay() {
  738. try {
  739. var evt = document.createEvent('HTMLEvents')
  740. evt.initEvent('click', true, true)
  741. document.getElementById('palyevent').dispatchEvent(evt)
  742. } catch (error) {
  743. }
  744. },
  745. owerPlay() {
  746. this.isPlay = true
  747. this.player && this.player.play();
  748. },
  749. owerPlay1() {
  750. if (this.userClick) {
  751. return
  752. }
  753. this.owerPlay()
  754. },
  755. uodateMsg(list) {
  756. this.messageList = list
  757. },
  758. countdownFun(value) {
  759. if (!value) {
  760. return "";
  761. }
  762. var h = parseInt(value / 3600);
  763. var m = parseInt((value % 3600) / 60);
  764. var str = "";
  765. if (h > 0) {
  766. str += h + "hrs";
  767. if (m < 10) {
  768. m = "0" + m;
  769. }
  770. str += " " + m + "min";
  771. return str;
  772. } else {
  773. if (m > 0) {
  774. if (m < 10) {
  775. m = "0" + m;
  776. }
  777. str += m + "min";
  778. }
  779. }
  780. var s = parseInt((value % 3600) % 60);
  781. if (s < 10) {
  782. s = "0" + s;
  783. }
  784. str += " " + s + "s";
  785. return str;
  786. },
  787. downloadTimerFun() {
  788. this.downloadShow = false
  789. this.downloadTimer = setTimeout(() => {
  790. this.downloadShow = true
  791. }, 60000 * 2)
  792. },
  793. adClick(info) {
  794. if (info.adver_url_one) {
  795. uni.$u.http
  796. .post("/api/live_streaming/click_adv", {
  797. type: this.liveType == 'game' ? 6 : 3,
  798. id: info.id,
  799. url: info.adver_url_one
  800. })
  801. .then((res) => {
  802. }).finally(() => {
  803. });
  804. window.open(info.adver_url_one)
  805. }
  806. },
  807. adClick1(info) {
  808. if (info.qr_url) {
  809. window.open(info.qr_url)
  810. }
  811. }
  812. },
  813. };
  814. </script>
  815. <style lang="scss">
  816. page {
  817. background-color: #f3f3f7;
  818. }
  819. .body {
  820. position: sticky;
  821. top: 0;
  822. z-index: 20;
  823. background-color: #f3f3f7;
  824. }
  825. @media screen and (orientation: landscape) {
  826. .body {
  827. position: relative;
  828. }
  829. }
  830. .quality-mask {
  831. color: #fff;
  832. position: absolute;
  833. top: 0;
  834. left: 0;
  835. right: 0;
  836. bottom: 0;
  837. z-index: 9997;
  838. background-color: rgba(0, 0, 0, 0.4);
  839. .quality-nav {
  840. padding: 40rpx;
  841. }
  842. .quality-title {
  843. padding: 0 98rpx;
  844. margin-top: 50rpx;
  845. }
  846. image {
  847. width: 24rpx;
  848. height: 24rpx;
  849. }
  850. .quality-list {
  851. padding: 0 98rpx;
  852. flex-wrap: wrap;
  853. view {
  854. font-size: 24rpx;
  855. margin-top: 28rpx;
  856. border-radius: 6rpx;
  857. padding: 8rpx 20rpx;
  858. border: 2rpx solid #fff;
  859. }
  860. .active {
  861. color: $color2;
  862. border: 2rpx solid $color2;
  863. }
  864. }
  865. }
  866. .video-mask {
  867. position: absolute;
  868. top: 0;
  869. left: 0;
  870. right: 0;
  871. bottom: 0;
  872. z-index: 9997;
  873. box-shadow: 0px 12px 20px -12px #000 inset, 0px -12px 20px -12px #000 inset;
  874. .top {
  875. color: #fff;
  876. position: absolute;
  877. top: 24rpx;
  878. right: 24rpx;
  879. padding: 4rpx 20rpx;
  880. border-radius: 40rpx;
  881. border: 2rpx solid #fff;
  882. }
  883. .foot {
  884. position: absolute;
  885. bottom: 24rpx;
  886. right: 0;
  887. left: 0;
  888. padding-right: 24rpx;
  889. &.full {
  890. position: fixed;
  891. bottom: 0;
  892. }
  893. .u-icon {
  894. margin-left: 26rpx;
  895. }
  896. image {
  897. width: 32rpx;
  898. height: 32rpx;
  899. margin-left: 26rpx;
  900. }
  901. }
  902. }
  903. .ranking-box {
  904. position: absolute;
  905. right: 10px;
  906. top: 50%;
  907. transform: translateY(-50%);
  908. .ranking {
  909. width: 45px;
  910. }
  911. }
  912. .volume-box {
  913. position: absolute;
  914. right: 20rpx;
  915. bottom: 16rpx;
  916. z-index: 999;
  917. display: flex;
  918. align-items: center;
  919. justify-content: center;
  920. width: 60rpx;
  921. height: 60rpx;
  922. border-radius: 50%;
  923. background-color: #000;
  924. }
  925. .detail {
  926. position: relative;
  927. background: #f3f3f7;
  928. }
  929. #palyevent {
  930. opacity: 0;
  931. position: absolute;
  932. top: 0;
  933. left: 0;
  934. }
  935. .no-live {
  936. position: relative;
  937. background: rgba(0, 0, 0, 1);
  938. .down-box {
  939. position: absolute;
  940. top: 0;
  941. left: 0;
  942. bottom: 0;
  943. right: 0;
  944. z-index: 10;
  945. background-color: rgba(27, 24, 67, 0.8);
  946. display: flex;
  947. align-items: center;
  948. justify-content: center;
  949. font-size: 26rpx;
  950. font-weight: 400;
  951. color: #d5d4e4;
  952. line-height: 1;
  953. text-align: center;
  954. .down {
  955. margin-top: 24rpx;
  956. font-size: 36rpx;
  957. font-weight: bold;
  958. color: #ffffff;
  959. }
  960. }
  961. .time {
  962. color: #fff;
  963. position: absolute;
  964. left: 0;
  965. right: 0;
  966. top: 0;
  967. background-color: rgba(0, 0, 0, 0.4);
  968. padding: 20rpx;
  969. z-index: 10;
  970. }
  971. .home_logo, .away_logo {
  972. position: absolute;
  973. top: 50%;
  974. transform: translateY(-50%);
  975. width: 150rpx;
  976. height: 150rpx;
  977. border-radius: 50%;
  978. }
  979. .home_logo {
  980. left: 100rpx;
  981. }
  982. .away_logo {
  983. right: 100rpx;
  984. }
  985. }
  986. .video {
  987. height: 420rpx;
  988. position: relative;
  989. .thumb {
  990. width: 100%;
  991. height: 100%;
  992. z-index: 100;
  993. position: relative;
  994. background-color: #000;
  995. }
  996. .video-bar {
  997. width: 100%;
  998. position: absolute;
  999. left: 0;
  1000. right: 0;
  1001. bottom: 0;
  1002. z-index: 9997;
  1003. color: #fff;
  1004. height: 60rpx;
  1005. background: rgba(0, 0, 0, 0.4);
  1006. image {
  1007. width: 30rpx;
  1008. height: 30rpx;
  1009. margin-left: 20rpx;
  1010. }
  1011. text {
  1012. margin-right: 60rpx;
  1013. }
  1014. }
  1015. .video-bar-right {
  1016. position: relative;
  1017. .quality {
  1018. width: 80rpx;
  1019. display: flex;
  1020. flex-wrap: wrap;
  1021. justify-content: center;
  1022. position: absolute;
  1023. left: -40rpx;
  1024. color: #fff;
  1025. bottom: 50rpx;
  1026. padding: 20rpx 22rpx;
  1027. border-radius: 20rpx;
  1028. background-color: rgba(0, 0, 0, 0.7);
  1029. text {
  1030. display: block;
  1031. width: 100%;
  1032. margin-right: 0;
  1033. text-align: center;
  1034. padding-bottom: 20rpx;
  1035. }
  1036. }
  1037. }
  1038. .voice {
  1039. position: absolute;
  1040. bottom: 50px;
  1041. left: 50%;
  1042. z-index: 4;
  1043. margin: -33rpx 0 0 -134rpx;
  1044. width: 268rpx;
  1045. height: 100rpx;
  1046. line-height: 100rpx;
  1047. border-radius: 8rpx;
  1048. justify-content: center;
  1049. align-items: center;
  1050. cursor: pointer;
  1051. background: #ff5d23;
  1052. font-size: 30rpx;
  1053. text-align: center;
  1054. color: #fff;
  1055. background-size: 100% 100%;
  1056. }
  1057. .play {
  1058. position: absolute;
  1059. left: 50%;
  1060. top: 50%;
  1061. margin-left: -50rpx;
  1062. width: 100rpx;
  1063. height: 100rpx;
  1064. z-index: 9;
  1065. }
  1066. .myVideo {
  1067. position: absolute;
  1068. left: 50%;
  1069. top: 50%;
  1070. margin-left: -50rpx;
  1071. width: 100rpx;
  1072. height: 100rpx;
  1073. z-index: 9;
  1074. }
  1075. }
  1076. .row {
  1077. display: flex;
  1078. align-items: center;
  1079. text-align: center;
  1080. background-color: rgb(18, 20, 21);
  1081. color: #fff;
  1082. font-size: 14px;
  1083. .col {
  1084. flex: 1;
  1085. display: flex;
  1086. align-items: center;
  1087. justify-content: center;
  1088. height: 20px;
  1089. }
  1090. .u-icon {
  1091. margin: 0 5px;
  1092. }
  1093. }
  1094. .tabs {
  1095. position: relative;
  1096. }
  1097. .u-tabs {
  1098. background-color: #fff;
  1099. }
  1100. .active {
  1101. background: #ccc;
  1102. }
  1103. .adver-box {
  1104. position: relative;
  1105. .qr_img {
  1106. position: absolute;
  1107. top: 0;
  1108. right: 0;
  1109. height: 100%;
  1110. }
  1111. }
  1112. .ad {
  1113. display: block;
  1114. width: 100%;
  1115. }
  1116. </style>