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

@ebin-player/core

v0.0.5

Published

A modular, plugin-based web video player with modern architecture

Downloads

27

Readme

🎬 Ebin Player

一个现代化的、模块化的 Web 视频播放器,基于 TypeScript 构建,采用全新架构设计,支持强大的插件系统和高度可定制的 UI。

框架适配:React、Vue 2、Vue 3、Angular。参见下文框架绑定与 docs/frameworks 总览。

✨ 核心特性

🏗️ 现代架构

  • 分层架构设计 - PlayerCore、PlayerStore、PluginManager 三层分离
  • 响应式状态管理 - 基于订阅模式的状态同步系统
  • 事件驱动架构 - 完整的事件监听和分发机制
  • 插件化设计 - 现代插件系统,支持服务、命令、配置管理
  • TypeScript 原生 - 完整的类型定义和类型安全

🎨 智能UI系统

  • 多UI模式 - 原生、自定义、高级、无UI四种模式
  • 组件化架构 - 基于 UIManager 的模块化UI组件
  • 响应式设计 - 自动适配移动端、平板和桌面端
  • 主题系统 - 基于 ThemeManager 的动态主题切换
  • 无障碍支持 - 完整的 ARIA 标签和键盘导航

🔌 强大插件系统

  • 现代插件架构 - 基于 PluginDefinition 的声明式插件
  • 服务定位 - 插件间服务注册和发现机制
  • 命令系统 - 插件间命令调用和通信
  • 配置管理 - 插件配置验证、版本控制和迁移
  • 权限控制 - 细粒度的插件权限管理

🚀 播放器功能

  • 完整播放控制 - 播放/暂停、快进/快退、播放速度调节
  • 全屏支持 - 全屏和画中画模式
  • 音量控制 - 音量调节和静音功能
  • 进度控制 - 精确的时间控制和进度显示
  • 键盘快捷键 - 完整的键盘操作支持

🚀 快速开始

安装

pnpm add @ebin-player/core
# 或
npm install @ebin-player/core
# 或
yarn add @ebin-player/core

框架绑定

Ebin Player 为流行的前端框架提供了官方绑定:

React

npm install @ebin-player/react @ebin-player/core
import { EbinPlayer } from '@ebin-player/react';
import '@ebin-player/core/styles';

function App() {
  return (
    <EbinPlayer
      src="video.mp4"
      uiMode="advanced"
      onReady={() => console.log('播放器准备就绪')}
    />
  );
}

Vue 2

npm install @ebin-player/vue2 @ebin-player/core
<template>
  <EbinPlayer
    :src="videoSrc"
    :ui-mode="'advanced'"
    @ready="onReady"
  />
</template>

<script>
import { EbinPlayer } from '@ebin-player/vue2';
import '@ebin-player/core/styles';

export default {
  components: { EbinPlayer },
  data() {
    return { videoSrc: 'video.mp4' };
  },
  methods: {
    onReady() { console.log('播放器准备就绪'); }
  }
};
</script>

Vue 3

npm install @ebin-player/vue3 @ebin-player/core

Angular

npm install @ebin-player/angular @ebin-player/core
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { EbinPlayerModule } from '@ebin-player/angular';

@NgModule({
  imports: [BrowserModule, EbinPlayerModule],
})
export class AppModule {}
<ebin-player [src]="'video.mp4'" [uiMode]="'advanced'" (ready)="onReady()"></ebin-player>
<template>
  <EbinPlayer
    :src="videoSrc"
    :ui-mode="'advanced'"
    @ready="onReady"
  />
</template>

<script setup>
import { ref } from 'vue';
import { EbinPlayer } from '@ebin-player/vue3';
import '@ebin-player/core/styles';

const videoSrc = ref('video.mp4');
const onReady = () => console.log('播放器准备就绪');
</script>

基础使用

HTML 引入方式

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="node_modules/@ebin-player/core/dist/styles.css">
</head>
<body>
    <div id="player-container"></div>
    <script src="node_modules/@ebin-player/core/dist/ebin-player.umd.js"></script>
    <script>
        const player = new PlayerInstance(
            document.getElementById('player-container'),
            {
                src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
                uiMode: 'custom',
                debug: true
            }
        );
    </script>
