usePlayerContext

预计阅读时间: 5 分钟

访问完整播放器上下文的钩子。

usePlayerContext 提供了 Video.js React 中完整的播放器上下文。它返回 store(存储)、media(媒体元素)、setMedia(设置媒体)、container(容器)、setContainer(设置容器)以及 popupGroup(弹出组)等关键对象。这个钩子是底层钩子,对于大多数用例,推荐使用更高级的钩子如 usePlayeruseMediauseMediaAttach

示例

基本用法

import { usePlayerContext } from '@videojs/react';

function AdvancedComponent() {
  const { store, media, setMedia, container, setContainer, popupGroup } = 
    usePlayerContext();

  // store: BaseStore - 播放器存储实例
  // media: HTMLMediaElement | undefined - 媒体元素引用
  // container: HTMLElement | undefined - 容器元素引用
  // popupGroup: Group | undefined - 弹出组实例

  return (
    <div>
      <p>Store has {Object.keys(store.state).length} state keys</p>
      <p>Media element: {media ? 'present' : 'not found'}</p>
      <p>Container: {container ? 'attached' : 'not attached'}</p>
    </div>
  );
}

访问存储方法

import { usePlayerContext } from '@videojs/react';

function StoreMethods() {
  const { store } = usePlayerContext();

  return (
    <div className="controls">
      <button onClick={() => store.play()}>Play</button>
      <button onClick={() => store.pause()}>Pause</button>
      <button onClick={() => store.seek(30)}>Seek to 30s</button>
    </div>
  );
}

访问容器和媒体

import { usePlayerContext } from '@videojs/react';

function ContainerInfo() {
  const { container, media } = usePlayerContext();

  const getContainerDimensions = () => {
    if (container) {
      return {
        width: container.clientWidth,
        height: container.clientHeight,
      };
    }
    return null;
  };

  const getMediaInfo = () => {
    if (media) {
      return {
        readyState: media.readyState,
        networkState: media.networkState,
      };
    }
    return null;
  };

  return (
    <div>
      <p>Container: {JSON.stringify(getContainerDimensions())}</p>
      <p>Media: {JSON.stringify(getMediaInfo())}</p>
    </div>
  );
}

API 参考

返回值

返回值类型说明
storeBaseStore & UnknownState播放器存储实例,包含状态和操作方法
mediaHTMLMediaElement | undefined当前注册的媒体元素引用
setMediaDispatch<RefObject<HTMLMediaElement>>设置媒体元素的函数
containerHTMLElement | undefined当前注册的容器元素引用
setContainerDispatch<RefObject<HTMLElement>>设置容器元素的函数
popupGroupGroup | undefined播放器弹出组实例

返回值详解

store

播放器存储实例,提供对播放器状态的访问和操作。

interface BaseStore {
  play: () => void;
  pause: () => void;
  seek: (time: number) => void;
  setVolume: (volume: number) => void;
  // ... 其他方法
  state: UnknownState;
}

media

当前注册的 <video><audio> 元素。如果尚未注册任何媒体元素,则为 undefined

setMedia

用于注册媒体元素的 RefCallback 函数。将此函数附加到媒体元素的 ref 属性即可完成注册。

container

当前注册的播放器容器元素。如果尚未注册任何容器,则为 undefined

setContainer

用于注册容器元素的 RefCallback 函数。将此函数附加到容器元素的 ref 属性即可完成注册。

popupGroup

Video.js 的弹出组实例,用于管理弹出菜单、工具提示等 UI 元素。

错误处理

Provider 外调用

usePlayerContextPlayer.Provider 外调用时会抛出错误:

// 这会抛出错误
function OutsideProvider() {
  usePlayerContext(); // Error: usePlayerContext must be used within a Player.Provider
  return null;
}

正确用法:

function InsideProvider() {
  const context = usePlayerContext(); // 正常工作
  return null;
}

function App() {
  return (
    <Player.Provider>
      <InsideProvider />
    </Player.Provider>
  );
}

推荐用法

虽然 usePlayerContext 提供了最大的灵活性,但对于大多数用例,推荐使用更高级的钩子:

高级钩子用途优势
usePlayer访问播放器状态和操作类型安全,简单易用
useMedia访问媒体元素直接访问,无需解构
useStore访问存储灵活的订阅选项
useMediaAttach注册媒体元素简化的注册流程

何时使用 usePlayerContext

使用 usePlayerContext 的场景:

  1. 需要同时访问多个上下文属性
  2. 需要访问 popupGroup 等特殊属性
  3. 需要访问底层的 setMediasetContainer 函数
  4. 构建自定义的中间件或工具函数

参见