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

React+Laravel项目中react-video-js-player切换视频时跳回0点问题

问题描述

在React+Laravel项目中使用react-video-js-player组件,从Laravel获取视频文件名作为播放源时,切换视频后currentTime总是跳回0点。但使用React本地导入的视频时功能正常,使用Laravel本地服务地址(如http://localhost:8000/video/course/166168673420.mp4)作为src时出现该问题。相关代码如下:

import React, { Component } from "react";
import VideoPlayer from "react-video-js-player";

class SingleCourse extends Component {
  player = {};
  state = {
    video: {
      src: "http://localhost:8000/video/course/166168673420.mp4",
      poster:
        "https://images.unsplash.com/photo-1661997011608-a8bc1a4da810?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1176&q=80",
    },
  };

  onPlayerReady(player) {
    console.log("Player is ready: ", player);
    this.player = player;
  }

  onVideoPlay(duration) {
    console.log("Video played at: ", duration);
  }

  onVideoPause(duration) {
    console.log("Video paused at: ", duration);
  }

  onVideoTimeUpdate(duration) {
    console.log("Time updated: ", duration);
  }

  onVideoSeeking(duration) {
    console.log("Video seeking: ", duration);
  }

  onVideoSeeked(from, to) {
    console.log(`Video seeked from ${from} to ${to}`);
  }

  onVideoEnd() {
    console.log("Video ended");
  }

  render() {
    return (
      <div>
        <VideoPlayer
          controls={true}
          src={this.state.video.src}
          poster={this.state.video.poster}
          width="720"
          height="420"
          onReady={this.onPlayerReady.bind(this)}
          onPlay={this.onVideoPlay.bind(this)}
          onPause={this.onVideoPause.bind(this)}
          onTimeUpdate={this.onVideoTimeUpdate.bind(this)}
          onSeeking={this.onVideoSeeking.bind(this)}
          onSeeked={this.onVideoSeeked.bind(this)}
          onEnd={this.onVideoEnd.bind(this)}
        />
      </div>
    );
  }
}
export default SingleCourse;
解决方案

1. 给播放器添加唯一Key

切换视频时,给VideoPlayer组件绑定与当前视频src一致的key,让React销毁旧播放器实例并创建新实例,避免旧状态残留:

<VideoPlayer
  key={this.state.video.src} // 添加该属性
  controls={true}
  src={this.state.video.src}
  poster={this.state.video.poster}
  width="720"
  height="420"
  onReady={this.onPlayerReady.bind(this)}
  onPlay={this.onVideoPlay.bind(this)}
  onPause={this.onVideoPause.bind(this)}
  onTimeUpdate={this.onVideoTimeUpdate.bind(this)}
  onSeeking={this.onVideoSeeking.bind(this)}
  onSeeked={this.onVideoSeeked.bind(this)}
  onEnd={this.onVideoEnd.bind(this)}
/>

2. 手动控制播放器状态切换

在切换视频前,先暂停当前播放器并重置必要状态,再更新视频源:

switchVideo = (newSrc) => {
  if (this.player) {
    this.player.pause();
    this.player.currentTime(0);
  }
  this.setState({
    video: {
      ...this.state.video,
      src: newSrc
    }
  });
}

3. 修复Laravel视频响应头

确保Laravel返回视频时发送支持断点续传的响应头,否则播放器无法正确记录播放位置:

return response()->file($pathToVideo, [
    'Accept-Ranges' => 'bytes',
    'Content-Length' => filesize($pathToVideo),
]);

4. 保存并恢复播放位置

如果需要保留上一个视频的播放进度,可以在切换视频后手动设置currentTime:

// 新增状态保存播放位置
state = {
  video: { /* ... */ },
  lastPlayTime: 0
};

// 更新播放位置时保存
onVideoTimeUpdate(duration) {
  this.setState({ lastPlayTime: duration });
}

// 新视频加载完成后恢复位置
onPlayerReady(player) {
  this.player = player;
  if (this.state.lastPlayTime) {
    player.currentTime(this.state.lastPlayTime);
  }
}

内容的提问来源于stack exchange,提问作者Abdullah Assoli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:48:26