</body>
</html>

ES6 模块使用

import { PlayerInstance } from '@ebin-player/core';
import '@ebin-player/core/styles';

const player = new PlayerInstance(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'custom',
    debug: true
});

使用 createPlayer 工厂函数

import { createPlayer } from '@ebin-player/core';
import '@ebin-player/core/styles';

const player = createPlayer(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'custom',
    theme: {
        primaryColor: '#3b82f6',
        backgroundColor: 'rgba(0, 0, 0, 0.8)'
    }
});

🎨 UI 模式

Ebin Player 提供三种UI模式,满足不同场景需求:

1. 原生控制条模式 (native)

使用浏览器原生HTML5控制条,性能最优:

const player = new PlayerInstance(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'native'
});

2. 自定义UI模式 (custom)

基于 ImprovedDefaultUI 的现代化自定义界面:

const player = new PlayerInstance(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'custom',
    uiConfig: {
        playButton: true,
        progressBar: true,
        timeDisplay: true,
        volumeControl: true,
        fullscreenButton: true,
        playbackRateControl: true
    },
    theme: {
        primaryColor: '#3b82f6',
        backgroundColor: 'rgba(0, 0, 0, 0.8)',
        textColor: '#ffffff',
        controlBarHeight: 50
    }
});

3. 无UI模式 (none)

纯播放器核心,适合自定义开发:

const player = new PlayerInstance(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'none'
});

// 手动监听事件和状态
player.on('play', () => console.log('开始播放'));
player.subscribe(state => console.log('状态更新:', state));

⌨️ 键盘快捷键

| 快捷键 | 功能 | |--------|------| | 空格 / Enter | 播放/暂停 | | F | 全屏切换 | | M | 静音/取消静音 | | C | 字幕开关 | | J | 快退10秒 | | L | 快进10秒 | | | 快退5秒 | | | 快进5秒 | | | 音量增加 | | | 音量减少 | | Shift + < | 播放速度减慢 | | Shift + > | 播放速度加快 |

📡 事件系统

Ebin Player 提供完整的事件系统,支持所有标准的HTML5视频事件以及自定义事件。

支持的事件类型

type PlayerEventType =
  | "loadstart"           // 开始加载
  | "loadedmetadata"      // 元数据加载完成
  | "loadeddata"          // 数据加载完成
  | "canplay"             // 可以开始播放
  | "canplaythrough"      // 可以播放到结束
  | "play"                // 开始播放
  | "pause"               // 暂停播放
  | "ended"               // 播放结束
  | "error"               // 播放错误
  | "timeupdate"          // 时间更新
  | "volumechange"        // 音量变化
  | "ratechange"          // 播放速度变化
  | "seeking"             // 开始跳转
  | "seeked"              // 跳转完成
  | "waiting"             // 等待数据
  | "stalled"             // 数据停滞
  | "progress"            // 加载进度
  | "durationchange"      // 时长变化
  | "resize"              // 尺寸变化
  | "fullscreenchange"    // 全屏状态变化
  | "enterpictureinpicture"  // 进入画中画
  | "leavepictureinpicture"  // 退出画中画
  | "lifecyclechange"     // 生命周期变化
  | "statechange";        // 状态变化

事件监听示例

// 监听播放事件
player.on('play', (event) => {
  console.log('开始播放', event);
});

// 监听时间更新事件
player.on('timeupdate', (event) => {
  console.log('当前时间:', player.getCurrentTime());
});

// 监听全屏变化
player.on('fullscreenchange', (event) => {
  console.log('全屏状态:', event.data?.isFullscreen);
});

// 监听状态变化
player.on('statechange', (event) => {
  console.log('状态更新:', event.data?.state);
});

🔧 API 参考

PlayerInstance

播放器主类,整合核心功能、状态管理和插件系统。

构造函数

new PlayerInstance(container: HTMLElement, options: PlayerOptions)

核心方法

播放控制
// 异步播放控制
player.play(): Promise<PlayerInstance>
player.pause(): PlayerInstance
player.load(): PlayerInstance

// 时间控制
player.getCurrentTime(): number
player.setCurrentTime(time: number): PlayerInstance
player.getDuration(): number

