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
相关产品推荐
相关产品推荐

