short_video.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <view class="video_box">
  3. <video v-if="play"
  4. x5-video-player-type="h5-page" webkit-playsinline="true"
  5. x5-video-orientation="portraint"
  6. class="video_file"
  7. :id="`video_${src}`"
  8. :ref="`video_${src}`"
  9. :src="src"
  10. loop
  11. :show-play-btn="false"
  12. :show-center-play-btn="false"
  13. :controls="false"
  14. :enable-progress-gesture="false"
  15. object-fit="contain"
  16. :autoplay="play"
  17. @timeupdate="onScheduleChange"
  18. @waiting="onWaiting"
  19. ></video>
  20. <image v-else class="video_file" src="../../static/images/template.png" mode=""></image>
  21. <!-- 播放按钮 -->
  22. <view class="play_btn" @click="onPlay">
  23. <image class="icon_play" v-if="playState == 1000" src="../../static/images/ic_play.png" mode="aspectFit"></image>
  24. </view>
  25. <view class="play_schedule">
  26. <view class="schedule" :style="{ width: schedule + '%' }"><view v-if="progressDrag" class="progress_drag_dot"></view></view>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. export default {
  32. props: {
  33. src: {
  34. type: String,
  35. default: ''
  36. },
  37. play: {
  38. type: Boolean,
  39. default: false
  40. },
  41. poster: {
  42. //视频封面的图片
  43. type: String,
  44. default: ''
  45. },
  46. progress: {
  47. type: Number,
  48. default: 0
  49. },
  50. progressValue: {
  51. type: Number,
  52. default: 0
  53. }
  54. },
  55. data() {
  56. return {
  57. schedule: 0,
  58. // 1000 待播放
  59. // 2000 播放中
  60. // 3000 播放缓冲中
  61. playState: 1000,
  62. // 是否拖动进度
  63. progressDrag: false,
  64. // 视频总长度
  65. duration: 0
  66. };
  67. },
  68. watch: {
  69. play(val) {
  70. // console.log(val,"watch")
  71. if (val) {
  72. setTimeout(() => {
  73. this.videoCtx.play();
  74. this.playState = 2000;
  75. }, 300);
  76. } else {
  77. setTimeout(() => {
  78. this.videoCtx.pause();
  79. this.videoCtx.seek(0);
  80. this.playState = 1000;
  81. this.schedule = 0;
  82. },100);
  83. }
  84. },
  85. progress(val) {
  86. if (this.play) {
  87. if (val == 0) {
  88. this.progressDrag = true;
  89. } else {
  90. this.schedule = val;
  91. }
  92. }
  93. },
  94. progressValue(val) {
  95. if (this.play) {
  96. this.schedule = val;
  97. this.progressDrag = false;
  98. this.videoCtx.seek(this.duration * (val / 100));
  99. }
  100. }
  101. },
  102. mounted() {
  103. this.videoCtx = uni.createVideoContext(`video_${this.src}`, this);
  104. // this.videoCtx.requestFullScreen();
  105. if(this.play){
  106. this.playState = 2000;
  107. }
  108. },
  109. methods: {
  110. onScheduleChange(e) {
  111. this.duration = e.detail.duration;
  112. if (!this.progressDrag) {
  113. this.schedule = (e.detail.currentTime / e.detail.duration) * 100;
  114. }
  115. },
  116. onPlay() {
  117. if (this.playState == 2000) {
  118. this.videoCtx.pause();
  119. this.playState = 1000;
  120. } else if (this.playState == 1000) {
  121. this.videoCtx.play();
  122. this.playState = 2000;
  123. } else if (this.playState == 3000) {
  124. this.videoCtx.play();
  125. this.playState = 2000;
  126. }
  127. },
  128. // 视频进入缓冲中
  129. onWaiting() {
  130. this.playState = 3000;
  131. }
  132. }
  133. };
  134. </script>
  135. <style lang="scss" scoped>
  136. // @import '@/style/mixin.scss';
  137. .video_box {
  138. position: relative;
  139. width: 100%;
  140. }
  141. .video_file {
  142. width: 100%;
  143. height: calc(100vh - var(--window-bottom));
  144. }
  145. .play_schedule {
  146. position: absolute;
  147. bottom: 6rpx;
  148. left: 0;
  149. height: 2rpx;
  150. width: 100%;
  151. background-color: rgba(255, 255, 255, 0.2);
  152. z-index: 3;
  153. }
  154. .schedule {
  155. background-color: #fff;
  156. height: 2rpx;
  157. width: 0%;
  158. position: relative;
  159. }
  160. .progress_drag_dot {
  161. position: absolute;
  162. right: -8rpx;
  163. top: -6rpx;
  164. width: 16rpx;
  165. height: 16rpx;
  166. border-radius: 50%;
  167. background-color: #fff;
  168. }
  169. .play_btn {
  170. position: absolute;
  171. top: 0;
  172. left: 0;
  173. width: 100%;
  174. height: 100%;
  175. justify-content: center;
  176. align-items: center;
  177. }
  178. .icon_play {
  179. width: 90rpx;
  180. height: 90rpx;
  181. }
  182. </style>