<template>
|
<view class="fullscreen-page" :style="pageStyle">
|
<video
|
id="fullscreen-live-player"
|
class="fullscreen-video"
|
:style="videoStyle"
|
:src="videoUrl"
|
:poster="poster"
|
:initial-time="initialTime"
|
:controls="false"
|
:autoplay="true"
|
:show-center-play-btn="false"
|
:show-fullscreen-btn="false"
|
:show-play-btn="false"
|
:show-progress="false"
|
:enable-progress-gesture="false"
|
object-fit="contain"
|
@loadedmetadata="handleVideoReady"
|
@canplay="handleVideoReady"
|
></video>
|
<view class="back-button" @click="closePlayer">
|
<view class="back-button-arrow"></view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
const PLAYER_ID = 'fullscreen-live-player'
|
|
export default {
|
data() {
|
return {
|
videoUrl: '',
|
poster: '',
|
initialTime: 0,
|
hasPrepared: false,
|
playerContext: null,
|
windowWidth: 375,
|
windowHeight: 667,
|
}
|
},
|
computed: {
|
pageStyle() {
|
return {
|
width: `${this.windowWidth}px`,
|
height: `${this.windowHeight}px`,
|
}
|
},
|
videoStyle() {
|
return {
|
width: `${this.windowWidth}px`,
|
height: `${this.windowHeight}px`,
|
}
|
},
|
},
|
onLoad(options) {
|
this.refreshWindowSize()
|
this.lockLandscape()
|
this.videoUrl = decodeRouteText(options && options.videoUrl)
|
this.poster = decodeRouteText(options && options.poster)
|
this.initialTime = normalizeNumber(options && options.initialTime)
|
},
|
onReady() {
|
this.playerContext = uni.createVideoContext(PLAYER_ID, this)
|
this.refreshWindowSize()
|
this.playerContext.play()
|
},
|
onResize(event) {
|
// 横屏旋转是异步的,以窗口事件为准,避免固定延时读到竖屏尺寸。
|
this.refreshWindowSize(event && event.size)
|
},
|
onUnload() {
|
this.playerContext && this.playerContext.pause()
|
this.lockPortrait()
|
},
|
onBackPress() {
|
this.playerContext && this.playerContext.pause()
|
this.lockPortrait()
|
return false
|
},
|
methods: {
|
refreshWindowSize(size) {
|
const windowInfo = size || uni.getSystemInfoSync()
|
this.windowWidth = windowInfo.windowWidth || this.windowWidth
|
this.windowHeight = windowInfo.windowHeight || this.windowHeight
|
},
|
handleVideoReady(event) {
|
if (this.hasPrepared) {
|
return
|
}
|
this.hasPrepared = true
|
const duration = normalizeNumber(event && event.detail && event.detail.duration)
|
if (this.initialTime > 0 && duration > 0 && this.initialTime < duration) {
|
this.playerContext && this.playerContext.seek(this.initialTime)
|
}
|
this.playerContext && this.playerContext.play()
|
},
|
lockLandscape() {
|
try {
|
if (typeof plus !== 'undefined' && plus.screen) {
|
plus.screen.lockOrientation('landscape-primary')
|
}
|
} catch (error) {}
|
},
|
lockPortrait() {
|
try {
|
if (typeof plus !== 'undefined' && plus.screen) {
|
plus.screen.lockOrientation('portrait-primary')
|
}
|
} catch (error) {}
|
},
|
closePlayer() {
|
this.lockPortrait()
|
setTimeout(() => {
|
uni.navigateBack()
|
}, 120)
|
},
|
},
|
}
|
|
function decodeRouteText(value) {
|
if (typeof value !== 'string') {
|
return ''
|
}
|
try {
|
return decodeURIComponent(value)
|
} catch (error) {
|
return value
|
}
|
}
|
|
function normalizeNumber(value) {
|
const numberValue = Number(value || 0)
|
return Number.isFinite(numberValue) && numberValue > 0 ? Math.floor(numberValue) : 0
|
}
|
</script>
|
|
<style scoped>
|
.fullscreen-page {
|
position: relative;
|
background-color: #000000;
|
}
|
|
.fullscreen-video {
|
position: absolute;
|
left: 0;
|
top: 0;
|
background-color: #000000;
|
}
|
|
.back-button {
|
/* 横屏使用固定尺寸,避免 rpx 随窗口宽度放大按钮。 */
|
position: absolute;
|
left: 32px;
|
top: 36px;
|
z-index: 9999;
|
width: 44px;
|
height: 44px;
|
border-radius: 22px;
|
background-color: rgba(0, 0, 0, 0.45);
|
align-items: center;
|
justify-content: center;
|
}
|
|
.back-button-arrow {
|
width: 12px;
|
height: 12px;
|
margin-left: 5px;
|
border-left-width: 2px;
|
border-bottom-width: 2px;
|
border-style: solid;
|
border-color: #ffffff;
|
transform: rotate(45deg);
|
}
|
</style>
|