前言
前段时间基于vue写了一个自定义的video播放器组件,踩了一些小坑, 这里做一下复盘分享出来,避免日后重复踩坑…
设计阶段
这里就直接放几张完成后的播放状态图吧,界面布局基本就是flex+vw适配一把梭,也比较容易.



需要实现的几个功能基本都标注出来了; 除了还有一个视频加载失败的…下面就这届上代码了;刚开始构思的时候考虑了一下功能的实现方式: 一是用原生的DOM操作,获取video元素后,用addEventListener来监听; 二是用vue的方式绑定事件监听; 最后图方便采用了两者结合的方式,但是总感觉有点乱, 打算后期再做一下代码格式优化.
video组件实现过程
组件模板部分
主要是播放器的几种播放状态的逻辑理清楚就好了, 即: 播放中,缓存中,暂停,加载失败这几种情况,下面按功能分别说一下
<template>
<div class="video-player">
<!-- 播放器界面; 兼容ios controls-->
<video
ref="video"
v-if="showVideo"
webkit-playsinline="true"
playsinline="true"
x-webkit-airplay="true"
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
style="object-fit:fill"
preload="auto"
muted="true"
poster="https://photo.mac69.com/180205/18020526/a9yPQozt0g.jpg"
:src="src"
@waiting="handleWaiting"
@canplaythrough="state.isLoading = false"
@playing="state.isLoading = false, state.controlBtnShow = false, state.playing=true"
@stalled="state.isLoading = true"
@error="handleError"
>您的浏览器不支持HTML5</video>
<!-- 兼容Android端层级问题, 弹出层被覆盖 -->
<img
v-show="!showVideo || state.isEnd"
class="poster"
src="https://photo.mac69.com/180205/18020526/a9yPQozt0g.jpg"
alt
>
<!-- 控制窗口 -->
<div
class="control"
v-show="!state.isError"
ref="control"
@touchstart="touchEnterVideo"
@touchend="touchLeaveVideo"
>
<!-- 播放 || 暂停 || 加载中-->
<div class="play" @touchstart.stop="clickPlayBtn" v-show="state.controlBtnShow">
<img
v-show="!state.playing && !state.isLoading"
src="../../assets/video/content_btn_play.svg"
>
<img
v-show="state.playing && !state.isLoading"
src="../../assets/video/content_btn_pause.svg"










