当前位置:网站首页>Wechat applet, continuously playing multiple videos. Synthesize the appearance of a video and customize the video progress bar
Wechat applet, continuously playing multiple videos. Synthesize the appearance of a video and customize the video progress bar
2022-07-01 21:36:00 【Summer thought】
1, First, customize the components of playback progress . Because the progress bar comes with each playback , Every video is from 0 At the beginning . So don't show your own progress bar . Customize a progress bar . You can refer to the official website of the applet silder Component to write progress bar .
So the premise is that we must know the length of each video . In this way, when customizing the progress bar, the total length is the sum of all video lengths . slider | Wechat open documents Wechat Developer Platform documentation https://developers.weixin.qq.com/miniprogram/dev/component/slider.html
2, The function that needs to monitor the end of each video , Each time the end trigger function is used to determine whether all videos have been played .
3, Judge when dragging the progress bar . Drag to the first few videos . Then play the videos in the corresponding array .
Rewrite the progress bar and playback pause, so the original pause playback and progress bar will not be displayed .video add
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: {
// Video playlists
videoList: {
type: Array,
value: [{
url: 'http://1310895430.vod2.myqcloud.com/acb3025cvodbj1310895430/8899089c387702302247202150/MZdixh89MtgA.mp4',
duration: '103',// The second corresponding to the video
}, {
url: 'http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400',
duration: '330'
}]
},
// The total length of the video (1:10:10)
},
data: {
// Video subscript
index: 0,
video: '',
// The total length of the video ( second )
duration: '',
// Video playback period (0:01)
startTime: '00:00',
// The total length of the video (10:10)
endTime: '00::00',
// Video playback progress ( percentage )
percent: '0',
totalTime:'0',
// Whether you are dragging
isSlide: false,
playStates: false,//true Start false Pause
},
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
})
}
},
// Initialize instance
onReady() {
},
methods: {
// Pause play button
videoOpreation() {
console.log(" Play pause ")
this.data.playStates ? this.data.video.pause() : this.data.video.play();
this.setData({
playStates: !this.data.playStates
})
},
// Monitor playback progress
bindtimeupdate(e) {
let {currentTime, duration} = e.detail;
let startTime=0;// The time of calculating the video is the time of the previous video plus the playback time of the current video
for(var i=0;i<this.data.index;i++){
startTime+=parseInt(this.data.videoList[i].duration);
}
// console.log(" The progress bar time of the current video 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(" Starting time "+this.data.startTime)
// console.log(" The current video "+this.data.index)
this.triggerEvent('refreshVideo', {
nowTime: nowTime
}, {});
},
// seek Trigger on completion
bindseekcomplete() {
// console.log("seek Trigger on completion ")
this.setData({
isSlide: false
})
},
// Video playback error
error(e){
// this.data.video.play()
console.log(e)
},
// End of video playback
ended() {
if (this.data.index == this.data.videoList.length - 1) {
this.data.video.pause()
wx.showToast({
title: ' Finished playing ',
icon: 'none',
duration: 1000,
mask: true,
})
this.setData({
index: 0,
playStates:false
})
} else {
// console.log(' Play the next video ')
this.videoPlay();
}
},
videoPlay() {
// console.log(" I'm the next video ")
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';// Set up autoplay
this.data.video.play()// Play the video
},
// Trigger after completing a drag
bindchange(e) {
// console.log("bindchange After a drag "+e.detail.value)
this.setSlide(e.detail.value)
let {value} = e.detail
let {video, duration} = this.data
let seekpeed=value / 100 * this.data.totalTime;// Calculate the video playback time corresponding to the dragged length according to the total length of the video
// console.log("seekpeed"+seekpeed)
let startTime=0;
// Which video is it , Just find the subscript and end the loop
var videolLength = this.data.videoList.length;
for(var i=0;i<this.data.videoList.length;i++){
if(seekpeed<this.data.videoList[i].duration){// Small progress
this.setData({
index: i,
})
break;
}else{
startTime+=parseInt(this.data.videoList[i].duration);// Great progress
this.setData({
index: i+1,
})
break;
}
}
// console.log(" The start time of the video after dragging "+startTime);
// console.log(" After dragging, the current video subscript "+this.data.index)
let seek=parseInt(seekpeed-startTime);// Jump position
// console.log(" Jump position "+seek)
this.data.video.play()// Play the video
this.data.video.seek(seek);
this.setData({
startTime: this.timeToMinute(seekpeed),// The start time after dragging is displayed
playStates:true,
isSlide: false
})
},
// Trigger during dragging
bindchanging(e) {
// console.log("bindchanging Trigger during dragging "+e.detail.value)
this.setSlide(e.detail.value)
},
// Set progress bar
setSlide(value) {
// console.log(" Drag to the location setSlide"+value)
let startTime=value / 100 * this.data.totalTime;
this.setData({
isSlide: true,
percentSlide: value,
startTime: this.timeToMinute(startTime),// The start time in dragging is displayed
})
},
// https://blog.csdn.net/qq_31984879/article/details/84071245
// Seconds convert minutes 00:00:00 Format
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;
}To download this component, you can go to this address Wechat applet combines multiple videos to play one . One player will automatically play the other after playing . Customize the video progress component -Javascript Document resources -CSDN download
边栏推荐
- 安装mysql时出现:需要这两个包perl(Data::Dumper),perl(JSON)
- 面试题:MySQL的union all和union有什么区别、MySQL有哪几种join方式(阿里面试题)[通俗易懂]
- 喜马拉雅自研网关架构演进过程
- 编程英语生词笔记本
- NSI脚本的测试
- Introduction à l'ingénierie logicielle (sixième édition) notes d'examen de Zhang haifan
- Entering Ruxin Town, digital intelligence transformation connects "future community"
- 东哥套现,大佬隐退?
- ngnix基础知识
- Gaussdb (for MySQL):partial result cache, which accelerates the operator by caching intermediate results
猜你喜欢

