因为需求理解不到位,视频自动播放列表又重写了


theme: scrolls-light
highlight: vs2015

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

一、一定要理解需求再下手

刚接手一个旧项目,只需要在上面添加一些新功能,和后端对对接口就可以了。因为害怕总是去问别人需求惹人烦,所以好几次讨论给我讲需求我就说我懂了,然后下来自己思考怎么做。最后又因为好多需求理解不到位,自己开发起来很费劲,耽搁了时间不说,还犯了很多错误,甚至接口都调错了好几次。所以以后一定要理解需求,最好有时间画一个流程图或者思维导图,犯了错也能有迹可循。

二、因为需求理解不到位,视频列表又重写了

还是上一篇文章的需求,但是被我想的很复杂。其实只需要有一个video播放器和一个视频列表,视频可以点击列表切换,每次切换时改变一个video播放器的视频地址就可以了,样子大概还是这样:

image-20221125104218176.png

总的说来就三个要点:

  • 进入页面自动播放视频
  • 点击列表切换视频
  • 当前视频播放完毕自动播放下一个视频

虽然需求少,但是需要考虑的东西还是挺多的,比如:列表的交互,最后一个视频播放完成切换到第一个,自动切换时列表样式也要随之切换等等。

三、重新理解需求后的新思路

video播放器

这里本来用的 vue3-video-play 组件,结果后面踩了一个坑,不知道是不是组件的bug(后面会讲),后面又换成原生 video 标签了,但是控制器就不好看了。

视频列表

这里还是使用的 swiper ,控制自由切换确实很方便

111.gif

四、编码

  • 下载引入 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);
}

记得在 OnUnmounten 中移除事件

onUnmounted(()=>{
  document.querySelector(".main").removeEventListener("click", mouseClick);
  document.querySelector(".main").removeEventListener("mousemove", mouseMove);
})

五、总结

写一个视频播放也算是踩坑无数了,还是经历的太少了,以后做需求一定要理解需求,最好画个流程图再开始做。

  • 根据后端返回数据编写页面结构,使用swiper插件制作播放列表效果
  • 进入页面监听鼠标移动事件:触发play方法,监听点击事件:移除鼠标移动事件
  • 监听列表点击事件,传入视频数据和下标,修改当前视频数据,移动slide到当前下标
  • 监听视频播放结束事件,将当前视频数据修改为下一个(如果存在),移动slide到下一个(如果存在),不存在就回到第一个。
© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容