208 lines
4.2 KiB
Vue
208 lines
4.2 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="video-page">
|
|||
|
|
<view class="video-container">
|
|||
|
|
<video
|
|||
|
|
:id="videoId"
|
|||
|
|
:src="videoUrl"
|
|||
|
|
class="video-player"
|
|||
|
|
controls
|
|||
|
|
autoplay
|
|||
|
|
enable-play-gesture
|
|||
|
|
show-center-play-btn
|
|||
|
|
object-fit="contain"
|
|||
|
|
direction="90"
|
|||
|
|
@fullscreenchange="onFullscreenChange"
|
|||
|
|
@play="onPlay"
|
|||
|
|
@pause="onPause"
|
|||
|
|
@click="onVideoClick"
|
|||
|
|
@loadedmetadata="onLoadedMetadata">
|
|||
|
|
</video>
|
|||
|
|
</view>
|
|||
|
|
<view class="close-btn" @click="goBack" v-if="!isFullscreen">
|
|||
|
|
<text>×</text>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
videoUrl: '',
|
|||
|
|
videoId: 'videoPlayer',
|
|||
|
|
isFullscreen: false
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onLoad(options) {
|
|||
|
|
// 获取传递过来的视频链接
|
|||
|
|
if (options.url) {
|
|||
|
|
this.videoUrl = decodeURIComponent(options.url)
|
|||
|
|
}
|
|||
|
|
// 设置横屏
|
|||
|
|
this.setOrientation('landscape')
|
|||
|
|
},
|
|||
|
|
onReady() {
|
|||
|
|
// 页面加载完成后自动进入全屏横屏播放
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.requestFullScreen()
|
|||
|
|
}, 500)
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
onUnload() {
|
|||
|
|
// 页面卸载时恢复竖屏
|
|||
|
|
this.setOrientation('portrait')
|
|||
|
|
},
|
|||
|
|
onBackPress() {
|
|||
|
|
// 拦截返回按钮
|
|||
|
|
if (this.isFullscreen) {
|
|||
|
|
// 如果全屏,先退出全屏
|
|||
|
|
this.exitFullScreen()
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
// 恢复竖屏
|
|||
|
|
this.setOrientation('portrait')
|
|||
|
|
return false
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
// 设置屏幕方向
|
|||
|
|
setOrientation(orientation) {
|
|||
|
|
// #ifdef APP-PLUS
|
|||
|
|
plus.screen.lockOrientation(orientation === 'landscape' ? 'landscape-primary' : 'portrait-primary')
|
|||
|
|
// #endif
|
|||
|
|
|
|||
|
|
// #ifdef H5
|
|||
|
|
// H5端可以通过CSS控制,但需要用户手动横屏
|
|||
|
|
// #endif
|
|||
|
|
},
|
|||
|
|
// 视频元数据加载完成
|
|||
|
|
onLoadedMetadata() {
|
|||
|
|
// 元数据加载完成后,尝试自动播放
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.playVideo()
|
|||
|
|
}, 300)
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
// 全屏状态变化
|
|||
|
|
onFullscreenChange(e) {
|
|||
|
|
this.isFullscreen = e.detail.fullScreen
|
|||
|
|
if (this.isFullscreen) {
|
|||
|
|
// 进入全屏后自动播放
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.playVideo()
|
|||
|
|
}, 300)
|
|||
|
|
})
|
|||
|
|
} else {
|
|||
|
|
// 退出全屏时返回上一页
|
|||
|
|
this.setOrientation('portrait')
|
|||
|
|
setTimeout(() => {
|
|||
|
|
uni.navigateBack()
|
|||
|
|
}, 300)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 播放事件
|
|||
|
|
onPlay() {
|
|||
|
|
// 播放时确保全屏
|
|||
|
|
if (!this.isFullscreen) {
|
|||
|
|
this.requestFullScreen()
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 暂停事件
|
|||
|
|
onPause() {
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
// 视频点击事件
|
|||
|
|
onVideoClick() {
|
|||
|
|
// 点击视频时进入全屏
|
|||
|
|
if (!this.isFullscreen) {
|
|||
|
|
this.requestFullScreen()
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 播放视频
|
|||
|
|
playVideo() {
|
|||
|
|
const videoContext = uni.createVideoContext(this.videoId, this)
|
|||
|
|
videoContext.play()
|
|||
|
|
},
|
|||
|
|
// 请求全屏
|
|||
|
|
requestFullScreen() {
|
|||
|
|
const videoContext = uni.createVideoContext(this.videoId, this)
|
|||
|
|
videoContext.requestFullScreen({
|
|||
|
|
direction: 90 // 横屏(90度)
|
|||
|
|
})
|
|||
|
|
// 进入全屏后自动播放
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.playVideo()
|
|||
|
|
}, 500)
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
// 退出全屏
|
|||
|
|
exitFullScreen() {
|
|||
|
|
const videoContext = uni.createVideoContext(this.videoId, this)
|
|||
|
|
videoContext.exitFullScreen()
|
|||
|
|
},
|
|||
|
|
// 返回
|
|||
|
|
goBack() {
|
|||
|
|
if (this.isFullscreen) {
|
|||
|
|
this.exitFullScreen()
|
|||
|
|
} else {
|
|||
|
|
// 恢复竖屏
|
|||
|
|
this.setOrientation('portrait')
|
|||
|
|
uni.navigateBack()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss">
|
|||
|
|
.video-page {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100vh;
|
|||
|
|
background-color: #000;
|
|||
|
|
position: relative;
|
|||
|
|
|
|||
|
|
.video-container {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100vh;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
|
|||
|
|
.video-player {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.close-btn {
|
|||
|
|
position: fixed;
|
|||
|
|
top: 40rpx;
|
|||
|
|
right: 40rpx;
|
|||
|
|
width: 80rpx;
|
|||
|
|
height: 80rpx;
|
|||
|
|
background-color: rgba(255, 255, 255, 0.2);
|
|||
|
|
border-radius: 50%;
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
z-index: 9999;
|
|||
|
|
transition: all 0.3s;
|
|||
|
|
|
|||
|
|
&:active {
|
|||
|
|
background-color: rgba(255, 107, 153, 0.6);
|
|||
|
|
transform: scale(0.95);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
text {
|
|||
|
|
font-size: 56rpx;
|
|||
|
|
color: #fff;
|
|||
|
|
line-height: 1;
|
|||
|
|
font-weight: 300;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|