|
@@ -0,0 +1,271 @@
|
|
|
+<template>
|
|
|
+ <view class="video-wrap" @click="handleClickWrap">
|
|
|
+ <video
|
|
|
+ autoplay
|
|
|
+ object-fit="contain"
|
|
|
+ show-mute-btn
|
|
|
+ show-background-playback-button
|
|
|
+ enable-play-gesture
|
|
|
+ :poster="videoInfo.cover_img_url"
|
|
|
+ :src="videoInfo.video_url"
|
|
|
+ :id="videoInfo.community_video_id"
|
|
|
+ @ended="handleVideoEnd"
|
|
|
+ @pause="handleVideoPause"
|
|
|
+ @timeupdate="handleTimeUpdate"
|
|
|
+ v-if="videoInfo.id==curVideoId"
|
|
|
+ >
|
|
|
+ <view class="video-inner-right-box">
|
|
|
+ <view class="video-speed-btn" @click.stop="showSpeedOpt=true">倍速</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 倍速选项模块 -->
|
|
|
+ <view class="speed-opt-box" v-if="showSpeedOpt">
|
|
|
+ <view
|
|
|
+ class="item"
|
|
|
+ :style="{color:item==curSpeed?'#F3A52F':''}"
|
|
|
+ v-for="item in speedOpts"
|
|
|
+ :key="item"
|
|
|
+ @click.stop="handleVideoSpeedChange(item)"
|
|
|
+ >{{item}}X</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ </video>
|
|
|
+ <image @click="handelClickPlay" v-else class="poster" :src="videoInfo.cover_img_url" mode="aspectFill" lazy-load/>
|
|
|
+
|
|
|
+ <!-- 外面弹幕按钮 -->
|
|
|
+ <view class="danmu-btn-box" v-if="showDanmu">
|
|
|
+ <view class="big-box" v-if="!closeDM">
|
|
|
+ <view class="left" @click.stop="showInput=true"></view>
|
|
|
+ <view class="right" @click.stop="closeDM=true"></view>
|
|
|
+ </view>
|
|
|
+ <view class="small-box" v-else @click.stop="closeDM=false"></view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 弹幕输入弹窗 -->
|
|
|
+ <view class="flex danmu-input-box" v-if="showInput">
|
|
|
+ <view class="flex input-box">
|
|
|
+ <input
|
|
|
+ type="text"
|
|
|
+ v-model="danmuText"
|
|
|
+ placeholder="请输入弹幕~"
|
|
|
+ cursor-spacing="20"
|
|
|
+ maxlength="50"
|
|
|
+ focus
|
|
|
+ confirm-type="send"
|
|
|
+ @keyboardheightchange="keyboardheightchange"
|
|
|
+ />
|
|
|
+ <text>{{danmuText.length}}/50</text>
|
|
|
+ </view>
|
|
|
+ <view class="btn">发送</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+
|
|
|
+export default {
|
|
|
+ props:{
|
|
|
+ showDanmu:{
|
|
|
+ type:Boolean,
|
|
|
+ default:false
|
|
|
+ },//是否显示弹幕
|
|
|
+ videoInfo:{},//{source:2-视频社区\3-路演视频,id:视频社区id\路演视频id,...其他数据}
|
|
|
+ curVideoId:0,//当前正在播放的id
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ curVideoId(){
|
|
|
+ this.curSpeed='1.0'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ curVideoIns:null,
|
|
|
+
|
|
|
+ showInput:false,//显示悬浮输入弹幕弹窗
|
|
|
+ closeDM:false,//是否关闭弹幕
|
|
|
+ danmuText:'',
|
|
|
+
|
|
|
+ showSpeedOpt:false,
|
|
|
+ speedOpts:['0.5','0.8','1.0','1.25','1.5','2.0'],
|
|
|
+ curSpeed:'1.0',
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ //点击最外层盒子
|
|
|
+ handleClickWrap(){
|
|
|
+ this.showSpeedOpt=false
|
|
|
+ },
|
|
|
+
|
|
|
+ // 点击播放
|
|
|
+ handelClickPlay(){
|
|
|
+ this.$emit('videoPlay', this.videoInfo)
|
|
|
+ setTimeout(() => {
|
|
|
+ this.curVideoIns=uni.createVideoContext(this.curVideoId.toString(),this)//由于是在自定义组件内 所有this不可少
|
|
|
+ }, 300);
|
|
|
+ },
|
|
|
+ handleVideoEnd(){
|
|
|
+ // 此处因为如果不调用退出全屏方法 安卓和ios页面均会表现异常,安卓横屏不恢复竖屏,ios底部tabbar渲染异常
|
|
|
+ this.curVideoIns.exitFullScreen()
|
|
|
+ this.curVideoIns=null
|
|
|
+ this.$emit('ended')
|
|
|
+ },
|
|
|
+ handleVideoPause(){
|
|
|
+ this.$emit('pause')
|
|
|
+ },
|
|
|
+ handleTimeUpdate(e){
|
|
|
+ this.$emit('timeupdate',e)
|
|
|
+ },
|
|
|
+
|
|
|
+ //键盘高度变为0 则收起悬浮弹幕输入框
|
|
|
+ keyboardheightchange(e){
|
|
|
+ if(e.detail.height===0){
|
|
|
+ setTimeout(() => {
|
|
|
+ this.showInput=false
|
|
|
+ }, 60);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // 倍速切换
|
|
|
+ handleVideoSpeedChange(item){
|
|
|
+ const num=Number(item)
|
|
|
+ this.curVideoIns.playbackRate(num)
|
|
|
+ this.curSpeed=item
|
|
|
+ this.showSpeedOpt=false
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.video-wrap{
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ position: relative;
|
|
|
+ video,.poster{
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+ .poster{
|
|
|
+ position: relative;
|
|
|
+ &::after{
|
|
|
+ content:'';
|
|
|
+ display: block;
|
|
|
+ position: absolute;
|
|
|
+ width: 120rpx;
|
|
|
+ height: 120rpx;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%,-50%);
|
|
|
+ background-image: url('@/static/video-play-btn.png');
|
|
|
+ background-size: cover;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .danmu-btn-box{
|
|
|
+ position: absolute;
|
|
|
+ bottom: -70rpx;
|
|
|
+ right: 6rpx;
|
|
|
+ .big-box{
|
|
|
+ width: 248rpx;
|
|
|
+ height: 50rpx;
|
|
|
+ background-image: url('@/static/danmu-show-btn.png');
|
|
|
+ background-size: cover;
|
|
|
+ display: flex;
|
|
|
+ .left{
|
|
|
+ width: 67%;
|
|
|
+ height: 100%;
|
|
|
+ flex-shrink: 0;
|
|
|
+ }
|
|
|
+ .right{
|
|
|
+ flex: 1;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .small-box{
|
|
|
+ width: 80rpx;
|
|
|
+ height: 50rpx;
|
|
|
+ background-image: url('@/static/danmu-close-btn.png');
|
|
|
+ background-size: cover;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .danmu-input-box{
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: 999999;
|
|
|
+ background-color: #fff;
|
|
|
+ padding: 10rpx 34rpx;
|
|
|
+ border-top: 1px solid #E5E5E5;
|
|
|
+ align-content: center;
|
|
|
+ .input-box{
|
|
|
+ flex:1;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ padding: 6rpx 10rpx;
|
|
|
+ background: #EFEFEF;
|
|
|
+ border: 2rpx solid #E5E5E5;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 12px;
|
|
|
+ input{
|
|
|
+ flex:1;
|
|
|
+ }
|
|
|
+ text{
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .btn{
|
|
|
+ width: 100rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+ color: #F3A52F;
|
|
|
+ font-size: 12px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .video-inner-right-box{
|
|
|
+ position: absolute;
|
|
|
+ bottom: 30%;
|
|
|
+ right: 5%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .video-speed-btn{
|
|
|
+ width: 80rpx;
|
|
|
+ height: 44rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: rgba(0, 0, 0, 0.4);
|
|
|
+ border-radius: 22rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ .speed-opt-box{
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ width: 20%;
|
|
|
+ background: rgba(0, 0, 0, 0.8);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-around;
|
|
|
+ padding-top: 55rpx;
|
|
|
+ .item{
|
|
|
+ color: #fff;
|
|
|
+ font-size: 26rpx;
|
|
|
+ flex: 1;
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|