npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cqsjjb/web-video-player

v1.0.0

Published

基于 video.js 封装的 React 视频播放器组件,专为网络课程教育应用设计

Downloads

93

Readme

@cqsjjb/web-video-player

@cqsjjb/web-video-player 是一个基于 video.js 封装的 React 视频播放器组件,专为网络课程教育应用设计,提供丰富的视频播放功能和高度可定制的用户体验。

特性

  • 多清晰度支持 - 支持多视频源切换,自动清晰度选择
  • 智能进度条 - 自定义双层进度条,支持已观看/未观看区域限制
  • 试看功能 - 内置试看时间限制,支持付费内容预览
  • 水印支持 - 可自定义水印文本和样式
  • 字幕轨道 - 支持多语言字幕和音轨切换
  • 播放控制 - 丰富的播放控制选项(速率、画中画、全屏等)
  • 权限控制 - 细粒度的功能控制(下载、快进、音量等)
  • TypeScript 支持 - 完整的类型定义

安装

npm install @cqsjjb/web-video-player
# 或
yarn add @cqsjjb/web-video-player
# 或
pnpm add @cqsjjb/web-video-player

🚀 快速开始

import React from 'react';
import WebVideoPlayer from '@cqsjjb/web-video-player';

function App() {
  return (
    <WebVideoPlayer
      width="800"
      sources={[
        { src: 'https://example.com/video.mp4', label: '高清', default: true }
      ]}
      poster="https://example.com/poster.jpg"
    />
  );
}

API 文档

WebVideoPlayerProps

| 属性 | 类型 | 默认值 | 说明 | |------|------|-------|------| | width | number \| string | 520 | 播放器宽度,数字(px)或百分比 | | sources | VideoSource[] | [] | 视频源列表,支持多清晰度切换 | | poster | string | undefined | 视频封面图 URL | | tracks | VideoTrack[] | [] | 字幕轨道列表 | | fluid | boolean | true | 是否自适应父容器宽度 | | preload | 'auto' \| 'metadata' \| 'none' | 'auto' | 视频预加载策略 | | controls | boolean | true | 是否显示默认控制栏 | | autoplay | boolean | false | 是否自动播放 | | allowFullscreen | boolean | true | 是否允许全屏 | | allowDownload | boolean | true | 是否显示下载按钮 | | trialTime | number | undefined | 试看时长(秒),超过暂停并回到起始位置 | | watermark | string | undefined | 视频水印文本 | | watermarkStyle | WatermarkStyle | {} | 水印样式配置 | | subtitleStyle | React.CSSProperties | undefined | 字幕容器样式,作用于 .vjs-text-track-display | | subtitleClassName | string | undefined | 附加到 .vjs-text-track-display 的类名,便于自定义样式 | | disableSeek | boolean | false | 是否禁用快进 | | enablePiP | boolean | false | 是否启用画中画 | | disableVolume | boolean | false | 是否隐藏音量控制 | | seekableWatchedOnly | boolean | false | 是否仅允许在已观看区域拖动进度 | | muted | boolean | false | 是否默认静音 | | loop | boolean | false | 是否循环播放 | | mini | boolean | false | 是否启用迷你模式(非全屏仅显示播放/暂停、全屏按钮) | | rootStyle | React.CSSProperties | {} | 播放器根元素样式 | | playbackRates | number[] | [] | 播放速率选项 | | enablePlaybackRate | boolean | true | 是否启用播放速率控制 | | showDuration | boolean | true | 是否显示时长信息 | | onTrialEnded | () => void | undefined | 试看结束回调 | | onError | (error?: any) => void | undefined | 播放错误回调 |

VideoSource

interface VideoSource {
  /** 视频地址 */
  src: string;
  /** 显示名称,例如 "高清"、"标清" */
  label: string;
  /** 视频类型,如 "video/mp4",可选,会自动检测 */
  type?: string;
  /** 是否为默认播放源,默认 false */
  default?: boolean;
}

VideoTrack

interface VideoTrack extends React.TrackHTMLAttributes<HTMLTrackElement> {}

WatermarkStyle

interface WatermarkStyle extends React.CSSProperties {
  /** 水印位置,默认 'top-left' */
  position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
  /** 水印透明度,默认 0.3 */
  opacity?: number;
  /** 水印字体大小,默认 14 */
  fontSize?: number;
  /** 水印颜色,默认 '#fff' */
  color?: string;
}

WebVideoPlayerRef

interface WebVideoPlayerRef {
  /** 获取 video.js player 实例 */
  getPlayer: () => videojs.Player | null;
  /** 获取原生 HTMLVideoElement */
  getNativePlayer: () => HTMLVideoElement | null;
}

使用示例

基础用法

import React from 'react';
import WebVideoPlayer from '@cqsjjb/web-video-player';

function BasicExample() {
  return (
    <WebVideoPlayer
      width="800"
      sources={[
        { src: 'https://example.com/video.mp4', label: '高清', default: true }
      ]}
      poster="https://example.com/poster.jpg"
    />
  );
}

多清晰度切换

import React, { useRef } from 'react';
import WebVideoPlayer, { WebVideoPlayerRef } from '@cqsjjb/web-video-player';

