<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) => { // sheep.$helper.toast(e) uni.showToast({ title: JSON.stringify(e), icon: 'none', }); 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>