live.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. <template>
  2. <div>
  3. <div class="top">
  4. <div class="header">
  5. <img class="logo" src="/static/logo_big.png" alt="" />
  6. <div id="palyevent">palyevent</div>
  7. <u--image
  8. class="border"
  9. :showLoading="true"
  10. :src="info.avatar || '/static/image/match/teams_avatar_ico@2x.png'"
  11. @click="go('/pages/Match/member/usermanger', true)"
  12. width="24px"
  13. height="24px"
  14. shape="circle"
  15. ></u--image>
  16. </div>
  17. <div class="title-box">
  18. <div class="flex" @click="stepBack">
  19. <u-icon name="arrow-left" color="#ffffff" size="16px" bold></u-icon>
  20. <!-- Videos -->
  21. {{ $t('video.lab') }}
  22. </div>
  23. </div>
  24. </div>
  25. <div style="height: 436rpx; width: 100%">
  26. <div class="prism-player" id="player-con">
  27. <!-- <div class="tool-box" v-if="toolbar">
  28. <img class="case" @click="caseVideo" src="/static/image/common/line-case.png" alt="">
  29. </div> -->
  30. <div class="icon-box" v-if="toolbar">
  31. <u-icon name="rewind-left-fill" color="#fff" size="50" @click="setSeek(-10)"></u-icon>
  32. <u-icon :name="!isPlay ? 'play-right-fill' : 'pause'" @click="playToggle" color="#fff" size="100"></u-icon>
  33. <u-icon name="rewind-right-fill" color="#fff" size="50" @click="setSeek(10)"></u-icon>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="box">
  38. <div class="name">
  39. {{ targetInfo.title }}
  40. </div>
  41. <div class="time" v-if="targetInfo.addtime">{{ targetInfo.addtime }}</div>
  42. </div>
  43. <div class="list-box" v-if="list.length">
  44. <div class="title">
  45. <!-- Recommended Videos -->
  46. {{ $t('video.lab19') }}
  47. </div>
  48. <div class="item" @click="onTap(params.id)" v-for="(params) in list" :key="params.id">
  49. <view class="waterfall-item-img">
  50. <u--image
  51. :showLoading="true"
  52. :src="params.flie[0].img"
  53. width="100%"
  54. height="348rpx"
  55. >
  56. <template v-slot:loading>
  57. <image class="loading-banner-img" src="/static/image/common/video-list-bg.png" mode="aspectFill"></image>
  58. </template>
  59. </u--image>
  60. <div class="bg"></div>
  61. <div class="content">
  62. <div class="text-clamp2">{{ params.title }}</div>
  63. </div>
  64. <img class="play" src="/static/image/live/play-icon.png" alt="">
  65. </view>
  66. </div>
  67. <u-loadmore
  68. :status="status"
  69. fontSize="28"
  70. :line="true"
  71. :loading-text="statusType.loadingText"
  72. :loadmore-text="statusType.loadmoreText"
  73. :nomore-text="statusType.nomoreText"
  74. />
  75. </div>
  76. </div>
  77. </template>
  78. <script>
  79. import { parseTime } from '@/utils/util'
  80. export default {
  81. components: {},
  82. data() {
  83. return {
  84. id: "",
  85. tournament: "",
  86. targetInfo: {},
  87. isPlay: true,
  88. toolbar: false,
  89. player: null,
  90. toolbarTimer: null,
  91. userClick: false,
  92. mediaUrl: '',
  93. list: [],
  94. type: '',
  95. obj: {
  96. total: 1
  97. },
  98. page: 1,
  99. status: 'loadmore',
  100. statusType:{
  101. loadingText: this.$t('common.lab'),
  102. loadmoreText: this.$t('common.lab1'),
  103. nomoreText: this.$t('common.lab2')
  104. },
  105. cjs: null
  106. };
  107. },
  108. computed: {
  109. info() {
  110. return this.$store.state.info;
  111. },
  112. isLogin() {
  113. return this.$store.state.isLogin;
  114. },
  115. },
  116. onLoad(option) {
  117. this.id = option.id;
  118. this.tournament = option.tournament;
  119. },
  120. onUnload() {
  121. window.removeEventListener('touchstart', this.owerPlay1)
  122. // window.removeEventListener('load', this.init)
  123. this.player && this.player.dispose();
  124. },
  125. created() {
  126. this.getDetail();
  127. },
  128. onReachBottom() {
  129. if (this.status == 'loadmore') {
  130. this.page++;
  131. this.getDetail();
  132. }
  133. },
  134. mounted() {
  135. // window.addEventListener("load", this.init);
  136. window.addEventListener('touchstart', this.owerPlay1)
  137. document.getElementById('palyevent').addEventListener('click',this.owerPlay)
  138. },
  139. methods: {
  140. getDetail() {
  141. this.status = 'loading';
  142. let obj = {
  143. }
  144. if (this.tournament) {
  145. obj.tournament = this.tournament
  146. }
  147. uni.$u.http
  148. .get("/api/Video/getTournamentVideoInfo", {
  149. params: {
  150. id: this.id,
  151. page: this.page,
  152. ...obj
  153. },
  154. })
  155. .then((res) => {
  156. this.targetInfo = res.info || {};
  157. if(this.targetInfo.flie && this.targetInfo.flie[0]) {
  158. this.mediaUrl = this.targetInfo.flie[0].video
  159. this.videoInit()
  160. }
  161. if (this.page == 1) {
  162. // 关闭下拉
  163. this.list=res.list.data || []
  164. // uni.stopPullDownRefresh();
  165. } else {
  166. this.list = this.list.concat(res.list.data || [])
  167. }
  168. this.obj = res.list
  169. this.status = this.list.length == res.list.total ? 'nomore' : 'loadmore'
  170. })
  171. .catch((res) => {});
  172. },
  173. onTap(id) {
  174. uni.navigateTo({
  175. url: '/pages/Videos/live?id=' + id+'&tournament=' + this.tournament
  176. });
  177. },
  178. playToggle() {
  179. let status = this.player.getStatus();
  180. if (this.toolbarTimer) {
  181. clearTimeout(this.toolbarTimer)
  182. }
  183. this.toolbarTimer = setTimeout(() => {
  184. this.toolbar = false
  185. this.toolbarTimer = null
  186. }, 3000)
  187. if (status == 'playing') {
  188. this.isPlay = false
  189. this.userClick = true
  190. this.player.pause()
  191. } else {
  192. this.isPlay = true
  193. this.player.play()
  194. }
  195. },
  196. clickPlay() {
  197. try {
  198. var evt = document.createEvent('HTMLEvents')
  199. evt.initEvent('click', true, true)
  200. document.getElementById('palyevent').dispatchEvent(evt)
  201. } catch (error) {
  202. }
  203. },
  204. owerPlay() {
  205. this.isPlay = true
  206. this.player && this.player.play()
  207. },
  208. owerPlay1() {
  209. if (this.userClick) {
  210. return
  211. }
  212. this.owerPlay()
  213. },
  214. setSeek(type) {
  215. if (this.toolbarTimer) {
  216. clearTimeout(this.toolbarTimer)
  217. }
  218. this.toolbarTimer = setTimeout(() => {
  219. this.toolbar = false
  220. this.toolbarTimer = null
  221. }, 3000)
  222. let t = this.player.getCurrentTime();
  223. let a = this.player.getDuration();
  224. t += type
  225. if (t < 0) {
  226. t = 0
  227. }
  228. if (t > a) {
  229. t = a
  230. }
  231. this.player.seek(t)
  232. },
  233. parseTime(t) {
  234. return parseTime(t, '{y}-{m}-{d} {h}:{i}:{m}')
  235. },
  236. videoInit() {
  237. var $this = this
  238. this.player = new Aliplayer(
  239. {
  240. id: "player-con",
  241. source: this.mediaUrl,
  242. width: "100%",
  243. height: "100%",
  244. autoplay: true,
  245. isLive: false,
  246. rePlay: true,
  247. showBarTime: '3000',
  248. // cover: data.thumb,
  249. videoHeight: "100%",
  250. keyShortCuts: true,
  251. playsinline: true,
  252. "language": "en-us",
  253. preload: true,
  254. controlBarVisibility: "hover",
  255. videoWidth: "100%",
  256. useH5Prism: true,
  257. skinLayout: [
  258. // {
  259. // name: "bigPlayButton",
  260. // align: "blabs",
  261. // x: 30,
  262. // y: 80,
  263. // },
  264. {
  265. name: "H5Loading",
  266. align: "cc",
  267. },
  268. {
  269. name: "errorDisplay",
  270. align: "tlabs",
  271. x: 0,
  272. y: 0,
  273. },
  274. {
  275. name: "infoDisplay",
  276. },
  277. {
  278. name: "tooltip",
  279. align: "blabs",
  280. x: 0,
  281. y: 56,
  282. },
  283. {
  284. name: "thumbnail",
  285. },
  286. {
  287. name: "controlBar",
  288. align: "blabs",
  289. x: 0,
  290. y: 0,
  291. children: [
  292. {
  293. name: "progress",
  294. align: "blabs",
  295. x: 0,
  296. y: 44,
  297. },
  298. // {
  299. // name: "playButton",
  300. // align: "tl",
  301. // x: 15,
  302. // y: 12,
  303. // },
  304. {
  305. name: "timeDisplay",
  306. align: "tl",
  307. x: 10,
  308. y: 7,
  309. },
  310. {
  311. name: "fullScreenButton",
  312. align: "tr",
  313. x: 10,
  314. y: 12,
  315. },
  316. {
  317. name: "volume",
  318. align: "tr",
  319. x: 5,
  320. y: 10,
  321. },
  322. ],
  323. },
  324. ],
  325. },
  326. function (player) {
  327. setTimeout(() => {
  328. $this.clickPlay()
  329. }, 1000)
  330. }
  331. );
  332. this.player.on('hideBar', () => {
  333. this.toolbar = false
  334. })
  335. this.player.on('showBar', () => {
  336. this.isPlay = this.player.getStatus() == 'playing';
  337. this.toolbar = true;
  338. if (this.toolbarTimer) {
  339. clearTimeout(this.toolbarTimer)
  340. }
  341. this.toolbarTimer = setTimeout(() => {
  342. this.toolbar = false
  343. this.toolbarTimer = null
  344. }, 3000)
  345. })
  346. },
  347. init() {
  348. try{
  349. this.cjs = new Castjs()
  350. this.cjs.on('error', (err) => {
  351. console.error(err)
  352. })
  353. this.cjs.on('available', () => {
  354. })
  355. }catch(error) {
  356. }
  357. },
  358. caseVideo() {
  359. if (this.cjs) {
  360. console.error(this.cjs.available)
  361. if (this.cjs.available) {
  362. var metadata = {
  363. poster: '',
  364. title: this.targetInfo.title,
  365. description: '',
  366. subtitles: [],
  367. }
  368. this.cjs.cast(this.mediaUrl, metadata)
  369. }
  370. }
  371. },
  372. stepBack() {
  373. uni.switchTab({
  374. url: '/pages/Videos/index'
  375. })
  376. },
  377. },
  378. };
  379. </script>
  380. <style lang="scss">
  381. .top {
  382. position: sticky;
  383. top: 0;
  384. z-index: 999;
  385. .header {
  386. display: flex;
  387. align-items: center;
  388. justify-content: space-between;
  389. padding: 8rpx 16px 16rpx;
  390. background-color: #10044a;
  391. #palyevent {
  392. opacity: 0;
  393. }
  394. }
  395. .logo {
  396. height: 24px;
  397. }
  398. .border {
  399. border: 1px solid #cc2900;
  400. border-radius: 50%;
  401. }
  402. .title-box {
  403. height: 40px;
  404. background-color: #262e4a;
  405. padding: 0 16px;
  406. display: flex;
  407. align-items: center;
  408. color: #fff;
  409. font-weight: 500;
  410. font-size: 16px;
  411. .u-icon {
  412. margin-right: 10px;
  413. }
  414. }
  415. }
  416. .tool-box {
  417. position: absolute;
  418. right: 16px;
  419. top: 16px;
  420. background-color: rgba(0, 0, 0, 0.1);
  421. padding: 2px 2px 2px 0px;
  422. .case {
  423. margin-left: 10px;
  424. width: 20px;
  425. }
  426. }
  427. .icon-box {
  428. position: absolute;
  429. top: 50%;
  430. left: 50%;
  431. transform: translate(-50%, -50%);
  432. color: #fff;
  433. font-weight: 700;
  434. z-index: 2;
  435. display: flex;
  436. align-items: center;
  437. background-color: rgba(0, 0, 0, 0.1);
  438. .u-icon {
  439. padding: 10px;
  440. }
  441. }
  442. .box {
  443. padding: 32rpx;
  444. .name {
  445. font-weight: 500;
  446. font-size: 28rpx;
  447. overflow: hidden;
  448. text-overflow: ellipsis;
  449. display: -webkit-box;
  450. -webkit-box-orient: vertical;
  451. -webkit-line-clamp: 4;
  452. color: #000;
  453. }
  454. .time {
  455. padding-top: 16px;
  456. text-align: right;
  457. font-weight: 400;
  458. font-size: 20rpx;
  459. color: #4E4E4E;
  460. }
  461. }
  462. .list-box {
  463. .title {
  464. padding: 10rpx 16px 10px;
  465. font-weight: 600;
  466. font-size: 18px;
  467. color: #242424;
  468. }
  469. .item {
  470. background-color: #fff;
  471. overflow: hidden;
  472. font-size: 28rpx;
  473. color: #fff;
  474. font-weight: 500;
  475. margin-bottom: 20rpx;
  476. .waterfall-title {
  477. padding: 20rpx 10rpx;
  478. font-weight: 700;
  479. }
  480. .waterfall-item-img {
  481. position: relative;
  482. height: 348rpx;
  483. .loading-banner-img {
  484. width: 100%;
  485. height: 348rpx;
  486. }
  487. .bg {
  488. position: absolute;
  489. top: 0;
  490. left: 0;
  491. right: 0;
  492. bottom: 0;
  493. background: linear-gradient(180deg, rgba(16, 4, 74, 0) 0%, #080031 100%);
  494. }
  495. .content {
  496. position: absolute;
  497. left: 0;
  498. right: 0;
  499. bottom: 0;
  500. padding: 11px 72px 11px 16px;
  501. }
  502. .play {
  503. position: absolute;
  504. right: 16px;
  505. bottom: 19px;
  506. width: 28px;
  507. }
  508. }
  509. }
  510. }
  511. </style>