Player.Provider

预计阅读时间: 3 分钟

Player.Provider 是播放器的状态边界。它创建一个存储(store),并通过 context 将其提供给内部的所有组件。每个播放器需要且仅需要一个 Provider。

App.tsx
import { videoFeatures } from '@videojs/react/video';
import { createPlayer } from '@videojs/react';

const Player = createPlayer({ features: videoFeatures });

function App() {
  return (
    <Player.Provider>
      {/* 内部所有组件都可以访问播放器存储 */}
      <Player.Container>
        <video src="video.mp4" />
      </Player.Container>
    </Player.Provider>
  );
}

如何创建

调用 createPlayer() 并传入 features 数组。返回的对象包含 ProviderContainerusePlayeruseMedia — 构建一个播放器实例所需的一切。

import { createPlayer } from '@videojs/react';
import { videoFeatures } from '@videojs/react/video';

const Player = createPlayer({
  features: videoFeatures,
});

传入的功能特性决定了存储中可用的状态。videoFeatures 是一个预设,包含播放、音量、全屏和其他标准视频控件。

内部包含什么

所有需要播放器状态的内容都放在 Provider 内部:皮肤、容器、UI 组件以及你自己的自定义组件。内部的任何组件都可以访问存储。

<Player.Provider>
  <VideoSkin>           {/* 皮肤 — 包含容器和控件 */}
    <Video src="..." /> {/* 媒体元素 */}
  </VideoSkin>
  <MyCustomOverlay />   {/* 你自己的组件 — 可以使用 Player.usePlayer() */}
</Player.Provider>

无视觉存在

Provider 不渲染任何可见元素 — 它纯粹是一个状态包装器。尺寸、边框和背景应该放在 Container 上,而不是 Provider 上。

访问状态

使用 Player.usePlayer 从 Provider 内部的任何组件读取状态或调用操作:

PlayPauseButton.tsx
function PlayPauseButton() {
  const paused = Player.usePlayer(selectPlayback).paused;
  const store = Player.usePlayer();

  return (
    <button onClick={() => store.dispatch('toggle-playback')}>
      {paused ? 'Play' : 'Pause'}
    </button>
  );
}

扩展播放器布局

Provider 的作用域可以扩展到全屏目标之外。播放列表、字幕、侧边栏和其他补充 UI 可以放在 Provider 内部但在 Container 外部。它们仍然拥有完整的存储访问权限,只是不会随视频一起全屏。

<Player.Provider>
  <Player.Container>
    <video src="video.mp4" />
    <Controls />          {/* 随视频一起全屏 */}
  </Player.Container>

  <Transcript />          {/* 在容器外部 — 仍有存储访问权限 */}
  <PlaylistSidebar />     {/* 在容器外部 — 仍有存储访问权限 */}
</Player.Provider>

参见