目标检测——Yolo系列

新牛牛盲盒微信小程序源码_支持流量变现,带完整素材图片

杰理之蓝牙耳机品控和生产技巧【篇】

杰理之、产线装配环节【篇】

杰理之烧录都使用 VBAT 供电,供电电压 4.2V【篇】

极客DIY开源方案分享——数字幅频均衡功率放大器设计(实用的嵌入式电子设计作品软硬件综合实践)

NSI脚本的测试

Data analysts sound tall? Understand these points before you decide whether to transform

Gaussdb (for MySQL):partial result cache, which accelerates the operator by caching intermediate results

杰理之烧录上层版物料需要【篇】
随机推荐
运放-滞回(迟滞)比较器全流程实战计算
测试撤销1
安装mysql时出现:需要这两个包perl(Data::Dumper),perl(JSON)
目標檢測——Yolo系列
【opencv】train&test HOG+SVM
【商业终端仿真解决方案】上海道宁为您带来Georgia介绍、试用、教程
杰理之烧录都使用 VBAT 供电,供电电压 4.2V【篇】
Détection des cibles - série Yolo
芭比Q了!新上架的游戏APP,咋分析?
deb文件安装
Importance of EDA tools to chip industry knowledge popularization
多个张量与多个卷积核做卷积运算的输出结果
如何用OpenMesh创建一个四棱锥
PLC模拟量输入 模拟量转换FB S_ITR(三菱FX3U)
极客DIY开源方案分享——数字幅频均衡功率放大器设计(实用的嵌入式电子设计作品软硬件综合实践)
[multithreading] realize the singleton mode (hungry and lazy) realize the thread safe singleton mode (double validation lock)
PWN攻防世界cgpwn2
【深度学习】利用深度学习监控女朋友的微信聊天?
杰理之蓝牙耳机品控和生产技巧【篇】
从20s优化到500ms,我用了这三招