// 音量控制
player.getVolume(): number
player.setVolume(volume: number): PlayerInstance
player.getMuted(): boolean
player.setMuted(muted: boolean): PlayerInstance

// 播放速度
player.getPlaybackRate(): number
player.setPlaybackRate(rate: number): PlayerInstance

// 播放状态
player.getPaused(): boolean
player.getEnded(): boolean
player.getReadyState(): number
player.getNetworkState(): number
player.getError(): MediaError | null
状态管理
// 状态访问
player.getState(): PlayerState
player.setState(state: Partial<PlayerState>): void

// 状态订阅
player.subscribe(
    callback: (state: PlayerState) => void,
    keys?: (keyof PlayerState)[]
): () => void
事件系统
// 事件监听
player.on<T extends PlayerEventType>(
    event: T, 
    callback: (event: PlayerEventBase<T>) => void
): () => void

player.off<T extends PlayerEventType>(
    event: T, 
    callback: (event: PlayerEventBase<T>) => void
): void

player.emit<T extends PlayerEventType>(
    event: T, 
    data?: EventPayloadMap[T]
): PlayerInstance
全屏和画中画
// 全屏控制
player.requestFullscreen(): Promise<PlayerInstance>
player.exitFullscreen(): Promise<PlayerInstance>
player.isFullscreen(): boolean

// 画中画
player.requestPictureInPicture(): Promise<PictureInPictureWindow>
player.exitPictureInPicture(): Promise<PlayerInstance>
player.isPictureInPicture(): boolean
插件系统
// 插件管理
player.use(plugin: PluginDefinition<unknown, unknown>): PlayerInstance
player.unuse(pluginId: string): PlayerInstance
player.getPlugin(pluginId: string): PluginDefinition | undefined
UI控制
// UI管理
player.updateUIMode(uiMode: UIMode): PlayerInstance
player.updateUIConfig(config: ControlBarConfig): PlayerInstance
player.updateUITheme(theme: PlayerTheme): PlayerInstance
player.getUIMode(): UIMode

// 元素访问
player.getContainer(): HTMLElement
player.getVideoElement(): HTMLVideoElement
工具方法
// 播放器信息
player.getInfo(): {
    version: string;
    lifecycle: string;
    plugins: string[];
    state: PlayerState;
    uiMode: UIMode;
}

// 调试
player.setDebug(enabled: boolean): void

// 销毁
player.destroy(): void

配置选项

PlayerOptions

interface PlayerOptions {
    // 基础配置
    src: string;                    // 视频源
    autoplay?: boolean;             // 自动播放
    muted?: boolean;                // 静音
    volume?: number;                // 音量 (0-1)
    playbackRate?: number;          // 播放速度
    poster?: string;                // 封面图
    width?: number | string;        // 宽度
    height?: number | string;       // 高度
    controls?: boolean;             // 已废弃,使用uiMode替代
    loop?: boolean;                 // 循环播放
    preload?: 'none' | 'metadata' | 'auto';  // 预加载策略
    crossOrigin?: 'anonymous' | 'use-credentials' | '';  // 跨域设置
    playsInline?: boolean;          // 内联播放
    
    // UI配置
    uiMode?: UIMode;                // UI模式
    uiConfig?: ControlBarConfig;    // UI组件配置
    theme?: PlayerTheme;            // 主题配置
    
    // 插件配置
    builtinPlugins?: {              // 内置插件配置
        playbackRate?: boolean | {
            defaultRate?: number;
            options?: Array<{ value: number; label: string }>;
        };
    };
    
    // 调试配置
    debug?: boolean;                // 调试模式
    logger?: Logger;                // 自定义日志器
}

ControlBarConfig

interface ControlBarConfig {
    // 基础控制
    playButton?: boolean;
    progressBar?: boolean;
    timeDisplay?: boolean;
    volumeControl?: boolean;
    fullscreenButton?: boolean;
    
    // 高级功能
    playbackRateControl?: boolean;
    pictureInPictureButton?: boolean;
    qualitySelector?: boolean;
    subtitleToggle?: boolean;
    aspectRatio?: boolean;
    pictureInPicture?: boolean;  // 注意:实际类型中有这个属性
    screenshot?: boolean;
    skipButtons?: boolean;
    
