当前位置:网站首页>微信小程序,连续播放多段视频。合成一个视频的样子,自定义视频进度条
微信小程序,连续播放多段视频。合成一个视频的样子,自定义视频进度条
2022-07-01 21:32:00 【夏天想】
1,首先要自定义播放进度的组件。因为每次播放自带的进度条,每个视频都是从0开始的。所以不显示自带的进度条。自定义一个进度条。可以参考小程序官网silder组件来写进度条。
所以前提是我们必须知道每个视频的长度。这样自定义进度条的时候总长度就是所有的视频长度之和。 slider | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/component/slider.html
2,需要监听每个视频结束的函数,每次结束触发函数里面去判断是否播放了全部的视频。
3,拖拽进度条的时候要判断。拖到了第几个视频。然后播放相应的数组里面的第几个视频。
重写进度条和播放暂停所以原来的暂停播放和进度条就不显示了 。video标签添加
show-play-btn="{ {false}}" show-center-play-btn="{ {false}}"
WXML
<view class="content">
<video class="video" id="video"
src="{
{videoList[index].url||defaultVideo}}"
object-fit="cover"
id="video"
autoplay="{
{false}}"
controls="{
{false}}"
show-play-btn="{
{false}}"
show-center-play-btn="{
{false}}"
enable-progress-gesture="{
{true}}"
bindtimeupdate="bindtimeupdate"
bindseekcomplete="bindseekcomplete"
binderror="error"
bindended="ended"
>
</video>
<view class="process-container">
<van-icon name="{
{playStates ? 'pause':'play'}}" class="play-pause" bindtap='videoOpreation'/>
<view class="slider">
<slider block-size="{
{12}}" class="slider-light" activeColor="#ccc"
value="{
{isSlide ? percentSlide : percent}}" bindchange="bindchange"
bindchanging="bindchanging"/>
<text class="time startTime">{
{startTime}}</text>
<text class="time endTime">{
{endTime}}</text>
</view>
</view>
</view>
JS
Component({
properties: {
//视频播放列表
videoList: {
type: Array,
value: [{
url: 'http://1310895430.vod2.myqcloud.com/acb3025cvodbj1310895430/8899089c387702302247202150/MZdixh89MtgA.mp4',
duration: '103',//视频对应的秒钟
}, {
url: 'http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400',
duration: '330'
}]
},
// 视频总长度(1:10:10)
},
data: {
// 视频下标
index: 0,
video: '',
// 视频总长度(秒)
duration: '',
// 视频播放时间段(0:01)
startTime: '00:00',
// 视频总长度(10:10)
endTime: '00::00',
// 视频播放进度(百分比)
percent: '0',
totalTime:'0',
// 是否在拖动
isSlide: false,
playStates: false,//true开始 false暂停
},
lifetimes: {
ready: function () {
this.setData({
video: wx.createVideoContext('video', this),
totalTime:this.properties.videoList.reduce((sum, e) => sum + Number(e.duration || 0), 0),
endTime: this.timeToMinute(this.properties.videoList.reduce((sum, e) => sum + Number(e.duration || 0), 0)),
defaultVideo:this.data.videoList[this.data.index].url
})
}
},
// 初始化实例
onReady() {
},
methods: {
// 暂停播放按钮
videoOpreation() {
console.log("播放暂停")
this.data.playStates ? this.data.video.pause() : this.data.video.play();
this.setData({
playStates: !this.data.playStates
})
},
// 监听播放进度
bindtimeupdate(e) {
let {currentTime, duration} = e.detail;
let startTime=0;//计算视频的时间是上个视频的时间加上当前视频的播放时间
for(var i=0;i<this.data.index;i++){
startTime+=parseInt(this.data.videoList[i].duration);
}
// console.log("当前视频的进度条时间currentTime"+currentTime)
// console.log('startTime:'+startTime)
let nowTime=currentTime+startTime;
this.setData({
startTime: this.timeToMinute(nowTime),
percent: ((nowTime) / this.data.totalTime * 100).toFixed(2),
})
// console.log("开始时间"+this.data.startTime)
// console.log("当前视频"+this.data.index)
this.triggerEvent('refreshVideo', {
nowTime: nowTime
}, {});
},
// seek 完成时触发
bindseekcomplete() {
// console.log("seek 完成时触发")
this.setData({
isSlide: false
})
},
//视频播放出错
error(e){
// this.data.video.play()
console.log(e)
},
//视频播放结束
ended() {
if (this.data.index == this.data.videoList.length - 1) {
this.data.video.pause()
wx.showToast({
title: '已播放完成',
icon: 'none',
duration: 1000,
mask: true,
})
this.setData({
index: 0,
playStates:false
})
} else {
// console.log('播放下一个视频')
this.videoPlay();
}
},
videoPlay() {
// console.log("我是下一个视频")
var videolLength = this.data.videoList.length;
this.setData({
index: this.data.index+1,
playStates:true
})
// console.log(this.data.index)
this.data.video.autoplay ='true';//设置自动播放
this.data.video.play()//播放视频
},
// 完成一次拖动后触发
bindchange(e) {
// console.log("bindchange完成一次拖动后"+e.detail.value)
this.setSlide(e.detail.value)
let {value} = e.detail
let {video, duration} = this.data
let seekpeed=value / 100 * this.data.totalTime;//根据视频的总长度计算拖动的长度对应的视频播放的时间
// console.log("seekpeed"+seekpeed)
let startTime=0;
//判断是第几个视频,只要找到下标就结束循环
var videolLength = this.data.videoList.length;
for(var i=0;i<this.data.videoList.length;i++){
if(seekpeed<this.data.videoList[i].duration){//进度小的
this.setData({
index: i,
})
break;
}else{
startTime+=parseInt(this.data.videoList[i].duration);//进度大的
this.setData({
index: i+1,
})
break;
}
}
// console.log("拖拽结束之后的视频开始时间"+startTime);
// console.log("拖拽结束之后当前视频下标"+this.data.index)
let seek=parseInt(seekpeed-startTime);//跳转的位置
// console.log("跳转的位置"+seek)
this.data.video.play()//播放视频
this.data.video.seek(seek);
this.setData({
startTime: this.timeToMinute(seekpeed),//拖拽结束后的开始时间显示
playStates:true,
isSlide: false
})
},
// 拖动过程中触发
bindchanging(e) {
// console.log("bindchanging拖动过程中触发"+e.detail.value)
this.setSlide(e.detail.value)
},
// 设置进度条
setSlide(value) {
// console.log("拖拽到的位置setSlide"+value)
let startTime=value / 100 * this.data.totalTime;
this.setData({
isSlide: true,
percentSlide: value,
startTime: this.timeToMinute(startTime),//拖拽中的开始时间显示
})
},
// https://blog.csdn.net/qq_31984879/article/details/84071245
// 秒转换分钟00:00:00格式
timeToMinute(times) {
let t;
if (times > -1) {
let hour = Math.floor(times / 3600);
let min = Math.floor(times / 60) % 60;
let sec = times % 60;
if (min < 10) {
t = "0" + min + ':';
}else{
t = min + ":";
}
if (sec < 10) {
t += "0";
}
t += sec.toFixed(2);
}
t = t.substring(0, t.length - 3);
return t;
},
},
})wxss
.content {
position: relative;
}
.content .video {
width: 100%;
border-radius: 12rpx;
}
.content .slider {
width: 70%;
height: 50rpx;
margin-left:58rpx;
/* overflow: hidden;*/
}
.content .slider .plan {
width: 90%;
height: 10rpx;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 255, 255, 0.3);
}
.content .slider .plan .sign {
width: 30rpx;
height: 30rpx;
background-color: #FFFFFF;
border-radius: 50%;
position: absolute;
bottom: -9rpx;
}
.content .slider slider {
/* margin: 0rpx 50rpx; */
/* opacity: 0; */
}
.play-pause{
font-size:70rpx;
color:#fff;
/* padding: 20rpx; */
}
.process-container{
display:flex;
align-items: baseline;
justify-content:flex-start;
position:absolute;
bottom: 20rpx;
left: 30rpx;
z-index:9999;
width: 100%;
}
.time{
display:inline-block;
font-size:28rpx;
color:#FFF;
position: absolute;
top:29rpx;
}
.time.startTime{
left:75rpx;
}
.time.endTime{
right:44rpx;
}
.slider-light .wx-slider-handle-wrapper {
height: 40rpx;
}下载这个组件可以去这个地址微信小程序多个视频合成一个播放。一个播放完自动在播放另一个。自定义视频进度组件-Javascript文档类资源-CSDN下载
边栏推荐
- 目标检测——Yolo系列
- 杰理之蓝牙耳机品控和生产技巧【篇】
- On the usage of a magic function
- Accelera Systems Initiative是一个独立的非营利组织
- 极客DIY开源方案分享——数字幅频均衡功率放大器设计(实用的嵌入式电子设计作品软硬件综合实践)
- leetcode刷题:栈与队列01(用栈实现队列)
- Oracle deadlock test
- [multithreading] realize the singleton mode (hungry and lazy) realize the thread safe singleton mode (double validation lock)
- 杰理之、产线装配环节【篇】
- 深度学习 常见的损失函数
猜你喜欢
随机推荐
运放-滞回(迟滞)比较器全流程实战计算
Detailed explanation and code example of affinity propagation clustering calculation formula based on graph
三菱PLC FX3U脉冲轴点动功能块(MC_Jog)
MySQL数据库驱动(JDBC Driver)jar包下载
PMP证书真的有用吗?
Niuke programming question -- must brush the string of 101 (brush the question efficiently, draw inferences from one instance)
Customize the insertion of page labels and realize the initial search of similar address books
What else do you not know about new set()
Entering Ruxin Town, digital intelligence transformation connects "future community"
Learn white box test case design from simple to deep
ngnix基础知识
UVM教程
Uniapp uses Tencent map to select points without window monitoring to return users' location information. How to deal with it
杰理之、产线装配环节【篇】
小鸟逃票登机,如何反思,应如何解决,飞机为何怕小鸟?
《QTreeView+QAbstractItemModel自定义模型》:系列教程之三[通俗易懂]
BPR(贝叶斯个性化排序)
Importance of EDA tools to chip industry knowledge popularization
【Leetcode】最大连续1的个数
String类型转换BigDecimal、Date类型









