| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- <template>
- <view>
- <DomVideoPlayer class="video" :style="{ 'height': height + 'px' }" :ref="`domVideoPlayer_${current}`" object-fit='contain'
- :controls="controls" :autoplay="autoplay" :loop="loop" :src="item.src" :playback-rate="playbackRate"
- @play="onPlay" @pause="onPause" @ended="onEnded" @timeupdate="onTimeUpdate" @durationchange="onDurationChange"
- @ratechange="onRateChange" @fullscreenchange="onFullscreenChange" @tap.stop="change" />
- <view class="play-btn" :style="{ left: `${width / 2}px`, top: `${height / 2}px` }" v-if="showPlayBtn">
- <up-icon name="play-right-fill" size="16" color="var(--light)"></up-icon>
- </view>
- <!-- loading -->
- <image class="loading" :style="{ left: `${width / 2}px`, top: `${height / 2}px` }" src="@/static/loading.gif"
- v-if="loading">
- </image>
- <view class="info" @click.stop="$emit('showMulu')">
- <text class="text title">@{{ item.title }}</text>
- <text class="text" style="margin-top: 25rpx;font-size: 26rpx;line-height: 40rpx;">{{ item.desc ||
- '讲述温暖出行故事,描绘人间烟火,大锁与陈珂从原来的两条“平行线”,变成了感情不断升温的情侣...'}}</text>
- </view>
- <view class="btns" :style="{ height: height + 'px' }" @click.stop>
- <image class="toux" style="margin-bottom: 40rpx;" src="@/static/tx.png"></image>
- <image class="btn" :src="isZan ? '/static/dianzan_h.png' : '/static/dianzan.png'" @click="isZan = !isZan">
- </image>
- <text class="text">0</text>
- <image class="btn" src="@/static/pinglun.png" @click.stop="emit('showPinglun')"></image>
- <text class="text">0</text>
- <image class="btn" :src="isSc ? '/static/shoucang_h.png' : '/static/shoucang.png'" @click="isSc = !isSc">
- </image>
- <text class="text">0</text>
- <image class="btn" src="@/static/fenxiang.png?v=6"></image>
- </view>
- <view class="progress">
- <view class="line" :style="{ width: lineWidth + 'px' }"></view>
- </view>
- <view class="_duration" @click.stop>
- <view style="flex-direction: row;flex: 1;">
- <text class="text">{{ currentTime ? currentTime : '00:00' }}</text>
- <text class="text" style="margin: 0 10rpx;">/</text>
- <text class="text" style="opacity: .5;">{{ duration ? duration : '00:00' }}</text>
- </view>
- <image class="shengyin" :src="muted ? '/static/jingyin.png' : '/static/yinliang.png'" @click="muted = !muted">
- </image>
- <image class="shengyin" style="margin-left:20rpx" src="/static/quanping.png" @click="fullScreen">
- </image>
- </view>
- </view>
- </template>
- <script setup>
- import { ref, computed,onUnmounted } from 'vue'
- import DomVideoPlayer from '@/components/DomVideoPlayer'
- import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
- const systemInfo = uni.getSystemInfoSync();
- const width = systemInfo.screenWidth;
- const height = systemInfo.screenHeight - 50;
- // 将xx秒转为 xx:xx 分秒格式
- const formatSec2Time = (time) => {
- const min = Math.floor(time / 60)
- const sec = Math.floor(time % 60)
- return `${min}:${sec < 10 ? '0' + sec : sec}`
- }
- const props = defineProps({
- info: {
- type: Object,
- default: () => { }
- },
- item: {
- type: Object,
- default: () => { }
- },
- index: {
- type: Number,
- default: -1
- },
- current: {
- type: Number,
- default: 0
- }
- })
- const playing = ref(true)
- const loop = ref(true)
- const controls = ref(false)
- const autoplay = ref(true)
- const playbackRate = ref(1)
- const currentTime = ref(0)
- const duration = ref(0)
- const domVideoPlayer = ref(null);
- const showPlayBtn = ref(false);
- const loading = ref(false);
- const lineWidth = ref(0);
- const muted = ref(false);
- const isZan = ref(false);
- const isSc = ref(false);
- const isFullscreen = ref(false);
- const change = () => {
- if (!isFullscreen.value) {
- playing.value ? pause() : play()
- }
- }
- const play = () => {
- showPlayBtn.value = false
- playing.value = true
- domVideoPlayer.value.play()
- }
- const pause = () => {
- showPlayBtn.value = true
- playing.value = false
- domVideoPlayer.value.pause()
- }
- const onPlay = () => {
- console.log('onPlay')
- if (props.current != props.index) {
- domVideoPlayer.value.pause()
- playing.value = false
- } else {
- playing.value = true
- showPlayBtn.value = false
- loading.value = false
- }
- }
- const onPause = () => {
- console.log('onPause')
- showPlayBtn.value = true
- playing.value = false
- }
- const onEnded = () => {
- console.log('onEnded')
- playing.value = false
- }
- const fullScreen = () => {
- console.log('全屏');
- domVideoPlayer.value.fullScreen();
- }
- const onDurationChange = (e) => {
- console.log(e);
- if (loading.value) loading.value = false;
- if (!playing.value) playing.value = true;
- if (!duration.value || duration.value == '00:00') duration.value = secondToTime(e, 1)
- }
- const onTimeUpdate = (e) => {
- currentTime.value = secondToTime(e)
- lineWidth.value = e / duration.value * width
- }
- const secondToTime = (s, n) => {
- const t = parseInt(s)
- const hours = Math.floor(t / (60 * 60));
- const seconds = t % (60 * 60)
- const minutes = Math.floor(seconds / 60);
- const seconds2 = seconds % 60
- if (hours > 0) {
- return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds2.toString().padStart(2, '0')}`;
- } else {
- return `${minutes.toString().padStart(2, '0')}:${seconds2.toString().padStart(2, '0')}`;
- }
- }
- const onRateChange = (e) => {
- console.log('onRateChange', e)
- playbackRate.value = e
- }
- const onFullscreenChange = (e) => {
- console.log('onFullScreenChange', e)
- }
- // defineExpose({
- // play
- // })
- onUnmounted(()=>{
- console.log('组件卸载');
-
- })
- onHide(() => {
- pause()
- })
- </script>
- <style scoped lang="less">
- @import url('@/style.less');
- .action-box {
- margin-top: 30rpx;
- padding: 0 60rpx;
- }
- .action-box button {
- margin-top: 10rpx;
- }
- .video {
- width: 750rpx;
- background-color: #000000;
- }
- .text {
- color: #fff;
- font-size: 28rpx;
- }
- .info {
- position: absolute;
- z-index: 100;
- left: 0;
- bottom: 50px;
- width: 750rpx;
- padding: 30rpx 140rpx 130rpx 30rpx;
- .flex();
- flex-direction: column;
- .title {
- font-size: 36rpx;
- max-width: calc(750rpx - 140rpx - 60rpx);
- }
- .des {
- background-color: rgba(255, 255, 255, .1);
- border-radius: 10rpx;
- padding: 15rpx 20rpx;
- .text {
- font-size: 24rpx;
- }
- }
- }
- .btns {
- position: absolute;
- z-index: 100;
- right: 0;
- bottom: 0;
- width: 140rpx;
- .flex_position(flex-end);
- flex-direction: column;
- padding-bottom: 340rpx;
- .toux {
- height: 88rpx;
- width: 88rpx;
- border-radius: 50%;
- object-fit: cover;
- }
- .btn {
- height: 66rpx;
- width: 66rpx;
- }
- .text {
- margin-top: 10rpx;
- margin-bottom: 30rpx;
- font-size: 26rpx;
- }
- }
- .play-btn {
- height: 68rpx;
- width: 68rpx;
- border-radius: 50%;
- background-color: rgba(0, 0, 0, .5);
- position: absolute;
- margin-left: -34rpx;
- margin-top: -34rpx;
- .flex_center();
- }
- .loading {
- position: absolute;
- height: 60rpx;
- width: 60rpx;
- margin-left: -30rpx;
- margin-top: -30rpx;
- }
- .progress {
- width: 750rpx;
- height: 90rpx;
- position: absolute;
- left: 0;
- bottom: 50px;
- .line {
- height: 2rpx;
- width: 500rpx;
- background-color: rgba(255, 255, 255, .35);
- transform: scaleY(.1);
- }
- }
- ._duration {
- position: absolute;
- height: 88rpx;
- .ver();
- left: 0;
- width: 750rpx;
- bottom: 50px;
- z-index: 101;
- padding-left: 30rpx;
- padding-right: 30rpx;
- background-color: rgba(255, 255, 255, .05);
- }
- .shengyin {
- height: 38rpx;
- width: 38rpx;
- }
- </style>
|