    // 自定义组件
    customButtons?: UIComponent[];
}

PlayerTheme

interface PlayerTheme {
    primaryColor?: string;          // 主色调
    secondaryColor?: string;        // 辅助色
    backgroundColor?: string;       // 背景色
    textColor?: string;             // 文字颜色
    controlBarHeight?: number;      // 控制栏高度
    borderRadius?: number;          // 圆角半径
    fontFamily?: string;            // 字体族
}

PlayerState

interface PlayerState {
    // 基础播放状态
    src: string;
    currentTime: number;
    duration: number;
    paused: boolean;
    muted: boolean;
    volume: number;
    playbackRate: number;
    
    // 媒体状态
    readyState: number;
    networkState: number;
    error: MediaError | null;
    ended: boolean;
    loading: boolean;
    seeking: boolean;
    
    // 视频尺寸
    videoWidth: number;
    videoHeight: number;
    
    // 缓冲状态
    buffered: TimeRanges | null;
    seekable: TimeRanges | null;
    
    // 播放质量
    quality: string;
    bitrate: number;
}

🎨 主题定制

CSS 变量

:root {
    --ebin-primary: #3b82f6;
    --ebin-secondary: #6b7280;
    --ebin-bg: rgba(0, 0, 0, 0.8);
    --ebin-text: #ffffff;
}

自定义样式

/* 自定义控制栏样式 */
.ebin-control-bar {
    background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
    border-radius: 12px;
}

/* 自定义按钮样式 */
.ebin-play-button {
    background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
    border-radius: 50%;
}

🔌 现代插件系统

Ebin Player 采用全新的插件架构,基于 PluginDefinition 设计,提供强大的扩展能力和优秀的开发体验。

插件架构特点

  • 声明式配置 - 基于 PluginDefinition 的元数据驱动
  • 服务定位 - 插件间服务注册和发现机制
  • 命令系统 - 插件间命令调用和通信
  • 配置管理 - 配置验证、版本控制和迁移
  • 权限控制 - 细粒度的插件权限管理
  • 生命周期 - 完整的插件生命周期管理

内置插件配置

内置插件可通过配置选项自动启用:

const player = new EbinPlayer(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'custom',
    builtinPlugins: {
        playbackRate: {
            defaultRate: 1.25,
            options: [
                { value: 0.5, label: '0.5x' },
                { value: 1, label: '1x' },
                { value: 1.25, label: '1.25x' },
                { value: 1.5, label: '1.5x' },
                { value: 2, label: '2x' }
            ]
        }
    }
});

插件开发

基础插件类

import { BasePlugin, PluginDefinition, PluginContext } from '@ebin-player/core';

interface MyPluginConfig {
    enabled: boolean;
    customOption: string;
}

interface MyPluginExports {
    getStatus(): boolean;
    doSomething(): void;
}

class MyPlugin extends BasePlugin<MyPluginConfig, MyPluginExports> {
    meta = {
        id: 'my-plugin',
        version: '1.0.0',
        displayName: 'My Plugin',
        description: '一个示例插件',
        capabilities: ['custom-feature'],
        permissions: ['player:control']
    };

    defaultConfig: MyPluginConfig = {
        enabled: true,
        customOption: 'default'
    };

    validateConfig = (config: unknown) => {
        const c = config as Partial<MyPluginConfig>;
        return { 
            valid: typeof c?.enabled === 'boolean',
            errors: c?.enabled === undefined ? ['enabled 必须为 boolean'] : []
        };
    };

    commands = {
        toggle: (args: any) => {
            const enabled = !this.ctx.getConfig<MyPluginConfig>().enabled;
            this.ctx.setConfig({ enabled });
            return { enabled };
        }
    };

    async onInit(ctx: PluginContext): Promise<MyPluginExports> {
        // 注册服务
        this.registerService('myService', {
            doSomething: () => console.log('服务调用')
        });
        
        // 监听播放器事件
        this.on('play', () => console.log('开始播放'));
        
        return {
            getStatus: () => this.ctx.getConfig<MyPluginConfig>().enabled,
            doSomething: () => console.log('执行操作')
        };
    }

    onStart() {
        console.log('插件启动');
    }

