一、一定要理解需求再下手
刚接手一个旧项目,只需要在上面添加一些新功能,和后端对对接口就可以了。因为害怕总是去问别人需求惹人烦,所以好几次讨论给我讲需求我就说我懂了,然后下来自己思考怎么做。最后又因为好多需求理解不到位,自己开发起来很费劲,耽搁了时间不说,还犯了很多错误,甚至接口都调错了好几次。所以以后一定要理解需求,最好有时间画一个流程图或者思维导图,犯了错也能有迹可循。
二、因为需求理解不到位,视频列表又重写了
还是上一篇文章的需求,但是被我想的很复杂。其实只需要有一个video播放器和一个视频列表,视频可以点击列表切换,每次切换时改变一个video播放器的视频地址就可以了,样子大概还是这样:
总的说来就三个要点:
- 进入页面自动播放视频
- 点击列表切换视频
- 当前视频播放完毕自动播放下一个视频
虽然需求少,但是需要考虑的东西还是挺多的,比如:列表的交互,最后一个视频播放完成切换到第一个,自动切换时列表样式也要随之切换等等。
三、重新理解需求后的新思路
video播放器
这里本来用的 vue3-video-play
组件,结果后面踩了一个坑,不知道是不是组件的bug(后面会讲),后面又换成原生 video
标签了,但是控制器就不好看了。
视频列表
这里还是使用的 swiper
,控制自由切换确实很方便
四、编码
- 下载引入
vue3-video-play
,文档,建议跳过,已经踩了坑了,可以就用原生
保存数据
const state = reactive({
videoData: [], //所有视频数据,因为数据不多,暂时没有考虑分页
curData: {}, //当前视频数据
swiper:{}, //swiper实例
})
swiper
因为之前用的原生写的,所以对原生比较熟悉,就直接用的原生了,其实有swiper
集成vue,有时间再看下。
切记要在拿到数据后才创建swiper
实例
const getVideoData = () => {
getDataScreenMediaList(params).then(res => {
// state.videoData = res.data
state.videoData = [
{
fileId: "1",
fileSurfacePlot: "src/assets/images/banner/g1.png",
filePath: "https://cdn.uviewui.com/uview/resources/video.mp4",
mediaTitle: "transition是一种动画的表现形式,有4个属性",
}
]
return
}).then(()=>{
createSwiper()
})
}
const createSwiper = () => {
state.swiper = new Swiper(".mySwiper", {
spaceBetween: 10,
slidesPerView: 4,
freeMode: true,
watchSlidesProgress: true,
});
};
页面结构大概就是这样
<div class="main">
<div class="video">
<!--- 这里之前是vue3-video-play的组件,后面换原生了 --->
<video
class="d-player-video-main"
:src="state.curData.filePath"
:poster="state.curData.fileSurfacePlot"
controls
@ended="onended"
@pause="onpause"
></video>
</div>
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div
v-for="(item, index) in state.videoData"
:key="item.fileId"
:class="[{ active: state.curData.fileId == item.fileId },'swiper-slide',]"
@click="switchVideo(item, index)"
>
<p>{{ item.mediaTitle }}</p>
<img :src="item.fileSurfacePlot" />
</div>
</div>
</div>
接下来,控制切换自动播放视频
//切换视频
const switchVideo = async (val: object, index: number) => {
state.swiper.slideTo(index);
state.curData = val;
await nextTick();
document.querySelector(".d-player-video-main").play();
};
就是在这里那个
vue3-video-play
组件出现了问题,切换的时候自动播放,但是控制器还是停止播放的样式。当点击暂停后切换,视频会自动播放,但是样式还是暂停的样式
忘记截图了,坑已经踩过了,有没有遇到过这个问题的,其实还是想用这个组件,ui会比原生好看一点,后面有机会看看
vue3-video-player
然后,监听视频播放结束切换下一个视频
//监听视频播放结束
const onended = async () => {
let index = state.videoData.findIndex(
(item) => item.fileId == state.curData.fileId
);
if (state.videoData[index + 1]) {
state.curData = state.videoData[index + 1];
state.swiper.slideNext();
} else {
state.swiper.slideTo(0);
state.curData = state.videoData[0];
}
await nextTick();
document.querySelector(".d-player-video-main").play();
};
最后,进入页面自动播放视频,这个问题百度了很多总的说来就三个方案
- autoplay 静音自动播放
- iframe可以设置自动播放,src设置一个很短的音频触发浏览器打开音频
- 监听用户事件触发
play()
方法
选择了第三种方式
//放在创建了swiper实例之后的 .then 中
document.querySelector(".main").addEventListener("mousemove", mouseMove);
document.querySelector(".main").addEventListener("click", mouseClick);
//鼠标移动事件回调
const mouseMove = () => {
document.querySelector(".d-player-video-main").play().catch(()=>{
return
});
};
//鼠标点击事件回调
const mouseClick = () => {
document.querySelector(".main").removeEventListener("mousemove", mouseMove);
}
记得在 onUnmounted 中移除事件
onUnmounted(()=>{
document.querySelector(".main").removeEventListener("click", mouseClick);
document.querySelector(".main").removeEventListener("mousemove", mouseMove);
})
五、总结
写一个视频播放也算是踩坑无数了,还是经历的太少了,以后做需求一定要理解需求,最好画个流程图再开始做。
- 根据后端返回数据编写页面结构,使用
swiper
插件制作播放列表效果 - 进入页面监听鼠标移动事件:触发play方法,监听点击事件:移除鼠标移动事件
- 监听列表点击事件,传入视频数据和下标,修改当前视频数据,移动slide到当前下标
- 监听视频播放结束事件,将当前视频数据修改为下一个(如果存在),移动slide到下一个(如果存在),不存在就回到第一个。
最后
为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。
有需要的小伙伴,可以点击下方卡片领取,无偿分享