video-show.tsx 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. import {
  2. defineComponent,
  3. nextTick,
  4. onMounted,
  5. onUnmounted,
  6. reactive,
  7. ref,
  8. watch
  9. } from 'vue';
  10. import styles from '../video.module.less';
  11. import styles2 from './show.module.less';
  12. import { Button } from 'vant';
  13. import { browser } from '@/helpers/utils';
  14. // import Plyr from 'plyr'
  15. // import 'plyr/dist/plyr.css'
  16. import { useRoute } from 'vue-router';
  17. import deepClone from '@/helpers/deep-clone';
  18. import TCPlayer from 'tcplayer.js';
  19. import 'tcplayer.js/dist/tcplayer.css';
  20. export default defineComponent({
  21. name: 'pre-register',
  22. emits: ['tabChange'],
  23. setup(props, { emit }) {
  24. const route = useRoute();
  25. const video = route.query.v ? JSON.parse(route.query.v as any) : [];
  26. console.log(route.query, 'query');
  27. const forms = reactive({
  28. coverImg: route.query.coverImg,
  29. videoID: 'video' + Date.now() + Math.floor(Math.random() * 100),
  30. introductionVideo: route.query.introductionVideo as any,
  31. id: null as any,
  32. videoDetails: deepClone(video),
  33. player: null as any,
  34. currentTime: 0
  35. });
  36. /**
  37. * 视屏累计时长
  38. * 1、视屏开始播放时-开始计时
  39. * 2、视频暂停时暂停-停止计时
  40. * 3、视频加载时-停止计时
  41. * 4、视频倍数播放时,时间正常计时
  42. * 5、点击视频进度或拖动进度时,时间暂停
  43. */
  44. const _init = () => {
  45. // const controls = [
  46. // 'play-large',
  47. // 'play',
  48. // 'progress',
  49. // 'captions',
  50. // 'current-time',
  51. // 'duration',
  52. // 'settings',
  53. // 'fullscreen'
  54. // ]
  55. // const params: any = {
  56. // controls: controls,
  57. // settings: ['speed'],
  58. // speed: { selected: 1, options: [0.5, 1, 1.5, 2] },
  59. // i18n: {
  60. // speed: '速度',
  61. // normal: '默认'
  62. // },
  63. // invertTime: false
  64. // }
  65. // if (browser().iPhone) {
  66. // params.fullscreen = {
  67. // enabled: true,
  68. // fallback: 'force',
  69. // iosNative: true
  70. // }
  71. // }
  72. // const times: any = []
  73. // deepClone(forms.videoDetails).forEach((item: any) => {
  74. // times.push({
  75. // time: item.startNode,
  76. // label: item.desc
  77. // })
  78. // })
  79. // params.markers = { enabled: true, points: times }
  80. // forms.player = new Plyr('#register-video', params)
  81. // forms.player.on('loadedmetadata', () => {
  82. // checkVideoDetails(forms.player.currentTime)
  83. // })
  84. // // 如何视频在缓存不会触发
  85. // forms.player.on('timeupdate', (e: any) => {
  86. // // 时间变化时更新每一段的状态
  87. // console.log(forms.player.currentTime, 'forms.player.currentTime', e)
  88. // checkVideoDetails(forms.player.currentTime)
  89. // })
  90. // forms.player.on('enterfullscreen', () => {
  91. // console.log('fullscreen')
  92. // const i = document.createElement('i')
  93. // i.id = 'fullscreen-back'
  94. // i.className = 'van-icon van-icon-arrow-left video-back'
  95. // i.addEventListener('click', () => {
  96. // forms.player.fullscreen.exit()
  97. // })
  98. // console.log(document.getElementsByClassName('plyr'))
  99. // document.getElementsByClassName('plyr')[0].appendChild(i)
  100. // })
  101. // forms.player.on('exitfullscreen', () => {
  102. // console.log('exitfullscreen')
  103. // const i = document.getElementById('fullscreen-back')
  104. // i && i.remove()
  105. // })
  106. const Button = TCPlayer.getComponent('Button');
  107. const BigPlayButton = TCPlayer.getComponent('BigPlayButton');
  108. BigPlayButton.prototype.createEl = function () {
  109. const el = Button.prototype.createEl.call(this);
  110. const _html =
  111. '<button><svg width="41px"height="41px"viewBox="0 0 41 41"version="1.1"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke="none"stroke-width="1"fill="none"fill-rule="evenodd"><g transform="translate(-167.000000, -155.000000)"><g transform="translate(0.000000, 85.000000)"><g transform="translate(158.000000, 70.000000)"><g transform="translate(9.000000, 0.000000)"><circle id="椭圆形"stroke="#FFFFFF"fill-opacity="0.1"fill="#D8D8D8"cx="20.5"cy="20.5"r="20"></circle><path d="M14.5483871,27.6859997 L14.5483871,13.4342349 C14.5480523,12.8729571 14.8729597,12.356555 15.3949624,12.0887034 C15.9169651,11.8208518 16.5522696,11.8445472 17.0503046,12.1504437 L28.6530473,19.2778563 C29.1119763,19.5602271 29.3887725,20.0426422 29.3887725,20.5601173 C29.3887725,21.0775924 29.1119763,21.5600075 28.6530473,21.8423783 L17.0503046,28.9697909 C16.5522696,29.2756874 15.9169651,29.2993828 15.3949624,29.0315312 C14.8729597,28.7636796 14.5480523,28.2472775 14.5483871,27.6859997 Z"id="路径"fill="#FFFFFF"fill-rule="nonzero"></path></g></g></g></g></g></svg></button>';
  112. el.appendChild(
  113. TCPlayer.dom.createEl('div', {
  114. className: 'vjs-button-icon',
  115. innerHTML: _html
  116. })
  117. );
  118. return el;
  119. };
  120. forms.player = TCPlayer('register-video', {
  121. appID: '',
  122. controls: true,
  123. plugins: {
  124. ProgressMarker: true
  125. }
  126. }); // player-container-id 为播放器容器 ID,必须与 html 中一致
  127. if (forms.player) {
  128. forms.player.src(forms.introductionVideo); // url 播放地址
  129. forms.player.poster(forms.coverImg || '');
  130. forms.player.on('loadedmetadata', () => {
  131. checkVideoDetails(forms.player.currentTime());
  132. });
  133. // 如何视频在缓存不会触发
  134. forms.player.on('timeupdate', (e: any) => {
  135. // 时间变化时更新每一段的状态
  136. console.log(
  137. forms.player.currentTime(),
  138. 'forms.player.currentTime()',
  139. e
  140. );
  141. checkVideoDetails(forms.player.currentTime());
  142. });
  143. forms.player.on('fullscreenchange', () => {
  144. if (forms.player.isFullscreen()) {
  145. console.log('fullscreen');
  146. const i = document.createElement('i');
  147. i.id = 'fullscreen-back';
  148. i.className = 'van-icon van-icon-arrow-left video-back';
  149. i.addEventListener('click', () => {
  150. forms.player.exitFullscreen();
  151. });
  152. document.getElementsByClassName('video-js')[0].appendChild(i);
  153. } else {
  154. console.log('exitfullscreen');
  155. const i = document.getElementById('fullscreen-back');
  156. i && i.remove();
  157. }
  158. });
  159. }
  160. };
  161. const checkVideoDetails = (time: number) => {
  162. forms.videoDetails.forEach((item: any) => {
  163. if (item.startNode <= time && time <= item.endNode) {
  164. forms.id = item.id;
  165. }
  166. });
  167. };
  168. onMounted(() => {
  169. nextTick(() => {
  170. _init();
  171. });
  172. });
  173. const onSubmit = () => {
  174. // emit('tabChange', 3)
  175. };
  176. const messageContent = ref('');
  177. const registerDisplay = ref();
  178. const getMessage = (ev: any) => {
  179. if (ev.data.api === 'parent-notes') {
  180. console.log(ev.data, 'data');
  181. messageContent.value = ev.data.message || '';
  182. registerDisplay.value = ev.data.registerDisplay || false;
  183. }
  184. };
  185. onMounted(() => {
  186. nextTick(() => {
  187. // 是否加载完成
  188. window.parent &&
  189. window.parent.postMessage(
  190. {
  191. api: 'onLoad',
  192. status: true
  193. },
  194. '*'
  195. );
  196. });
  197. window.addEventListener('message', getMessage);
  198. });
  199. onUnmounted(() => {
  200. window.removeEventListener('message', getMessage);
  201. });
  202. return () => (
  203. <div class={[styles['pre-register-video'], styles2.activeVideo]}>
  204. <div class={styles.videoContainer}>
  205. <i class={styles.videoTitle}></i>
  206. <div class={styles.videoSection}>
  207. <div class={styles['video-content']}>
  208. {/* <video
  209. id="register-video"
  210. class={styles['video']}
  211. src={forms.introductionVideo}
  212. playsinline={true}
  213. poster={forms.coverImg as any}
  214. preload="auto"
  215. ></video> */}
  216. <img src={forms.coverImg as any} class={styles.coverImg} />
  217. </div>
  218. <div class={styles.videoCount}>
  219. <div class={styles.videoTitles}>点击会议段落可重播:</div>
  220. <div class={styles.videoCountContent}>
  221. {forms.videoDetails.map((item: any) => (
  222. <span
  223. class={[item.id === forms.id ? styles.active : '']}
  224. onClick={() => {
  225. forms.player.currentTime(item.startNode);
  226. }}>
  227. {item.desc}
  228. </span>
  229. ))}
  230. </div>
  231. </div>
  232. </div>
  233. </div>
  234. <div class={styles.messageContainer}>
  235. <div class={styles.messageTitle}></div>
  236. <div class={styles.messageContent}>
  237. {/* <p>家长您好!</p>
  238. <p class={styles.c1}>
  239. 请家长们合理安排时间,<span>认真观看</span>家长会内容。在<span>详细了解</span>
  240. 所有要求后,有意向让孩子加入乐团的家长,请在<span>明晚20:00前</span>,为孩子完成
  241. <span>乐团报名</span>
  242. </p>
  243. <p class={styles.c1}>
  244. 下周,专业老师将针对意向入团学员进行身体条件确认。谢谢各位的支持!
  245. </p>
  246. <p class={styles.bottom}>
  247. 注:乐团于下学期正式开始训练,训练时间下 学期开学前另行通知,训练时间会与学校其他
  248. 社团错开,家长无需担心时间冲突问题。
  249. </p> */}
  250. <div v-html={messageContent.value}></div>
  251. {/* {registerDisplay.value && <Button class={styles.submitBtn} onClick={onSubmit}></Button>} */}
  252. </div>
  253. </div>
  254. </div>
  255. );
  256. }
  257. });