You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

实现react-player在视频切换时保持全屏状态

实现React Player全屏状态记忆&解决相关问题

一、核心需求:让下一节课程自动继承全屏状态

其实思路很直白:

  • 先监听当前视频的全屏状态变化,把这个状态存在localStorage(或者你用的全局状态管理工具,比如Context/Redux)里
  • 当下一个React Player加载时,读取这个状态,自动帮用户触发全屏

可惜React Player本身没暴露全屏状态的回调,所以得借助浏览器原生全屏API或者第三方库,比如你尝试的screenfull

二、解决screenfull的编译错误

你碰到的Unexpected token错误,是因为新版screenfull用了ES2020的可选链操作符(?.),但你的Babel配置没支持这个语法。给你两个解决方向:

  • 降级到兼容版本:直接装一个不需要新语法的旧版本,比如npm install screenfull@5.2.0,这个版本兼容性拉满,不用改Babel配置
  • 升级Babel配置:如果想追新版,就装@babel/plugin-proposal-optional-chaining,然后在你的Babel配置文件(.babelrc或者babel.config.js)里加这个插件:
{
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}

三、为啥React Player本身有全屏按钮?

React Player的默认控制栏(开启controls属性就会显示)里确实自带全屏按钮,这个是它封装好的UI组件,底层其实也是用全屏API或者screenfull实现的。但它没把全屏状态的变化暴露成回调给咱们用,所以如果要做状态记忆,还是得自己监听全屏事件。

完整实现示例

给你写了个能用的示例,用screenfull@5.2.0+localStorage来实现状态记忆:

  1. 先装兼容版:
npm install screenfull@5.2.0
  1. 组件代码:
import React, { useEffect, useRef, useState } from 'react';
import ReactPlayer from 'react-player';
import screenfull from 'screenfull';

const CoursePlayer = ({ videoUrl }) => {
  const playerRef = useRef(null);
  const [isFullscreen, setIsFullscreen] = useState(false);

  // 组件加载时读取之前的全屏状态,自动触发全屏
  useEffect(() => {
    const savedFullscreen = localStorage.getItem('coursePlayerFullscreen') === 'true';
    if (savedFullscreen && playerRef.current && screenfull.isEnabled) {
      // 加个延迟,确保React Player渲染完成再触发全屏
      setTimeout(() => {
        screenfull.request(playerRef.current.wrapper);
      }, 300);
    }

    // 监听全屏状态变化,实时保存到本地
    const handleFullscreenChange = () => {
      const currentState = screenfull.isFullscreen;
      setIsFullscreen(currentState);
      localStorage.setItem('coursePlayerFullscreen', currentState.toString());
    };

    if (screenfull.isEnabled) {
      screenfull.on('change', handleFullscreenChange);
    }

    // 组件卸载时移除监听,避免内存泄漏
    return () => {
      if (screenfull.isEnabled) {
        screenfull.off('change', handleFullscreenChange);
      }
    };
  }, [videoUrl]);

  return (
    <div ref={playerRef}>
      <ReactPlayer
        url={videoUrl}
        controls
        width="100%"
        height="100%"
      />
    </div>
  );
};

export default CoursePlayer;

几点说明:

  • playerRef抓React Player的外层容器,因为screenfull需要作用在真实DOM元素上
  • 初始化时从localStorage读状态,自动触发全屏(加延迟是为了确保组件渲染完成,避免报错)
  • 监听screenfullchange事件,实时更新状态并保存到本地
  • 记得在组件卸载时移除监听,不然会有内存泄漏问题

额外提醒

  • 部分浏览器对全屏API有安全限制,比如必须通过用户交互(点击按钮之类的)触发,所以自动全屏可能在某些场景下失效,这时候可以加个提示让用户手动点全屏按钮
  • 如果你的课程是在同一个页面切换视频(不是刷新页面),用Context或者状态管理存状态会比localStorage更高效

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

火山引擎 最新活动