自定义皮肤

预计阅读时间: 4 分钟

如何弹出和自定义 Video.js 皮肤以满足你的设计需求。

Video.js 皮肤设计为可自定义。当你需要比打包皮肤提供的更多控制时,可以"弹出"皮肤——将其内部组件复制到你的项目中,然后从那里自定义。

何时弹出皮肤

在以下情况下考虑弹出皮肤:

  • 你需要重新排列控件布局
  • 你想要自定义控件的外观(超出 CSS 自定义属性允许的范围)
  • 你需要添加或删除特定控件
  • 你想要完全控制播放器的视觉设计

如何弹出皮肤

1. 安装 UI 组件

首先,安装你需要的 UI 组件:

npm install @videojs/react

2. 创建自定义皮肤组件

基于现有皮肤创建你自己的皮肤组件:

// components/CustomVideoSkin.tsx
import {
  PlayButton,
  MuteButton,
  VolumeSlider,
  TimeSlider,
  FullscreenButton,
  Player,
} from '@videojs/react';

export function CustomVideoSkin() {
  return (
    <Player.Container className="custom-video-skin">
      {/* 视频元素由父组件通过 children 提供 */}
      
      {/* 自定义控制栏 */}
      <div className="custom-controls">
        <div className="controls-left">
          <PlayButton />
          <MuteButton />
          <VolumeSlider />
        </div>
        
        <div className="controls-center">
          <TimeSlider />
        </div>
        
        <div className="controls-right">
          <FullscreenButton />
        </div>
      </div>
    </Player.Container>
  );
}

3. 添加自定义样式

/* styles/custom-skin.css */
.custom-video-skin {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
}

.custom-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);
}

.controls-left,
.controls-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.controls-center {
  flex: 1;
  margin: 0 16px;
}

/* 自定义按钮样式 */
.custom-video-skin button {
  background: transparent;
  border: none;
  color: white;
  cursor: pointer;
  padding: 8px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.custom-video-skin button:hover {
  background-color: rgba(255,255,255,0.1);
}

4. 使用自定义皮肤

// App.tsx
import { createPlayer, videoFeatures } from '@videojs/react';
import { Video } from '@videojs/react/video';
import { CustomVideoSkin } from './components/CustomVideoSkin';
import './styles/custom-skin.css';

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

function App() {
  return (
    <Player.Provider>
      <CustomVideoSkin>
        <Video src="https://example.com/video.mp4" />
      </CustomVideoSkin>
    </Player.Provider>
  );
}

自定义技巧

使用 render 属性

使用 render 属性完全控制组件的渲染:

<PlayButton
  render={(props, state) => (
    <button {...props} className="my-play-button">
      {state.paused ? (
        <PlayIcon className="icon-play" />
      ) : (
        <PauseIcon className="icon-pause" />
      )}
    </button>
  )}
/>

使用 data 属性样式

利用组件自动设置的 data 属性:

/* 根据播放状态改变按钮颜色 */
.play-button[data-paused] {
  color: #00ff00;
}

.play-button:not([data-paused]) {
  color: #ff0000;
}

/* 根据音量级别改变图标 */
.volume-button[data-volume-level="muted"] .icon {
  opacity: 0.5;
}

.volume-button[data-volume-level="high"] .icon {
  filter: drop-shadow(0 0 4px currentColor);
}

条件渲染控件

根据播放器状态条件渲染控件:

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

function CustomControls() {
  const { duration, live } = usePlayer((s) => ({
    duration: s.duration,
    live: s.live,
  }));

  return (
    <div className="controls">
      <PlayButton />
      
      {/* 仅在非直播时显示进度条 */}
      {!live && <TimeSlider />}
      
      {/* 仅在非直播时显示时间 */}
      {!live && (
        <span className="time-display">
          {formatTime(duration)}
        </span>
      )}
      
      {live && <span className="live-badge">LIVE</span>}
      
      <FullscreenButton />
    </div>
  );
}

保持可访问性

自定义皮肤时,确保保持可访问性:

  1. 保留 ARIA 属性:始终展开 {...props} 以保留组件的 ARIA 属性
  2. 键盘导航:确保所有交互元素都可以通过键盘访问
  3. 焦点指示器:为聚焦状态提供可见的指示器
  4. 对比度:确保控件在视频背景上具有足够的对比度

下一步


上一步: 无障碍访问

下一步: 构建自定义 UI 组件