200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Vue
		
	
	
| <template>
 | ||
|   <view class="ui-video-wrap">
 | ||
|     <video
 | ||
|       :id="`sVideo${uid}`"
 | ||
|       class="radius"
 | ||
|       :style="[{ height: height + 'rpx' }]"
 | ||
|       :src="src"
 | ||
|       controls
 | ||
|       object-fit="contain"
 | ||
|       :enable-progress-gesture="state.enableProgressGesture"
 | ||
|       :initial-time="initialTime"
 | ||
|       x5-video-player-type="h5"
 | ||
|       x-webkit-airplay="allow"
 | ||
|       webkit-playsinline="true"
 | ||
|       @error="videoErrorCallback"
 | ||
|       @timeupdate="timeupdate"
 | ||
|       @play="play"
 | ||
|       @pause="pause"
 | ||
|       @ended="end"
 | ||
|       :poster="poster"
 | ||
|       :autoplay="autoplay"
 | ||
|     >
 | ||
|       <!-- #ifdef APP-PLUS -->
 | ||
|       <cover-view :style="{ transform: 'translateX(' + moveX + 'px)' }" />
 | ||
|       <!-- #endif -->
 | ||
|     </video>
 | ||
|   </view>
 | ||
| </template>
 | ||
| <script setup>
 | ||
|   /**
 | ||
|    * 视频组件
 | ||
|    *
 | ||
|    * @property {Number} uid = 0 						- 当前轮播下标,还用来标记视频Id
 | ||
|    * @property {Number} moveX = 0 					- app端轮播滑动距离
 | ||
|    * @property {String} height = 300 					- 高度(rpx)
 | ||
|    * @property {String} width = 750 					- 宽度(rpx)
 | ||
|    * @property {Number} initialTime = 0 				- 指定视频播放位置
 | ||
|    * @property {String} videoSize						- 视频大小
 | ||
|    * @property {String} src 							- 视频播放地址
 | ||
|    * @property {String} poster 						- 视频封面
 | ||
|    *
 | ||
|    *
 | ||
|    */
 | ||
| 
 | ||
|   import { reactive, nextTick, getCurrentInstance } from 'vue';
 | ||
|   import sheep from '@/sheep';
 | ||
|   const vm = getCurrentInstance();
 | ||
| 
 | ||
|   // 数据
 | ||
|   const state = reactive({
 | ||
|     // #ifdef APP-PLUS
 | ||
|     enableProgressGesture: true, // 手势滑动
 | ||
|     // #endif
 | ||
|     // #ifndef APP-PLUS
 | ||
|     enableProgressGesture: false, // 手势滑动
 | ||
|     // #endif
 | ||
|     showModal: false, // 弹框
 | ||
|   });
 | ||
| 
 | ||
|   // 接收参数
 | ||
|   const props = defineProps({
 | ||
|     moveX: {
 | ||
|       type: [Number],
 | ||
|       default: 0,
 | ||
|     },
 | ||
|     // 下标索引
 | ||
|     uid: {
 | ||
|       type: [Number, String],
 | ||
|       default: 0,
 | ||
|     },
 | ||
|     // 视频高度
 | ||
|     height: {
 | ||
|       type: Number,
 | ||
|       default: 300,
 | ||
|     },
 | ||
|     // 视频宽度
 | ||
|     width: {
 | ||
|       type: Number,
 | ||
|       default: 750,
 | ||
|     },
 | ||
|     // 指定视频初始播放位置,单位为秒(s)
 | ||
|     initialTime: {
 | ||
|       type: Number,
 | ||
|       default: 1,
 | ||
|     },
 | ||
|     src: {
 | ||
|       type: String,
 | ||
|       default: '',
 | ||
|     },
 | ||
|     poster: {
 | ||
|       type: String,
 | ||
|       default: 'https://img1.baidu.com/it/u=1601695551,235775011&fm=26&fmt=auto',
 | ||
|     },
 | ||
|     autoplay: {
 | ||
|       type: Boolean,
 | ||
|       default: false,
 | ||
|     }
 | ||
|   });
 | ||
