综合办公系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

me-video.vue 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <!-- 视频组件: <me-video src="视频地址" poster="封面图"></me-video>
  2. video标签在APP端是原生组件, 真机APP端下拉时会渲染不及时, 出现悬浮错位现象;
  3. me-video组件, 未播放时自动展示image封面, 播放时才显示video, 提高性能; 如果播放中执行下拉,会自动显示封面, 避免视频下拉悬浮错位;
  4. -->
  5. <template>
  6. <view class="me-video" :style="{width:width, height:height}">
  7. <!-- 播放的时候才渲染video标签 -->
  8. <video v-if="showVideo" ref="videoRef" class="video" :class="{'full-play': fullplay&&!autoplay, 'mescroll-dowload': mescrollDownLoad}" :src="src" autoplay :loop="loop" @click="videoClick" x5-playsinline="true" x5-video-player-type="h5" playsinline="true" webkit-playsinline="true" x5-video-player-fullscreen="false"></video>
  9. <!-- 播放按钮 -->
  10. <view v-else class="btn-play"> <view class="triangle"></view> </view>
  11. <!-- 封面 -->
  12. <image v-if="(!showVideo || mescrollDownLoad) && poster" class="poster" :src="poster" @click="play()" mode="aspectFit"></image>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. props: {
  18. src: String, // 视频地址
  19. poster: String, // 封面图
  20. autoplay: { // 是否自动播放
  21. type: Boolean,
  22. default(){
  23. return false
  24. }
  25. },
  26. fullplay: { // 是否全屏播放,默认不全屏
  27. type: Boolean,
  28. default(){
  29. return false
  30. }
  31. },
  32. loop: { // 是否循环播放
  33. type: Boolean,
  34. default(){
  35. return true // 循环播放可避免Android微信播放完毕显示广告
  36. }
  37. },
  38. width: { // 宽度 (需带单位,支持格式: '100%', '300px', '300rpx')
  39. type: String,
  40. default: "100%"
  41. },
  42. height: { // 高度 (需带单位,支持格式: '100%', '300px', '300rpx')
  43. type: String,
  44. default: "225px"
  45. },
  46. mescroll: { // mescroll对象,APP端下拉刷新时显示封面,隐藏视频.缓解APP端视频下拉悬浮错位问题
  47. type: Object,
  48. default(){
  49. return {}
  50. }
  51. }
  52. },
  53. data() {
  54. return {
  55. showVideo: this.autoplay // 是否播放视频
  56. }
  57. },
  58. computed: {
  59. // 是否下拉中 (下拉隐藏视频,显示封面, 仅APP端生效)
  60. mescrollDownLoad() {
  61. // #ifdef APP-PLUS
  62. return this.mescroll.downLoadType
  63. // #endif
  64. // #ifndef APP-PLUS
  65. return false
  66. // #endif
  67. }
  68. },
  69. watch: {
  70. autoplay(val) {
  71. if(val) this.play()
  72. }
  73. },
  74. methods: {
  75. // 播放
  76. play(){
  77. this.showVideo = true
  78. this.wxAutoPlay()
  79. },
  80. // 视频点击事件
  81. videoClick(){
  82. // 全屏播放时,点击视频退出
  83. if(this.fullplay) this.showVideo = false
  84. },
  85. // 解决微信端视频无法自动播放的问题
  86. wxAutoPlay(){
  87. // #ifdef H5
  88. // 微信端
  89. if(navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){
  90. // iOS
  91. let head = document.getElementsByTagName("head")[0]
  92. let wxscript = document.createElement("script");
  93. wxscript.type = "text/javascript"
  94. wxscript.src = "https://res.wx.qq.com/open/js/jweixin-1.6.0.js"
  95. head.appendChild(wxscript)
  96. let vm = this
  97. let doPlay = function(){
  98. vm.$refs.videoRef && vm.$refs.videoRef.play()
  99. }
  100. wxscript.onload = function(){
  101. window.wx.config({
  102. debug: !1,
  103. appId: "",
  104. timestamp: 1,
  105. nonceStr: "",
  106. signature: "",
  107. jsApiList: []
  108. })
  109. window.wx.ready(doPlay)
  110. }
  111. // Android
  112. document.addEventListener("WeixinJSBridgeReady", doPlay, false);
  113. // 先尝试播放
  114. setTimeout(()=>{
  115. doPlay()
  116. },20)
  117. }
  118. // #endif
  119. }
  120. }
  121. }
  122. </script>
  123. <style lang="scss">
  124. .me-video{
  125. position: relative;
  126. background-color: #000;
  127. overflow: hidden;
  128. // 播放按钮
  129. .btn-play{
  130. z-index: 9;
  131. position: absolute;
  132. left: 50%;
  133. top: 50%;
  134. transform: translate(-50%, -50%);
  135. width: 100rpx;
  136. height: 100rpx;
  137. border-radius: 50%;
  138. background-color: rgba(0,0,0,.75);
  139. pointer-events: none;
  140. .triangle{
  141. position: absolute;
  142. left: 50%;
  143. top: 50%;
  144. transform: translate(-25%, -50%);
  145. width: 0;
  146. height: 0;
  147. border-top: 16rpx solid transparent;
  148. border-left: 24rpx solid #fff;
  149. border-bottom: 16rpx solid transparent;
  150. }
  151. }
  152. // 封面图
  153. .poster{
  154. width: 100%;
  155. height: 100%;
  156. vertical-align: bottom;
  157. }
  158. // 视频 (默认非全屏播放)
  159. .video{
  160. z-index: 8;
  161. position: absolute;
  162. top: 0;
  163. left: 0;
  164. width: 100%;
  165. height: 100%;
  166. // 全屏播放
  167. &.full-play{
  168. z-index: 999;
  169. position: fixed;
  170. }
  171. // 下拉时隐藏视频
  172. &.mescroll-dowload{
  173. display: none;
  174. }
  175. }
  176. }
  177. </style>