swiper 视频轮播

232 阅读1分钟

实现不同长度的视频轮播,简单整理一下思路,我们需要通过监听视频的播放和暂停事件来控制swiper的autoplay。所以需要去掉video标签的loop,

<video muted playsinline :ref="el => { videoRefs[index] = el }" :key="index" @play="handleVideoPlay" @ended="handleVideoEnd" @timeupdate="handleTimeUpdate" > <source :src="item" type="video/mp4" /> </video>这是video标签上,创建 const videoRefs = ref([]) 存储video实例。

以下是swiper中的完整代码块 注意如果你和我一样用标签写法需要去import 相对于的组件和样式

 <Swiper :modules="[Pagination,Autoplay,EffectFade]" :autoplay="{
                delay: 3000,
                disableOnInteraction: false,
       }"
               :effect="'fade'"
               :fadeEffect="{
                crossFade: true
                }"
               :pagination="{
           el:'.banner-swiper-pagination',
           clickable:true
       }"
       @swiper="initSwiper"
       @slideChange="handleSlideChange">
           <Swiper-Slide v-for="(item,index) in curPage.banner[3]" :key="index">
               <video 
                   muted 
                   playsinline
                   :ref="el => { videoRefs[index] = el }"
                   :key="index"
                   @play="handleVideoPlay"
                   @ended="handleVideoEnd"
                   @timeupdate="handleTimeUpdate"
                   >
                   <source :src="item" type="video/mp4" />
               </video>
           </Swiper-Slide>

           <div class="banner-swiper-pagination" ></div>
       </Swiper>

接下是js的实现,因为我没有添加autoplay,所以视频不会自动播放,需要在onMounted中手动播放第一个

onMounted(()=>{
    nextTick(() => {
      if (videoRefs.value[0]) {
        videoRefs.value[0].play().catch(() => {
          console.log('播放遇到问题')
        })
      }
    })
})

需要通过@swiper存储swiper 实例

const swiperInstance=ref(null)
function initSwiper(swiper){
    swiperInstance.value=swiper
}

然后是video的播放和暂停事件和update

function handleVideoPlay(){
    if(swiperInstance.value){
        swiperInstance.value.autoplay.stop();
    }
}

function handleVideoEnd(){
    if(swiperInstance.value){
        swiperInstance.value.autoplay.start();
    }
}
function handleTimeUpdate(event) {
    // 当视频播放到结束时(移除了loop属性,所以需要手动控制循环)
    if (event.target.currentTime >= event.target.duration - 0.1) {
        event.target.currentTime = 0; // 重置视频到开始
        if (swiperInstance.value) {
            swiperInstance.value.autoplay.start(); // 开启轮播
            swiperInstance.value.slideNext(); // 切换到下一张
        }
    }
}

最后是轮播的change事件

function handleSlideChange(swiper) {
    if (!videoRefs.value) return
    
    videoRefs.value.forEach((video, index) => {
        if (!video) return
        
        if (index === swiper.activeIndex) {
            video.currentTime = 0
            const playPromise = video.play()
            if (playPromise !== undefined) {
                playPromise
                    .then(() => {
                        // 视频成功播放后停止轮播
                        if(swiperInstance.value) {
                            swiperInstance.value.autoplay.stop();
                        }
                    })
                    .catch(() => {
                        console.log('Video autoplay prevented')
                    })
            }
        } else {
            video.pause()
            video.currentTime = 0
        }
    })
}