function MultiQualityExample() {
  const playerRef = useRef<WebVideoPlayerRef>(null);

  const handleGetPlayer = () => {
    const player = playerRef.current?.getPlayer();
    console.log('Player instance:', player);
  };

  return (
    <div>
      <WebVideoPlayer
        ref={playerRef}
        width="100%"
        sources={[
          { src: 'https://example.com/video-480p.mp4', label: '480P', default: true },
          { src: 'https://example.com/video-720p.mp4', label: '720P' },
          { src: 'https://example.com/video-1080p.mp4', label: '1080P' }
        ]}
        poster="https://example.com/poster.jpg"
        playbackRates={[0.5, 1, 1.25, 1.5, 2]}
        onError={(error) => console.error('播放错误:', error)}
      />
      <button onClick={handleGetPlayer}>获取播放器实例</button>
    </div>
  );
}

试看功能

import React, { useState } from 'react';
import WebVideoPlayer from '@cqsjjb/web-video-player';

function TrialExample() {
  const [trialEnded, setTrialEnded] = useState(false);

  const handleTrialEnded = () => {
    setTrialEnded(true);
    alert('试看结束,请购买完整版');
  };

  return (
    <div>
      {trialEnded && (
        <div style={{ padding: '20px', background: '#f0f0f0', marginBottom: '10px' }}>
          试看已结束,请购买完整版继续观看
        </div>
      )}
      <WebVideoPlayer
        width="800"
        sources={[
          { src: 'https://example.com/premium-video.mp4', label: '高清', default: true }
        ]}
        trialTime={60} // 60秒试看
        watermark="试看版本"
        watermarkStyle={{
          position: 'bottom-right',
          opacity: 0.5,
          fontSize: 16,
          color: '#ff0000'
        }}
        onTrialEnded={handleTrialEnded}
      />
    </div>
  );
}

字幕支持

import React from 'react';
import WebVideoPlayer from '@cqsjjb/web-video-player';

function SubtitleExample() {
  return (
    <WebVideoPlayer
      width="800"
      sources={[
        { src: 'https://example.com/video.mp4', label: '高清', default: true }
      ]}
      tracks={[
        {
          kind: 'subtitles',
          src: 'https://example.com/subtitles-zh.vtt',
          srcLang: 'zh',
          label: '中文字幕',
          default: true
        },
        {
          kind: 'subtitles',
          src: 'https://example.com/subtitles-en.vtt',
          srcLang: 'en',
          label: 'English'
        }
      ]}
    />
  );
}

字幕样式控制

function SubtitleStyleExample() {
  return (
    <WebVideoPlayer
      sources={[
        { src: 'https://example.com/video.mp4', label: '高清', default: true }
      ]}
      tracks={[
        {
          kind: 'subtitles',
          src: 'https://example.com/subtitles-zh.vtt',
          srcLang: 'zh',
          label: '中文字幕',
          default: true
        }
      ]}
      subtitleStyle={{
        color: '#fff',
        textShadow: '0 0 4px rgba(0, 0, 0, 0.9)',
        fontSize: '1.2rem',
        backgroundColor: 'rgba(0, 0, 0, 0.35)',
        padding: '4px 10px',
        borderRadius: '6px'
      }}
    />
  );
}

权限控制

import React from 'react';
import WebVideoPlayer from '@cqsjjb/web-video-player';

function PermissionControlExample() {
  return (
    <WebVideoPlayer
      width="800"
      sources={[
        { src: 'https://example.com/video.mp4', label: '高清', default: true }
      ]}
      // 禁用下载和右键菜单
      allowDownload={false}
      // 禁用快进
      disableSeek={true}
      // 禁用音量控制
      disableVolume={true}
      // 只能在已观看区域快进
      seekableWatchedOnly={true}
      // 禁用画中画
      enablePiP={false}
    />
  );
}

自定义样式

import React from 'react';
import WebVideoPlayer from '@cqsjjb/web-video-player';

function CustomStyleExample() {
  return (
    <WebVideoPlayer
      width="100%"
      sources={[
        { src: 'https://example.com/video.mp4', label: '高清', default: true }
      ]}
      rootStyle={{
        borderRadius: '8px',
        overflow: 'hidden',
        boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'
      }}
      watermark="自定义水印"
      watermarkStyle={{
        position: 'bottom-left',
        opacity: 0.3,
        fontSize: 14,
        color: '#ffffff',
        textShadow: '1px 1px 2px rgba(0, 0, 0, 0.5)'
      }}
    />
  );
}

最佳实践

1. 性能优化

// 使用 useMemo 优化 sources 数组
const sources = useMemo(() => [
  { src: videoUrl, label: '高清', default: true }
], [videoUrl]);

// 使用 useCallback 优化回调函数
const handleError = useCallback((error) => {
  console.error('播放错误:', error);
}, []);

2. 错误处理

const [error, setError] = useState(null);

<WebVideoPlayer
  sources={sources}
  onError={(err) => {
    setError(err);
    // 可以显示错误提示或重试按钮
  }}
/>

{error && (
  <div className="error-message">
    视频加载失败,请检查网络连接
  </div>
)}

3. 响应式设计

// 使用 CSS 媒体查询或 JavaScript 动态调整
const [playerWidth, setPlayerWidth] = useState('100%');

useEffect(() => {
  const updateWidth = () => {
    if (window.innerWidth < 768) {
      setPlayerWidth('100%');
    } else {
      setPlayerWidth('800px');
    }
  };
  
  updateWidth();
  window.addEventListener('resize', updateWidth);
  return () => window.removeEventListener('resize', updateWidth);
}, []);

License

MIT License - 详见 LICENSE 文件

版权信息

版权所有:重庆市建教帮科技有限责任公司

作者:[email protected]