uniapp video(倍速功能、层级过高、视频第一帧做封面 等问题)

         由于上次写video组件的问题,过于划水,没讲清楚,导致自己花费了很多时间,重新踩坑,对自己很抱歉。

一、自己写的一个基本的视频组件(包含倍速功能)

效果图如下:倍速的显示和隐藏,需在全屏的时候 和 显示控制组件时

代码逻辑
1. 实现倍速的核心是创建视频组件控制器,调用它的倍速方法

=》官方文档 uni.createVideoContext(videoId, this) | uni-app官网

let videoContext = uni.createVideoContext; 
videoContext.playbackRate(1.5);


2. 如何通过cover-view在原生video组件上写UI
第一,要在 nvue 页面(不然全屏下,cover-view覆盖失效

第二,cover-view组件要放在video组件内部

<template>
	<!-- 视频 -->
	<view class="videoBox" >
		<video 
			:style="{width: 2*videoWidth+'rpx'}"
			id="videoId"
			class="video" :src="tempUrl" 
			:autoplay="true" object-fit="fill"
			@fullscreenchange="handleFullScreen"
			@controlstoggle="handleControlstoggle"
		>
			<!-- 后退按钮 -->
			<cover-image v-if="!speedState" @click="handleGoBack" class="backBtn" src="../../static/index/return_icon_white.png"></cover-image>
			
			<!-- 倍速按钮 -->
			<cover-view  v-if="speedState&&controlsToggle" class="speed">
				<text @click="speedNum=true" class="doubleSpeed">倍速</text>
			</cover-view>
			<!-- 倍速面板 -->
			<cover-view  v-if="speedNum" class="speedModal" @click.stop="speedNum=false"  :style="{width:clientHeight+37+'px',height: videoWidth+16+'px'}">
				<view  class="speedNumBox" :style="{height: videoWidth+16+'px'}">
					<text  @click.stop="handleSetSpeedRate(0.5)"  :class="[0.5 == speedRate?activeClass:errorClass,'number']">0.5</text>
					<text  @click.stop="handleSetSpeedRate(0.8)"  :class="[0.8 == speedRate?activeClass:errorClass,'number']">0.8</text>
					<text  @click.stop="handleSetSpeedRate(1)"    :class="[1 == speedRate?activeClass:errorClass,'number']">1</text>
					<text  @click.stop="handleSetSpeedRate(1.25)" :class="[1.25 == speedRate?activeClass:errorClass,'number']">1.25</text>
					<text  @click.stop="handleSetSpeedRate(1.5)"  :class="[1.5 == speedRate?activeClass:errorClass,'number']">1.5</text>
				</view>
			</cover-view>
		</video>
		
	</view>
</template>

<script setup>
	import {ref,reactive} from 'vue';
	import { onLoad } from '@dcloudio/uni-app';
	import StatusBarCustom from "@/pages/StatusBarCustom.vue";
	//视频播放的url
	let tempUrl = "https://vdept3.bdstatic.com/mda-piah212eiqj2c8n6/720p/h264/1694433760278042600/mda-piah212eiqj2c8n6.mp4?v_from_s=hkapp-haokan-hbe&auth_key=1694494958-0-0-e6efe783e3f1291c8ae14aafc84c3449&bcevod_channel=searchbox_feed&pd=1&cr=2&cd=0&pt=3&logid=0158851676&vid=10823921248731998514&klogid=0158851676&abtest=112751_4";
	
/*======================================== 设置视频宽度 ===============================================*/
	let videoWidth = ref(0);     //设置视频宽度
	let clientHeight = ref(0);   //设备高度
	onLoad(()=>{
		uni.getSystemInfo({
			success: function (res) {
				videoWidth.value = res.screenWidth-16;
				clientHeight.value = res.screenHeight;
			}
		});
	});
	
/*======================================== 倍速功能模块 ===============================================*/	
	let speedState = ref(false);      //监听全屏和退出全屏,控制对应的“返回按钮和倍速按钮是否显示”
	let speedNum   = ref(false);      //倍速的数字蒙版(0.5,0.8,1.0,1.25,1.5)
	const activeClass = ref('active');//选中倍速时的颜色样式active是类名
	const errorClass=ref('noActive'); //非选中的颜色样式noActive是类名
	let speedRate = ref(1);           //倍速的值(用来判断选中状态)
	//监听进入全屏 和 退出全屏
	const handleFullScreen = (e)=>{
		//e.detail对象的两个属性fullScreen和direction,一个可以得到true/false 另一个得到horizontal/vertical
		speedState.value = e.detail.fullScreen;
	}
	//倍速按钮:显示的条件  1.首先全屏   2.控件(播放/暂停按钮、播放进度、时间)是显示状态
	let controlsToggle = ref(false);
	const handleControlstoggle = (e)=>{
		controlsToggle.value = e.detail.show;
	}
	//设置倍速速度
	const handleSetSpeedRate = (rate)=>{
		let videoContext = uni.createVideoContext("videoId");
		videoContext.playbackRate(rate);
		speedRate.value = rate;
	}
</script>

<style scoped lang="scss">

	.videoBox{
		display: flex;
		justify-content: center;
		align-items: center;
	}
	.video{
	}
	.backBtn{
		position: absolute;
		left: 16rpx;
		top: 45rpx;
		width: 45rpx;
		height: 45rpx;
	}
	.speed{
		position: absolute;
		right: 20rpx;
		top: 16rpx;
		.doubleSpeed{
			color: #fff;
			font-size: 14rpx;
			background-color: rgba(0,0,0,0.6);
			padding: 4rpx 6rpx;
		}
	}
	
	// 倍速的蒙版
	.speedModal{
		background-color: rgba(0,0,0,0.7);
	}
	.speedNumBox{
		display: flex;
		flex-direction: column;
		justify-content: space-around;
		align-items: center;
		background-color: #2c2c2c;
		width: 120rpx;
		position: absolute;
		right: 0rpx;
		top: 0;
		.number{
			width: 120rpx;
			font-weight: 700;
			font-size: 14rpx;
			padding: 18rpx 0;
			display: flex;
			justify-content: center;
			align-items: center;
			text-align: center;
		}
		.active{
			color: red;
		}
		.noActive{
			color: #fff;
		}
	}
	
</style>

cover-view组件的问题

(1)v-for根本无法使用

(2)也不能嵌套 uview-plus组件

=》只能手写状态

二、其它相关问题

1. uniapp获取视频第一帧图片,作为视频的封面

逻辑上就是再url后面,添加?x-oss-process=video/snapshot,t_0,f_jpg

<template>
    <video :poster="videoUrl+'?x-oss-process=video/snapshot,t_0,f_jpg'"></video>
</template>
<script setup>
    import {ref} from "vue";
    let videoUrl = ref("https://haokan.baidu.com/v?vid=5725386879683902914&tab=recommend&sfrom=recommend")
</script>  

2. video这个原生控件层级层级太高无法覆盖

我想在video视频组件上覆盖一个返回按钮(图片) 和 一段文本(文字),代码和效果图如下

<template>
		<!-- 视频组件 -->
		<video class="videoBox" :src="courseData.videoUrl" :autoplay="true"></video>
         <!-- 在视频上覆盖一段文本 -->
		<cover-view class="backBtn">这是内容</cover-view>
		 <!-- 在视频上覆盖图片 -->
		<cover-image style="width: 50rpx;height: 50rpx;position: fixed;top: 100rpx;right: 50rpx;background-color: #000;" src="../../static/index/return_icon_white.png"></cover-image>
</template>

3. 去掉video下面的黑边

下面就是视频组件出现黑色边线

出现上下出现黑边的原因是: object-fit :contain;需要修改为 fill 就可以

猜你喜欢

转载自blog.csdn.net/tengyuxin/article/details/130834079
今日推荐