小程序 uni-app video 自定义控制条

本来不想自定义video的控制条的,感觉不同机型,不同操作系统会有bug,肯定不如自带的好,不过,因为iPhone11或是iPhoneX下面的横线,导致,一想拖动进度条,就切换屏幕,video自带的控制条还不能控制在屏幕的位置。没办法,小白也得上手了。

先放两张真机截图:

      

<video
	@pause="pause"
	@play="contrPlay"
	v-if="reFresh"
	class="video-class"
	:src="recordUrl"
	style="width: 100%;height: 100%;"
	id="videoPlay"
	:object-fit="objectFit"
	:loop="true"
	:autoplay="true"
	@timeupdate='videoUpdate'
	@ended="videoEnded"
	:controls="bool"
>
<view class='process-container'>
	<view class="video-controls-play">
		<image :src="palyFlag ? '../../static/img/start.png' : '../../static/img/pause.png'" class='video-controls-icon' @click='videoOpreation'/>
	</view>
	<view class="currtime">{{currtime}}</view>
    <view class='slider-container'>
        <slider @change="sliderChange" @changing="sliderChanging" step="1" :value="sliderValue" backgroundColor="#9f9587" activeColor="#d6d2cc" block-color="#FFFFFF" block-size="16rpx"/>
    </view>
	<view class="druationTime">{{druationTime}}</view>
	<image :src="fullScreenFlag ? '../../static/img/videoBack.png' : '../../static/img/fullScreen.png'" class='video-controls-icon' @click='videoAllscreen'></image>
</view>
 <!-- <view class='video_back'><image :src="fullScreenFlag ? '../../static/img/videoBack.png' : ''" @click='video_back'></image></view> -->
</video><!-- contain -->
data() {
		return {
			fullScreenFlag: false,
			currtime:'00:00:00',//当前播放时间 字符串 计算后
			druationTime:'00:00:00',//总时间 字符串 计算后
			bool:false,
			sliderValue: 0, //控制进度条slider的值,
			updateState: false, //防止视频播放过程中导致的拖拽失效
			palyFlag:false,
		};
	},
	methods: {
		// video_back: function (e) {
		//     this.fullScreenFlag ? this.videoContext.requestFullScreen() : this.videoContext.exitFullScreen();
		//     // this.fullScreenFlag ? this.bool=false : this.bool=true;
		//     this.fullScreenFlag= !this.fullScreenFlag;
		//  },
		// 全屏+退出全屏
		videoAllscreen(e) { 
		    this.fullScreenFlag ? this.videoContext.exitFullScreen() : this.videoContext.requestFullScreen();
			// this.fullScreenFlag ? this.bool=true : this.bool=false;
			this.fullScreenFlag=!this.fullScreenFlag;
		},
		// 根据秒获取时间
		formatSeconds(a) {
			var hh = parseInt(a/3600);  
			var mm = parseInt((a-hh*3600)/60);  
			if(mm<10) mm = "0" + mm;  
			var ss = parseInt((a-hh*3600)%60);  
			if(ss<10) ss = "0" + ss;  
			if(hh<10) hh = hh == 0?'':`0${hh}:`;  
			var length = hh  + mm + ":" + ss;  
			if(a>=0){  
				return length;  
			}else{  
				return "00:00";  
			}  
		},
		//开始+暂停
		videoOpreation() { 
		    this.palyFlag ? this.videoContext.play() : this.videoContext.pause();
		    this.palyFlag= !this.palyFlag;
		  },
		// 播放进度变化时触发,event.detail = {currentTime, duration} 。触发频率 250ms 一次
		videoUpdate(e) {
			let duration=this.live.liveRoomRecordList[0].duration;
			let sliderValue = e.detail.currentTime / duration * 100;
			let second=sliderValue / 100 * duration;
			if (this.updateState) { //判断拖拽完成后才触发更新,避免拖拽失效
				this.sliderValue=sliderValue;
			}else{
				
			}
			 this.druationTime = this.formatSeconds(duration);
			 this.currtime = this.formatSeconds(second);
		},
        //拖动过程中触发的事件
        sliderChanging(e) {
			//拖拽过程中,不允许更新进度条
			this.updateState= false;
		},
		// 拖动slider完成后触发
		sliderChange(e) {
			var duration=this.live.liveRoomRecordList[0].duration;
			var second=e.detail.value / 100 * duration;
			if (duration) { //完成拖动后,计算对应时间并跳转到指定位置
			   this.videoContext.seek(second);
			   this.sliderValue= e.detail.value,
			   this.updateState= true //完成拖动后允许更新滚动条
			   this.druationTime = this.formatSeconds(duration);
			   this.currtime = this.formatSeconds(second);
			} 
			else { }
		},
		// 开始
		contrPlay(){
			this.videoContext.play();
			this.palyFlag=false;
		},
		// 暂停
		pause() {
			this.videoContext.pause(); //站厅播放
			this.palyFlag=true;
		},
}
 .process-container{
  width:100%;
  padding:1% 2% 1% 2%;
  height:60rpx;
  max-height:60rpx;
  position:absolute;
  bottom:40rpx;
  left:0;
  right:0;
  z-index:13;
  display:flex;
  align-items: center;
  background:rgba(59, 57, 57, 0.2);
}
.process-container image{
  display:inline-block;
  flex:1;
  max-width:50rpx;
  max-height:50rpx;
  text-align:center;
}
.slider-container{
  z-index:13;
  height:60rpx;
  margin-bottom:10rpx;
  flex:6;
  max-width:58%;
}
.video-controls-play{
	width: 8%;
}
.currtime{
	color: #ffffff;
	font-size: 22rpx;
	width: 11%;
	height: 100%;
	line-height: 60rpx;
	text-align: center;
}
.druationTime{
	color: #ffffff;
	font-size: 22rpx;
	width: 12%;
	height: 100%;
	line-height: 60rpx;
	text-align: center;
}
.video_back{
  display:block;
  width:60rpx;
  height:60rpx;
  left:5rpx;
  top:15rpx;
  position:absolute;
  text-align:center;
  z-index:19;
}
.video_back image{
  width:44rpx;
  height:44rpx;
}

