前言

  功能要求开发的小程序以及h5在视频下滑切换要保持和抖音一样的流畅播放,同时绕过谷歌的视频禁止有声自动播放,也要解决视频过多滑动过快导致的白屏和视频无法自动播放的功能。

 

第一步 使用Taro的 Swiper 和 Video

  思路在于使用Swiper的上下滑动包裹着Video,实现流畅滑动切换视频的功能,但 SwiperItem 我们不能直接用获取的视频列表进行循环,因为视频列表一般都是做分页,往往都是几百条数据,直接循环就会导致在30条及往上的时候就卡顿白屏,触发页面的重熏染,影响体验。故我们限制死3个 SwiperItem,然后通过滑动切换计算当前列表的下标,动态渲染里面的 Video。

<Swiper
        className='Swiper'
        current={current}
        duration={700}
        vertical
        circular
        onAnimationFinish={e => {
          togglePlay(e.detail.current)
          switchPlay(e.detail.current)
        }}
        onChange={e => {
          e.stopPropagation()
          setCurrent(e.detail.current)
          throttle(handleSwiperChange, e.detail.current, 700)
        }
      }>
        {renderedVideos.map((e, i) => (
          <SwiperItem key={i}>
            <NewVideo
              ref={el => refs.current[i] = el}
              video_url={e.video_url}
              cover_img={e.cover_img}
              videoIndex={videoIndex}
              item={e}
              isActive={videoIndex === i}
              switchPlay={switchPlay}
            />
          </SwiperItem>
        ))}
      </Swiper>

  

const [current, setCurrent] = useState<number>(0)  // 索引
const [oldCurrent, setOldCurrent] = useState(0) // 旧索引
const [currentIndex, setCurrentIndex] = useState(0) // 当前视频在完整列表中的索引

  const handleSwiperChange = (i:number) => {
    setVideoIndex(i)

    if ((i > oldCurrent && !(i === 2 && oldCurrent === 0)) || (i === 0 && oldCurrent === 2)) {
      setCurrentIndex(currentIndex + 1)
    } else {
      setCurrentIndex(currentIndex - 1)
    }

    if (currentIndex >= videoList.length - 3) init()
    setOldCurrent(i)
  }

  // 核心:根据当前索引,计算需要渲染的3个视频(当前、下一个、上一个)
  const renderedVideos = useMemo(() => {
    const prevIndex = (currentIndex - 1 + videoList.length) % videoList.length;
    const nextIndex = (currentIndex + 1) % videoList.length;

    return [videoList[prevIndex], videoList[currentIndex % videoList.length], videoList[nextIndex]]
  }, [videoList, currentIndex]);

 

第二步 利用Video创建对应的类组件,然后加上点赞关注等等

  这里不方便加上过多代码,所以点赞关注等细节这种非常简单的就自己加,主要跟你们说下思路

<Video
            // ref={videoRef}
            id={`video_${index}`}
            src={video_url}
            className='video-player'
            loop
            // muted={!videoPlayingState}
            muted={false}
            poster={cover_img}
            objectFit='cover'
            onClick={() => switchPlay(index)}
            onPlay={() => 
              this.setState({
                videoPlayingState: true,
              })
            }
            onPause={() => {
              this.setState({
                videoPlayingState: false,
              })
            }}
          >
            <NewImage src="common/play_btn" suffix='svg' className={isPlaying ? ' hidden-btn' : ''} />
          </Video>
          { !isActive && <View className='cover-img' onClick={() => switchPlay(index)} /> }

 

最终效果图展示:

2dd99ce9e886cd6124454b54458ef8db (1)

 

有兴趣的也可以看看我公司的线下预约教练的网站 https://web.xiaoxiangfeng-sports.cn/pages_main/home/index

  

posted on 2026-02-03 14:28  Tom最好的朋友是Jerry  阅读(0)  评论(0)    收藏  举报