chore:H5和小程序都可以自己分辨横竖屏

This commit is contained in:
2026-03-28 17:38:26 +08:00
parent 50ee885b74
commit 857f295923

View File

@@ -2,33 +2,38 @@
<view class="video-container" :style="containerStyle">
<!-- H5端使用原生video标签 -->
<!-- #ifdef H5 -->
<video
<video
ref="videoRef"
data-component-name="diy-video"
class="diy-video h5-video"
:src="getVideoUrl()"
:poster="$util.img(value.imageUrl)"
:style="videoWarpCss"
data-component-name="diy-video"
class="diy-video h5-video"
:src="videoUrl"
:poster="posterUrl"
:style="videoWarpCss"
controls
preload="auto"
preload="metadata"
@loadedmetadata="onVideoLoaded"
@click="handlerClick(getVideoUrl())"
@click="handlerClick(videoUrl)"
></video>
<!-- #endif -->
<!-- 微信小程序端使用uni-app的video组件 -->
<!-- #ifdef MP-WEIXIN -->
<video
<video
ref="videoRef"
data-component-name="diy-video"
class="diy-video mp-video"
:src="getVideoUrl()"
:poster="$util.img(value.imageUrl)"
:style="videoWarpCss"
objectFit="contain"
data-component-name="diy-video"
class="diy-video mp-video"
:src="videoUrl"
:poster="posterUrl"
:style="videoWarpCss"
objectFit="cover"
controls
muted
autoplay
show-center-play-btn
@loadedmetadata="onVideoLoaded"
@tap="handlerClick(getVideoUrl())"
@play="onVideoPlay"
@pause="onVideoPause"
@error="onVideoError"
></video>
<!-- #endif -->
</view>
@@ -46,19 +51,29 @@ export default {
},
data() {
return {
videoRatio: null // 视频比例:'landscape'(横屏)或 'portrait'(竖屏)
videoRatio: null, // 视频比例:'landscape'(横屏)或 'portrait'(竖屏)
videoUrl: '',
posterUrl: ''
};
},
created() { },
created() {
this.initVideoData();
},
mixins: [DiyMinx],
watch: {
// 组件刷新监听
componentRefresh: function (nval) { }
value: {
immediate: true,
handler(newVal) {
if (newVal) {
this.initVideoData();
}
}
}
},
computed: {
videoWarpCss: function () {
var obj = '';
if (this.value.componentAngle == 'round') {
if (this.value && this.value.componentAngle == 'round') {
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
@@ -69,26 +84,33 @@ export default {
// 动态计算容器比例
containerStyle() {
let style = '';
if (this.videoRatio) {
// 已加载并识别出比例
if (this.videoRatio === 'portrait') {
// 竖屏视频:9/16比例
style += 'aspect-ratio: 9 / 16;';
} else {
// 横屏视频:16/9比例
style += 'aspect-ratio: 16 / 9;';
}
if (this.videoRatio === 'landscape') {
// 横屏视频:16/9比例
style += 'aspect-ratio: 16 / 9;';
} else if (this.videoRatio === 'portrait') {
// 竖屏视频:9/16比例
style += 'aspect-ratio: 9 / 16;';
} else {
// 未加载完成 → 默认使用竖屏比例(适合短视频)
// 未加载完成 → 默认使用竖屏比例
style += 'aspect-ratio: 9 / 16;';
}
return style;
}
},
methods: {
// 获取视频URL,根据格式决定是否使用$util.img()处理
// 初始化视频数据
initVideoData() {
this.videoUrl = this.getVideoUrl();
this.posterUrl = this.getPosterUrl();
// H5端:预加载视频获取宽高
// #ifdef H5
this.preloadVideoForRatio();
// #endif
},
// 获取视频URL
getVideoUrl() {
if (!this.value || !this.value.videoUrl) return '';
const videoUrl = this.value.videoUrl;
@@ -99,42 +121,89 @@ export default {
// 否则使用$util.img()处理
return this.$util.img(videoUrl);
},
// 视频加载完成事件
onVideoLoaded(event) {
this.$nextTick(() => {
let width = 0;
let height = 0;
// H5端:通过video元素获取真实视频宽高
// #ifdef H5
const video = this.$refs.videoRef;
if (video) {
width = video.videoWidth || 0;
height = video.videoHeight || 0;
}
// #endif
// 微信小程序端:通过事件对象获取视频宽高
// #ifdef MP-WEIXIN
if (event && event.detail) {
width = event.detail.width || 0;
height = event.detail.height || 0;
}
// #endif
// 获取封面图URL
getPosterUrl() {
if (!this.value || !this.value.imageUrl) return '';
return this.$util.img(this.value.imageUrl);
},
// H5端:预加载视频获取宽高比例
preloadVideoForRatio() {
const videoUrl = this.videoUrl;
if (!videoUrl) return;
console.log('H5端预加载视频获取比例:', videoUrl);
const video = document.createElement('video');
video.preload = 'metadata';
video.src = videoUrl;
video.muted = true;
video.playsInline = true;
video.addEventListener('loadedmetadata', () => {
const width = video.videoWidth;
const height = video.videoHeight;
console.log('H5端预加载获取视频宽高:', width, height);
if (width && height) {
// 判断视频方向:宽度 >= 高度为横屏,否则为竖屏
this.videoRatio = width >= height ? 'landscape' : 'portrait';
console.log(`视频宽高比检测: ${width}x${height}, 比例: ${this.videoRatio}`);
} else {
// 获取失败,默认竖屏
this.videoRatio = 'portrait';
console.log('视频宽高比检测失败,默认使用竖屏比例');
console.log('H5端视频比例判定:', this.videoRatio, width >= height ? '横屏' : '竖屏');
}
});
video.addEventListener('error', (e) => {
console.error('H5端预加载视频失败:', e);
});
// 触发加载
video.load();
},
// 视频加载完成事件(组件内video标签)
onVideoLoaded(event) {
console.log('视频组件 loadedmetadata 事件触发');
let width = 0;
let height = 0;
// #ifdef H5
if (event && event.target) {
width = event.target.videoWidth || 0;
height = event.target.videoHeight || 0;
console.log('H5端组件视频宽高:', width, height);
}
// #endif
// #ifdef MP-WEIXIN
if (event && event.detail) {
width = event.detail.width || 0;
height = event.detail.height || 0;
console.log('微信小程序端视频宽高:', width, height);
}
// #endif
if (width && height) {
this.videoRatio = width >= height ? 'landscape' : 'portrait';
console.log('视频比例最终判定:', this.videoRatio);
}
},
// 视频播放事件
onVideoPlay() {
console.log('视频开始播放');
},
// 视频暂停事件
onVideoPause() {
console.log('视频暂停');
},
// 视频错误事件
onVideoError(event) {
console.error('视频加载失败:', event);
},
async handlerClick(videoUrl) {
await this.__$emitEvent({
eventName: 'video-tap', data: videoUrl, promiseCallback: (event, handler, awaitedResult) => {
@@ -151,20 +220,20 @@ export default {
width: 100%;
position: relative;
overflow: hidden;
background-color: #000;
}
/* 基础样式 */
.diy-video {
width: 100%;
height: 100%;
display: block;
}
/* H5端样式 */
/* #ifdef H5 */
.h5-video {
display: block;
object-fit: contain; /* 改为contain以保持视频比例 */
background-color: #000; /* 添加背景色 */
object-fit: cover;
}
/* #endif */
@@ -174,16 +243,6 @@ export default {
position: absolute;
top: 0;
left: 0;
background-color: #000; /* 添加背景色 */
}
.mp-video>>>.uni-video-container {
background-color: transparent;
height: 100%;
}
.mp-video>>>.uni-video-control {
display: flex;
}
/* #endif */
</style>
</style>