参考:https://www.jb51.net/article/148266.htm

https://blog.csdn.net/qq_38194393/article/details/88655021?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160248681319724836722929%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160248681319724836722929&biz_id

 

 

### uni-app Video 组件常见错误及其解决方案 #### 1. 编译后代码报错难以定位 应用上线后,不同用户环境下的确可能出现各种报错情况。对于uni-app编译后的代码而言,第三方统计系统的报错信息往往指向的是编译后的乱码行数而非原始源文件中的具体位置[^1]。这使得开发者很难直接通过这些工具来精确定位问题所在。 针对此现象,建议采取以下措施: - **启用详细的日志记录**:可以在`main.js`入口处设置全局异常捕获机制,以便更好地收集并分析线上发生的未处理Promise拒绝和其他类型的JavaScript错误。 ```javascript // main.js 中加入如下配置 Vue.config.errorHandler = function (err, vm, info) { console.log('Error:', err); console.log('Info:', info); // 出错的额外信息 }; window.addEventListener('error', function(e){ console.log('Window Error:', e.message); }); window.addEventListener('unhandledrejection', function(e){ console.log('Unhandled Rejection at:', e.promise); console.log('Reason:', e.reason); }); ``` - **自定义上报逻辑**:当检测到特定件满足时(比如网络请求失败、页面加载超时等),主动触发事件向服务器发送诊断数据包用于后续排查工作。 #### 2. 使用原生组件替代默认实现 有时,默认提供的video组件可能并不完全适配某些特殊需求或存在兼容性问题。此时可以考虑采用更底层的方式——即调用平台特有的API接口完成相同功能的操作。例如,在iOS和Android平台上分别利用WebView控件加载网页版播放器;而在微信小程序环境中则可以直接运用其官方给出的小程序Video组件。 #### 3. 正确引入外部资源路径 确保所有静态资源(如图片、音频、视频文件)都按照正确方式引用非常重要。虽然vue允许像HTML那样使用相对路径指定外部模板、样式表以及脚本的位置[^4],但在实际操作过程中仍需注意跨域资源共享(CORS)政策的影响范围,并确认目标URL的有效性和可达性。 ```html <!-- 错误示范 --> <video :src="wrongPath"></video> <!-- 推荐做法 --> <template> <video id="my-video" class="video-js vjs-default-skin" controls preload="auto"> <!-- 设置多个source以提高浏览器兼容度 --> <source src="/static/videos/sample.mp4" type='video/mp4'/> Your browser does not support the video tag. </video> </template> <script> export default{ mounted(){ const playerOptions={ autoplay:false, muted:true, loop:false, playbackRates:[0.7,1.0,1.5,2.0], sources:[ {type:"video/mp4",src:this.$store.state.baseUrl+"/videos/sample.mp4"} ] }; this.player=new window.videojs(document.getElementById("my-video"),playerOptions,function onPlayerReady(){console.log("onPlayerReady");}); } } </script> ``` 以上方法能够有效帮助解决uni-appvideo组件所面临的大部分典型问题。当然,具体情况还需结合项目实际情况灵活调整优化策略。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值