You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactPlayer禁用拖拽跳转功能失效问题求助

修复ReactPlayer禁用拖拽跳转后的播放循环问题

我尝试在ReactPlayer中禁用拖拽跳转功能,强制用户完整观看视频,不允许跳过,编写了如下代码:

import ReactPlayer from "react-player";
import { useRef } from "react";

const MyLessons = () => {
const playerRef = useRef(null);
const prevPlayed = useRef(null);

const handleSeek = () => {
  if (prevPlayed.current) {
    playerRef.current.seekTo(prevPlayed.current.playedSeconds, 'seconds');
  }
};

const handleProgress = (state) => {
  prevPlayed.current = state;
};

return (
  <div className="app">
    <main className="content">
      <div className="player-wrapper">
        <ReactPlayer
          ref={playerRef}
          className="react-player"
          url="lessons/testmp4.MP4"
          width="100%"
          height="100%"
          controls
          config={{ file: { attributes: { controlsList: 'nodownload' } } }}
          onProgress={handleProgress}
          onSeek={handleSeek}
        />
      </div>
    </main>
  </div>
 );
};

export default MyLessons;

但遇到了问题:当视频播放时,用户尝试跳转至特定片段,视频会回到之前的播放位置,但随后会暂停且无法继续播放;同时ReactPlayer控制栏左下角的播放按钮会在播放与暂停状态间不停切换,陷入循环。

问题根源

  1. 调用seekTo会再次触发onSeek和onProgress事件,形成无限循环
  2. seekTo执行会中断当前播放状态,导致视频暂停

修复方案

通过添加状态锁、记录播放状态并限制位置记录更新,解决循环和暂停问题:

import ReactPlayer from "react-player";
import { useRef } from "react";

const MyLessons = () => {
  const playerRef = useRef(null);
  const prevPlayed = useRef(null);
  const isSeeking = useRef(false); // 防止循环触发的锁

  const handleSeek = () => {
    if (prevPlayed.current && !isSeeking.current) {
      isSeeking.current = true;
      // 记录跳转前的播放状态
      const wasPlaying = !playerRef.current.getInternalPlayer().paused;
      // 回退到用户跳转前的播放位置
      playerRef.current.seekTo(prevPlayed.current.playedSeconds, 'seconds');
      // 恢复之前的播放状态
      if (wasPlaying) {
        playerRef.current.play();
      }
      // 延迟解锁,避免重复触发事件
      setTimeout(() => {
        isSeeking.current = false;
      }, 100);
    }
  };

  const handleProgress = (state) => {
    // 仅在非强制跳转时更新播放位置记录
    if (!isSeeking.current) {
      prevPlayed.current = state;
    }
  };

  return (
    <div className="app">
      <main className="content">
        <div className="player-wrapper">
          <ReactPlayer
            ref={playerRef}
            className="react-player"
            url="lessons/testmp4.MP4"
            width="100%"
            height="100%"
            controls
            config={{ file: { attributes: { controlsList: 'nodownload' } } }}
            onProgress={handleProgress}
            onSeek={handleSeek}
          />
        </div>
      </main>
    </div>
  );
};

export default MyLessons;

关键改动说明

  • 状态锁isSeeking:避免seekTo触发的onSeek再次进入处理逻辑,打断无限循环
  • 记录并恢复播放状态:在回退到原位置后,根据跳转前的状态自动恢复播放,解决视频暂停问题
  • 限制prevPlayed更新:强制跳转期间不更新播放位置记录,确保回退的是用户跳转前的正确位置

内容的提问来源于stack exchange,提问作者los pollos hermanos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:55:32