| 
 | ||
|   // 事件
 | ||
|   const emits = defineEmits(['videoTimeupdate']);
 | ||
| 
 | ||
|   // 播放进度变化时触发,播放进度传给父组件
 | ||
|   const timeupdate = (e) => {
 | ||
|     emits('videoTimeupdate', e);
 | ||
|   };
 | ||
|   const videoErrorCallback = (e) => {
 | ||
|     console.log('视频错误信息:', e.target.errMsg);
 | ||
|   };
 | ||
|   // 当开始/继续播放时触发play事件
 | ||
|   const play = () => {
 | ||
|     console.log('视频开始');
 | ||
|   };
 | ||
|   // 当暂停播放时触发 pause 事件
 | ||
|   const pause = () => {
 | ||
|     console.log('视频暂停');
 | ||
|   };
 | ||
|   // 视频结束触发end 时间
 | ||
|   const end = () => {
 | ||
|     console.log('视频结束');
 | ||
|   };
 | ||
|   // 开始播放
 | ||
|   const startPlay = () => {
 | ||
|     nextTick(() => {
 | ||
|       const video = uni.createVideoContext(`sVideo${props.index}`, vm);
 | ||
|       video.play();
 | ||
|     });
 | ||
|   };
 | ||
| 
 | ||
|   //暂停播放
 | ||
|   const pausePlay = () => {
 | ||
|     const video = uni.createVideoContext(`sVideo${props.index}`, vm);
 | ||
|     video.pause();
 | ||
|   };
 | ||
| 
 | ||
|   // 播放前拦截
 | ||
|   const beforePlay = () => {
 | ||
|     uni.getNetworkType({
 | ||
|       success: (res) => {
 | ||
|         const networkType = res.networkType;
 | ||
|         // if (networkType === 'wifi' || networkType === 'ethernet') {
 | ||
|         //   startPlay();
 | ||
|         // } else {
 | ||
|         //   uni.showModal({
 | ||
|         //     title: '提示',
 | ||
|         //     content: `当前为移动网络,播放视频需消耗手机流量,是否继续播放?${networkType}`,
 | ||
|         //     success: (res) => {
 | ||
|         //       if (res.confirm) {
 | ||
|         //         startPlay();
 | ||
|         //       } else {
 | ||
|         //         state.isplay = false;
 | ||
|         //       }
 | ||
|         //     },
 | ||
|         //   });
 | ||
|         //   sheep.$helper.toast('正在消耗流量播放');
 | ||
|         //   startPlay();
 | ||
|         // }
 | ||
|         startPlay();
 | ||
|       },
 | ||
|     });
 | ||
|   };
 | ||
| 
 | ||
|   // 抛出方法供父组件调用
 | ||
|   defineExpose({
 | ||
|     pausePlay,
 | ||
|   });
 | ||
| </script>
 | ||
| <style lang="scss" scoped>
 | ||
|   .radius {
 | ||
|     width: 100%;
 | ||
|   }
 | ||
|   .ui-video-wrap {
 | ||
|     display: flex;
 | ||
|     align-items: center;
 | ||
|     justify-content: center;
 | ||
| 
 | ||
|     .poster-wrap {
 | ||
|       position: relative;
 | ||
|       width: 100%;
 | ||
|       height: 100%;
 | ||
| 
 | ||
|       .poster-image {
 | ||
|         width: 100%;
 | ||
|         height: 100%;
 | ||
|       }
 | ||
| 
 | ||
|       .play-icon {
 | ||
|         position: absolute;
 | ||
|         left: 50%;
 | ||
|         top: 50%;
 | ||
|         width: 80rpx;
 | ||
|         height: 80rpx;
 | ||
|         transform: translate(-50%, -50%);
 | ||
|         background-color: rgba($color: #000000, $alpha: 0.1);
 | ||
|         border-radius: 50%;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| </style>
 |