    onConfigChange(newConfig: Partial<MyPluginConfig>) {
        console.log('配置更新:', newConfig);
    }
}

// 使用插件
const plugin = new MyPlugin();
player.use(plugin);

PluginDefinition 接口

interface PluginDefinition<Config = unknown, Exports = unknown> {
    meta: PluginMeta;
    defaultConfig?: Config;
    validateConfig?: (config: unknown) => { valid: boolean; errors?: string[] };
    commands?: Record<string, (args: unknown, ctx: PluginContext) => unknown>;
    configVersion?: number;
    migrations?: Array<{
        from: number;
        to: number;
        migrate: (oldConfig: unknown) => unknown;
    }>;
    
    // 生命周期钩子
    onInit?: (ctx: PluginContext) => Promise<Exports> | Exports | void;
    onStart?: (ctx: PluginContext) => Promise<void> | void;
    onEvent?: <T extends PlayerEventType>(event: PlayerEventBase<T>, ctx: PluginContext) => void;
    onConfigChange?: (newConfig: Partial<Config>, ctx: PluginContext) => void;
    onDestroy?: (ctx: PluginContext) => Promise<void> | void;
}

interface PluginMeta {
    id: string;
    version: string;
    displayName?: string;
    description?: string;
    requires?: Record<string, string>;  // 依赖的插件版本
    optional?: Record<string, string>;  // 可选依赖
    capabilities?: string[];            // 插件能力
    permissions?: string[];             // 所需权限
}

插件上下文 API

interface PluginContext {
    player: PlayerInstance;
    logger: Logger;
    
    // 事件系统
    on<T extends PlayerEventType>(event: T, callback: (event: PlayerEventBase<T>) => void): () => void;
    off<T extends PlayerEventType>(event: T, callback: (event: PlayerEventBase<T>) => void): void;
    emit<T extends PlayerEventType>(event: T, data?: EventPayloadMap[T]): void;
    onAnyPlayerEvent(callback: (event: PlayerEvent) => void): () => void;
    
    // 插件间通信
    onPluginEvent(pluginId: string, type: string, callback: (data: any) => void): () => void;
    emitPluginEvent(pluginId: string, type: string, data?: any): void;
    
    // 服务系统
    registerService<T>(name: string, service: T): void;
    getService<T>(name: string): T | undefined;
    
    // 配置管理
    getConfig<T = unknown>(): T;
    setConfig<T = unknown>(partial: Partial<T>): void;
    
    // 存储系统
    storage: {
        get<T = unknown>(key: string): T | undefined;
        set<T = unknown>(key: string, value: T): void;
        delete(key: string): void;
        keys(): string[];
    };
    
    // 权限检查
    hasPermission?(perm: PluginPermission): boolean;
}

内置插件

PlaybackRatePlugin

播放速度控制插件,自动集成到控制栏:

// 通过配置启用
builtinPlugins: {
    playbackRate: { 
        defaultRate: 1.25,
        options: [
            { value: 0.5, label: '0.5x' },
            { value: 1, label: '1x' },
            { value: 1.25, label: '1.25x' },
            { value: 1.5, label: '1.5x' },
            { value: 2, label: '2x' }
        ]
    }
}

// 或手动安装
import { PlaybackRatePlugin } from '@ebin-player/core';
player.use(PlaybackRatePlugin);

插件开发最佳实践

  1. 继承 BasePlugin - 使用基础类获得通用功能
  2. 声明权限 - 明确插件需要的权限
  3. 提供配置验证 - 确保配置的正确性
  4. 实现生命周期 - 正确处理初始化和销毁
  5. 使用服务系统 - 通过服务与其他插件协作
  6. 错误处理 - 优雅处理异常情况
  7. 类型安全 - 使用 TypeScript 确保类型安全

📱 响应式设计

基于 ResponsiveManager 的智能响应式系统:

  • 移动端 (< 768px): 大按钮,触摸友好,简化控制栏
  • 平板端 (768px - 1024px): 适中控件大小,平衡功能与空间
  • 桌面端 (> 1024px): 完整功能显示,所有控制选项
// 响应式配置
const player = new EbinPlayer(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'advanced',
    uiConfig: {
        // 响应式控制栏配置
        controlBar: {
            mobile: {
                height: 60,
                showAdvancedControls: false
            },
            tablet: {
                height: 50,
                showAdvancedControls: true
            },
            desktop: {
                height: 40,
                showAdvancedControls: true
            }
        }
    }
});

♿ 无障碍访问

基于 ErrorHandler 和 ARIA 标准的完整无障碍支持:

  • ARIA 标签 - 所有交互元素都有适当的标签
  • 键盘导航 - 完整的 Tab 键导航支持
  • 屏幕阅读器 - 兼容主流屏幕阅读器
  • 高对比度 - 支持高对比度模式
  • 焦点管理 - 清晰的焦点指示器
  • 错误处理 - 优雅的错误提示和恢复

🌐 浏览器支持

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+
  • 移动端浏览器 iOS Safari 12+, Chrome Mobile 60+

📦 构建和开发

开发环境

# 克隆项目
git clone https://github.com/your-org/ebin-player.git
cd ebin-player

# 安装依赖
pnpm install

# 开发模式(监听文件变化)
pnpm run dev

# 构建生产版本
pnpm run build

# 类型检查
pnpm run type-check

# 文档开发
pnpm run docs:dev

构建脚本

# 构建 CSS(开发模式)
pnpm run build:css

# 构建 CSS(生产模式)
pnpm run build:css:prod

# 构建 JavaScript
pnpm run build

# 清理构建文件
pnpm run clean

# 构建文档
pnpm run docs:build

# 启动文档服务器
pnpm run docs:serve

# 文档开发模式
pnpm run docs:dev

# 完整构建并启动演示服务器
pnpm run demo

项目结构

src/
├── core/                    # 核心播放器
│   ├── Player.ts           # 主播放器类
│   ├── PlayerCore.ts       # 播放器核心
│   ├── PlayerStore.ts      # 状态管理
│   └── Logger.ts           # 日志系统
├── plugin/                 # 插件系统
│   ├── BasePlugin.ts       # 插件基类
│   ├── PluginManager.ts    # 插件管理器
│   └── built-in/           # 内置插件
├── ui/                     # UI系统
│   ├── ImprovedDefaultUI.ts # 改进版UI
│   ├── UIManager.ts        # UI管理器
│   ├── components/         # UI组件
│   ├── theme/              # 主题管理
│   └── responsive/         # 响应式管理
├── types/                  # 类型定义
└── index.ts               # 主入口文件

📚 文档

🎯 在线演示

📖 示例和演示

基础使用示例

// 基础播放器
import { PlayerInstance } from '@ebin-player/core';

const player = new PlayerInstance(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'custom',
    debug: true
});

// 监听事件
player.on('play', () => console.log('开始播放'));
player.on('pause', () => console.log('暂停播放'));

// 状态订阅
player.subscribe(state => {
    console.log('当前时间:', state.currentTime);
    console.log('播放状态:', state.paused ? '暂停' : '播放');
});

插件使用示例

// 使用内置插件
const player = new PlayerInstance(container, {
    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
    uiMode: 'custom',
    builtinPlugins: {
        playbackRate: {
            defaultRate: 1.25,
            options: [
                { value: 0.5, label: '0.5x' },
                { value: 1, label: '1x' },
                { value: 1.25, label: '1.25x' },
                { value: 1.5, label: '1.5x' },
                { value: 2, label: '2x' }
            ]
        }
    }
});

// 自定义插件
class CustomPlugin extends BasePlugin {
    meta = {
        id: 'custom-plugin',
        version: '1.0.0',
        displayName: 'Custom Plugin'
    };

    async onInit(ctx) {
        // 插件初始化逻辑
        return { customMethod: () => console.log('Custom method') };
    }
}

player.use(new CustomPlugin());

🤝 贡献

欢迎提交 Issue 和 Pull Request!

开发指南

  1. Fork 项目
  2. 创建功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 打开 Pull Request

代码规范

  • 使用 TypeScript 编写
  • 遵循 ESLint 配置
  • 添加适当的类型定义
  • 编写单元测试
  • 更新文档

📄 许可证

MIT License - 详见 LICENSE 文件


Ebin Player - 让视频播放更简单、更强大、更美观!

基于现代架构设计,提供完整的类型安全和强大的扩展能力