{"id":31926759,"url":"https://github.com/debingfeng/ebin-player","last_synced_at":"2026-01-20T17:01:15.304Z","repository":{"id":318486902,"uuid":"1070495792","full_name":"debingfeng/ebin-player","owner":"debingfeng","description":"A modern, modular web video player built with TypeScript, featuring a brand-new architecture design with powerful plugin system and highly customizable UI.","archived":false,"fork":false,"pushed_at":"2025-10-15T16:00:16.000Z","size":1106,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-27T16:56:40.875Z","etag":null,"topics":["javascript","player","player-video","typescript","video-player"],"latest_commit_sha":null,"homepage":"https://debingfeng.github.io/ebin-player/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/debingfeng.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-06T02:38:44.000Z","updated_at":"2025-10-15T16:00:20.000Z","dependencies_parsed_at":"2025-10-07T14:32:41.627Z","dependency_job_id":"47a7b7c1-e30f-4400-a5ae-7a46e54da7c4","html_url":"https://github.com/debingfeng/ebin-player","commit_stats":null,"previous_names":["debingfeng/ebin-player"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/debingfeng/ebin-player","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debingfeng%2Febin-player","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debingfeng%2Febin-player/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debingfeng%2Febin-player/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debingfeng%2Febin-player/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/debingfeng","download_url":"https://codeload.github.com/debingfeng/ebin-player/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debingfeng%2Febin-player/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28607624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","player","player-video","typescript","video-player"],"created_at":"2025-10-14T01:50:44.230Z","updated_at":"2026-01-20T17:01:15.271Z","avatar_url":"https://github.com/debingfeng.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎬 Ebin Player\n\n\u003cdiv align=\"left\"\u003e\n  \u003cp\u003e\n    \u003ca href=\"./README.zhCN.md\"\u003e中文文档\u003c/a\u003e |\n    \u003ca href=\"./README.md\"\u003eEnglish Documentation\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\nA modern, modular web video player built with TypeScript, featuring a brand-new architecture design with powerful plugin system and highly customizable UI.\n\n\u003e Framework integrations: React, Vue 2, Vue 3, Angular. See Framework Bindings and the docs/frameworks overview.\n\n## ✨ Core Features\n\n### 🏗️ Modern Architecture\n- ✅ **Layered Architecture Design** - Separated PlayerCore, PlayerStore, PluginManager layers\n- ✅ **Reactive State Management** - Subscription-based state synchronization system\n- ✅ **Event-Driven Architecture** - Complete event listening and dispatching mechanism\n- ✅ **Plugin Design** - Modern plugin system with service, command, and configuration management\n- ✅ **TypeScript Native** - Complete type definitions and type safety\n\n### 🎨 Smart UI System\n- ✅ **Multiple UI Modes** - Native, custom, advanced, and no-UI modes\n- ✅ **Component Architecture** - Modular UI components based on UIManager\n- ✅ **Responsive Design** - Auto-adaptation for mobile, tablet, and desktop\n- ✅ **Theme System** - Dynamic theme switching based on ThemeManager\n- ✅ **Accessibility Support** - Complete ARIA labels and keyboard navigation\n\n### 🔌 Powerful Plugin System\n- ✅ **Modern Plugin Architecture** - Declarative plugins based on PluginDefinition\n- ✅ **Service Location** - Plugin service registration and discovery mechanism\n- ✅ **Command System** - Inter-plugin command invocation and communication\n- ✅ **Configuration Management** - Plugin configuration validation, version control, and migration\n- ✅ **Permission Control** - Fine-grained plugin permission management\n\n### 🚀 Player Features\n- ✅ **Complete Playback Control** - Play/pause, fast forward/rewind, playback rate adjustment\n- ✅ **Fullscreen Support** - Fullscreen and picture-in-picture modes\n- ✅ **Volume Control** - Volume adjustment and mute functionality\n- ✅ **Progress Control** - Precise time control and progress display\n- ✅ **Keyboard Shortcuts** - Complete keyboard operation support\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\npnpm add @ebin-player/core\n# or\nnpm install @ebin-player/core\n# or\nyarn add @ebin-player/core\n```\n\n### Framework Bindings\n\nEbin Player provides official bindings for popular frontend frameworks:\n\n#### React\n```bash\nnpm install @ebin-player/react @ebin-player/core\n```\n\n```tsx\nimport { EbinPlayer } from '@ebin-player/react';\nimport '@ebin-player/core/styles';\n\nfunction App() {\n  return (\n    \u003cEbinPlayer\n      src=\"video.mp4\"\n      uiMode=\"advanced\"\n      onReady={() =\u003e console.log('Player ready')}\n    /\u003e\n  );\n}\n```\n\n#### Vue 2\n```bash\nnpm install @ebin-player/vue2 @ebin-player/core\n```\n\n```vue\n\u003ctemplate\u003e\n  \u003cEbinPlayer\n    :src=\"videoSrc\"\n    :ui-mode=\"'advanced'\"\n    @ready=\"onReady\"\n  /\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport { EbinPlayer } from '@ebin-player/vue2';\nimport '@ebin-player/core/styles';\n\nexport default {\n  components: { EbinPlayer },\n  data() {\n    return { videoSrc: 'video.mp4' };\n  },\n  methods: {\n    onReady() { console.log('Player ready'); }\n  }\n};\n\u003c/script\u003e\n```\n\n#### Vue 3\n```bash\nnpm install @ebin-player/vue3 @ebin-player/core\n```\n\n#### Angular\n```bash\nnpm install @ebin-player/angular @ebin-player/core\n```\n\n```ts\n// app.module.ts\nimport { NgModule } from '@angular/core';\nimport { BrowserModule } from '@angular/platform-browser';\nimport { EbinPlayerModule } from '@ebin-player/angular';\n\n@NgModule({\n  imports: [BrowserModule, EbinPlayerModule],\n})\nexport class AppModule {}\n```\n\n```html\n\u003cebin-player [src]=\"'video.mp4'\" [uiMode]=\"'advanced'\" (ready)=\"onReady()\"\u003e\u003c/ebin-player\u003e\n```\n\n```vue\n\u003ctemplate\u003e\n  \u003cEbinPlayer\n    :src=\"videoSrc\"\n    :ui-mode=\"'advanced'\"\n    @ready=\"onReady\"\n  /\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { ref } from 'vue';\nimport { EbinPlayer } from '@ebin-player/vue3';\nimport '@ebin-player/core/styles';\n\nconst videoSrc = ref('video.mp4');\nconst onReady = () =\u003e console.log('Player ready');\n\u003c/script\u003e\n```\n\n### Basic Usage\n\n#### HTML Import\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003clink rel=\"stylesheet\" href=\"node_modules/@ebin-player/core/dist/styles.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cdiv id=\"player-container\"\u003e\u003c/div\u003e\n    \u003cscript src=\"node_modules/ebin-player/dist/ebin-player.umd.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e\n        const player = new EbinPlayer(\n            document.getElementById('player-container'),\n            {\n                src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n                uiMode: 'advanced',\n                debug: true\n            }\n        );\n    \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### ES6 Module Usage\n\n```javascript\nimport { PlayerInstance } from '@ebin-player/core';\nimport '@ebin-player/core/styles';\n\nconst player = new EbinPlayer(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'advanced',\n    debug: true\n});\n```\n\n#### Using createPlayer Factory Function\n\n```javascript\nimport { createPlayer } from '@ebin-player/core';\nimport '@ebin-player/core/styles';\n\nconst player = createPlayer(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'custom',\n    theme: {\n        primaryColor: '#3b82f6',\n        backgroundColor: 'rgba(0, 0, 0, 0.8)'\n    }\n});\n```\n\n## 🎨 UI Modes\n\nEbin Player provides three UI modes to meet different scenario requirements:\n\n### 1. Native Control Bar Mode (`native`)\n\nUses browser native HTML5 control bar for optimal performance:\n\n```javascript\nconst player = new PlayerInstance(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'native'\n});\n```\n\n### 2. Custom UI Mode (`custom`)\n\nModern custom interface based on ImprovedDefaultUI:\n\n```javascript\nconst player = new PlayerInstance(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'custom',\n    uiConfig: {\n        playButton: true,\n        progressBar: true,\n        timeDisplay: true,\n        volumeControl: true,\n        fullscreenButton: true,\n        playbackRateControl: true\n    },\n    theme: {\n        primaryColor: '#3b82f6',\n        backgroundColor: 'rgba(0, 0, 0, 0.8)',\n        textColor: '#ffffff',\n        controlBarHeight: 50\n    }\n});\n```\n\n### 3. No UI Mode (`none`)\n\nPure player core, suitable for custom development:\n\n```javascript\nconst player = new PlayerInstance(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'none'\n});\n\n// Manually listen to events and state\nplayer.on('play', () =\u003e console.log('Started playing'));\nplayer.subscribe(state =\u003e console.log('State updated:', state));\n```\n\n## ⌨️ Keyboard Shortcuts\n\n| Shortcut | Function |\n|----------|----------|\n| `Space` / `Enter` | Play/Pause |\n| `F` | Toggle fullscreen |\n| `M` | Mute/Unmute |\n| `C` | Toggle captions |\n| `J` | Rewind 10 seconds |\n| `L` | Forward 10 seconds |\n| `←` | Rewind 5 seconds |\n| `→` | Forward 5 seconds |\n| `↑` | Increase volume |\n| `↓` | Decrease volume |\n| `Shift + \u003c` | Decrease playback rate |\n| `Shift + \u003e` | Increase playback rate |\n\n## 🔧 API Reference\n\n### PlayerInstance\n\nMain player class that integrates core functionality, state management, and plugin system.\n\n#### Constructor\n\n```typescript\nnew EbinPlayer(container: HTMLElement, options: PlayerOptions)\n```\n\n#### Core Methods\n\n##### Playback Control\n```typescript\n// Async playback control\nplayer.play(): Promise\u003cPlayerInstance\u003e\nplayer.pause(): PlayerInstance\nplayer.load(): PlayerInstance\n\n// Time control\nplayer.getCurrentTime(): number\nplayer.setCurrentTime(time: number): PlayerInstance\nplayer.getDuration(): number\n\n// Volume control\nplayer.getVolume(): number\nplayer.setVolume(volume: number): PlayerInstance\nplayer.getMuted(): boolean\nplayer.setMuted(muted: boolean): PlayerInstance\n\n// Playback rate\nplayer.getPlaybackRate(): number\nplayer.setPlaybackRate(rate: number): PlayerInstance\n```\n\n##### State Management\n```typescript\n// State access\nplayer.getState(): PlayerState\nplayer.setState(state: Partial\u003cPlayerState\u003e): void\n\n// State subscription\nplayer.subscribe(\n    callback: (state: PlayerState) =\u003e void,\n    keys?: (keyof PlayerState)[]\n): () =\u003e void\n```\n\n##### Event System\n```typescript\n// Event listening\nplayer.on\u003cT extends PlayerEventType\u003e(\n    event: T, \n    callback: (event: PlayerEventBase\u003cT\u003e) =\u003e void\n): () =\u003e void\n\nplayer.off\u003cT extends PlayerEventType\u003e(\n    event: T, \n    callback: (event: PlayerEventBase\u003cT\u003e) =\u003e void\n): void\n\nplayer.emit\u003cT extends PlayerEventType\u003e(\n    event: T, \n    data?: EventPayloadMap[T]\n): PlayerInstance\n```\n\n##### Fullscreen and Picture-in-Picture\n```typescript\n// Fullscreen control\nplayer.requestFullscreen(): Promise\u003cPlayerInstance\u003e\nplayer.exitFullscreen(): Promise\u003cPlayerInstance\u003e\nplayer.isFullscreen(): boolean\n\n// Picture-in-picture\nplayer.requestPictureInPicture(): Promise\u003cPictureInPictureWindow\u003e\nplayer.exitPictureInPicture(): Promise\u003cPlayerInstance\u003e\nplayer.isPictureInPicture(): boolean\n```\n\n##### Plugin System\n```typescript\n// Plugin management\nplayer.use(plugin: PluginDefinition): PlayerInstance\nplayer.unuse(pluginId: string): PlayerInstance\nplayer.getPlugin(pluginId: string): PluginDefinition | undefined\n```\n\n##### UI Control\n```typescript\n// UI management\nplayer.updateUIMode(uiMode: UIMode): PlayerInstance\nplayer.updateUIConfig(config: ControlBarConfig): PlayerInstance\nplayer.updateUITheme(theme: PlayerTheme): PlayerInstance\nplayer.getUIMode(): UIMode\n\n// Element access\nplayer.getContainer(): HTMLElement\nplayer.getVideoElement(): HTMLVideoElement\n```\n\n##### Utility Methods\n```typescript\n// Player info\nplayer.getInfo(): {\n    version: string;\n    lifecycle: string;\n    plugins: string[];\n    state: PlayerState;\n    uiMode: UIMode;\n}\n\n// Debug\nplayer.setDebug(enabled: boolean): void\n\n// Destroy\nplayer.destroy(): void\n```\n\n### Configuration Options\n\n#### PlayerOptions\n\n```typescript\ninterface PlayerOptions {\n    // Basic configuration\n    src: string;                    // Video source\n    autoplay?: boolean;             // Auto play\n    muted?: boolean;                // Muted\n    volume?: number;                // Volume (0-1)\n    playbackRate?: number;          // Playback rate\n    poster?: string;                // Poster image\n    width?: number | string;        // Width\n    height?: number | string;       // Height\n    loop?: boolean;                 // Loop playback\n    preload?: 'none' | 'metadata' | 'auto';  // Preload strategy\n    crossOrigin?: 'anonymous' | 'use-credentials' | '';  // CORS settings\n    playsInline?: boolean;          // Inline playback\n    \n    // UI configuration\n    uiMode?: UIMode;                // UI mode\n    uiConfig?: ControlBarConfig;    // UI component configuration\n    theme?: PlayerTheme;            // Theme configuration\n    \n    // Plugin configuration\n    builtinPlugins?: {              // Built-in plugin configuration\n        playbackRate?: boolean | {\n            defaultRate?: number;\n            options?: Array\u003c{ value: number; label: string }\u003e;\n        };\n    };\n    \n    // Debug configuration\n    debug?: boolean;                // Debug mode\n    logger?: Logger;                // Custom logger\n}\n```\n\n#### ControlBarConfig\n\n```typescript\ninterface ControlBarConfig {\n    // Basic controls\n    playButton?: boolean;\n    progressBar?: boolean;\n    timeDisplay?: boolean;\n    volumeControl?: boolean;\n    fullscreenButton?: boolean;\n    \n    // Advanced features\n    playbackRateControl?: boolean;\n    pictureInPictureButton?: boolean;\n    qualitySelector?: boolean;\n    subtitleToggle?: boolean;\n    aspectRatio?: boolean;\n    screenshot?: boolean;\n    skipButtons?: boolean;\n    \n    // Custom components\n    customButtons?: UIComponent[];\n}\n```\n\n#### PlayerTheme\n\n```typescript\ninterface PlayerTheme {\n    primaryColor?: string;          // Primary color\n    secondaryColor?: string;        // Secondary color\n    backgroundColor?: string;       // Background color\n    textColor?: string;             // Text color\n    controlBarHeight?: number;      // Control bar height\n    borderRadius?: number;          // Border radius\n    fontFamily?: string;            // Font family\n}\n```\n\n#### PlayerState\n\n```typescript\ninterface PlayerState {\n    // Basic playback state\n    src: string;\n    currentTime: number;\n    duration: number;\n    paused: boolean;\n    muted: boolean;\n    volume: number;\n    playbackRate: number;\n    \n    // Media state\n    readyState: number;\n    networkState: number;\n    error: MediaError | null;\n    ended: boolean;\n    loading: boolean;\n    seeking: boolean;\n    \n    // Video dimensions\n    videoWidth: number;\n    videoHeight: number;\n    \n    // Buffer state\n    buffered: TimeRanges | null;\n    seekable: TimeRanges | null;\n    \n    // Playback quality\n    quality: string;\n    bitrate: number;\n}\n```\n\n## 🎨 Theme Customization\n\n### CSS Variables\n\n```css\n:root {\n    --ebin-primary: #3b82f6;\n    --ebin-secondary: #6b7280;\n    --ebin-bg: rgba(0, 0, 0, 0.8);\n    --ebin-text: #ffffff;\n}\n```\n\n### Custom Styles\n\n```css\n/* Custom control bar styles */\n.ebin-control-bar {\n    background: linear-gradient(45deg, #ff6b6b, #4ecdc4);\n    border-radius: 12px;\n}\n\n/* Custom button styles */\n.ebin-play-button {\n    background: linear-gradient(45deg, #ff6b6b, #4ecdc4);\n    border-radius: 50%;\n}\n```\n\n## 🔌 Modern Plugin System\n\nEbin Player adopts a brand-new plugin architecture based on `PluginDefinition` design, providing powerful extensibility and excellent developer experience.\n\n### Plugin Architecture Features\n\n- **Declarative Configuration** - Metadata-driven based on `PluginDefinition`\n- **Service Location** - Plugin service registration and discovery mechanism\n- **Command System** - Inter-plugin command invocation and communication\n- **Configuration Management** - Configuration validation, version control, and migration\n- **Permission Control** - Fine-grained plugin permission management\n- **Lifecycle** - Complete plugin lifecycle management\n\n### Built-in Plugin Configuration\n\nBuilt-in plugins can be automatically enabled through configuration options:\n\n```javascript\nconst player = new EbinPlayer(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'custom',\n    builtinPlugins: {\n        playbackRate: {\n            defaultRate: 1.25,\n            options: [\n                { value: 0.5, label: '0.5x' },\n                { value: 1, label: '1x' },\n                { value: 1.25, label: '1.25x' },\n                { value: 1.5, label: '1.5x' },\n                { value: 2, label: '2x' }\n            ]\n        }\n    }\n});\n```\n\n### Plugin Development\n\n#### Base Plugin Class\n\n```typescript\nimport { BasePlugin, PluginDefinition, PluginContext } from '@ebin-player/core';\n\ninterface MyPluginConfig {\n    enabled: boolean;\n    customOption: string;\n}\n\ninterface MyPluginExports {\n    getStatus(): boolean;\n    doSomething(): void;\n}\n\nclass MyPlugin extends BasePlugin\u003cMyPluginConfig, MyPluginExports\u003e {\n    meta = {\n        id: 'my-plugin',\n        version: '1.0.0',\n        displayName: 'My Plugin',\n        description: 'An example plugin',\n        capabilities: ['custom-feature'],\n        permissions: ['player:control']\n    };\n\n    defaultConfig: MyPluginConfig = {\n        enabled: true,\n        customOption: 'default'\n    };\n\n    validateConfig = (config: unknown) =\u003e {\n        const c = config as Partial\u003cMyPluginConfig\u003e;\n        return { \n            valid: typeof c?.enabled === 'boolean',\n            errors: c?.enabled === undefined ? ['enabled must be boolean'] : []\n        };\n    };\n\n    commands = {\n        toggle: (args: any) =\u003e {\n            const enabled = !this.ctx.getConfig\u003cMyPluginConfig\u003e().enabled;\n            this.ctx.setConfig({ enabled });\n            return { enabled };\n        }\n    };\n\n    async onInit(ctx: PluginContext): Promise\u003cMyPluginExports\u003e {\n        // Register service\n        this.registerService('myService', {\n            doSomething: () =\u003e console.log('Service call')\n        });\n        \n        // Listen to player events\n        this.on('play', () =\u003e console.log('Started playing'));\n        \n        return {\n            getStatus: () =\u003e this.ctx.getConfig\u003cMyPluginConfig\u003e().enabled,\n            doSomething: () =\u003e console.log('Execute operation')\n        };\n    }\n\n    onStart() {\n        console.log('Plugin started');\n    }\n\n    onConfigChange(newConfig: Partial\u003cMyPluginConfig\u003e) {\n        console.log('Configuration updated:', newConfig);\n    }\n}\n\n// Use plugin\nconst plugin = new MyPlugin();\nplayer.use(plugin);\n```\n\n#### Plugin Context API\n\n```typescript\ninterface PluginContext {\n    player: PlayerInstance;\n    logger: Logger;\n    \n    // Event system\n    on\u003cT extends PlayerEventType\u003e(event: T, callback: (event: PlayerEventBase\u003cT\u003e) =\u003e void): () =\u003e void;\n    off\u003cT extends PlayerEventType\u003e(event: T, callback: (event: PlayerEventBase\u003cT\u003e) =\u003e void): void;\n    emit\u003cT extends PlayerEventType\u003e(event: T, data?: EventPayloadMap[T]): void;\n    onAnyPlayerEvent(callback: (event: PlayerEvent) =\u003e void): () =\u003e void;\n    \n    // Inter-plugin communication\n    onPluginEvent(pluginId: string, type: string, callback: (data: any) =\u003e void): () =\u003e void;\n    emitPluginEvent(pluginId: string, type: string, data?: any): void;\n    \n    // Service system\n    registerService\u003cT\u003e(name: string, service: T): void;\n    getService\u003cT\u003e(name: string): T | undefined;\n    \n    // Configuration management\n    getConfig\u003cT = unknown\u003e(): T;\n    setConfig\u003cT = unknown\u003e(partial: Partial\u003cT\u003e): void;\n    \n    // Storage system\n    storage: {\n        get\u003cT = unknown\u003e(key: string): T | undefined;\n        set\u003cT = unknown\u003e(key: string, value: T): void;\n        delete(key: string): void;\n        keys(): string[];\n    };\n    \n    // Permission check\n    hasPermission?(perm: PluginPermission): boolean;\n}\n```\n\n### Built-in Plugins\n\n#### PlaybackRatePlugin\n\nPlayback rate control plugin, automatically integrated into control bar:\n\n```typescript\n// Enable through configuration\nbuiltinPlugins: {\n    playbackRate: { \n        defaultRate: 1.25,\n        options: [\n            { value: 0.5, label: '0.5x' },\n            { value: 1, label: '1x' },\n            { value: 1.25, label: '1.25x' },\n            { value: 1.5, label: '1.5x' },\n            { value: 2, label: '2x' }\n        ]\n    }\n}\n\n// Or manually install\nimport { PlaybackRatePlugin } from '@ebin-player/core';\nplayer.use(PlaybackRatePlugin);\n```\n\n### Plugin Development Best Practices\n\n1. **Extend BasePlugin** - Use base class for common functionality\n2. **Declare Permissions** - Clearly specify required permissions\n3. **Provide Configuration Validation** - Ensure configuration correctness\n4. **Implement Lifecycle** - Properly handle initialization and destruction\n5. **Use Service System** - Collaborate with other plugins through services\n6. **Error Handling** - Gracefully handle exception cases\n7. **Type Safety** - Use TypeScript to ensure type safety\n\n## 📱 Responsive Design\n\nIntelligent responsive system based on `ResponsiveManager`:\n\n- **Mobile** (\u003c 768px): Large buttons, touch-friendly, simplified control bar\n- **Tablet** (768px - 1024px): Moderate control size, balanced functionality and space\n- **Desktop** (\u003e 1024px): Complete functionality display, all control options\n\n```typescript\n// Responsive configuration\nconst player = new EbinPlayer(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'advanced',\n    uiConfig: {\n        // Responsive control bar configuration\n        controlBar: {\n            mobile: {\n                height: 60,\n                showAdvancedControls: false\n            },\n            tablet: {\n                height: 50,\n                showAdvancedControls: true\n            },\n            desktop: {\n                height: 40,\n                showAdvancedControls: true\n            }\n        }\n    }\n});\n```\n\n## ♿ Accessibility\n\nComplete accessibility support based on `ErrorHandler` and ARIA standards:\n\n- ✅ **ARIA Labels** - All interactive elements have appropriate labels\n- ✅ **Keyboard Navigation** - Complete Tab key navigation support\n- ✅ **Screen Reader** - Compatible with mainstream screen readers\n- ✅ **High Contrast** - Support for high contrast mode\n- ✅ **Focus Management** - Clear focus indicators\n- ✅ **Error Handling** - Graceful error prompts and recovery\n\n## 🌐 Browser Support\n\n- **Chrome** 60+\n- **Firefox** 55+\n- **Safari** 12+\n- **Edge** 79+\n- **Mobile Browsers** iOS Safari 12+, Chrome Mobile 60+\n\n### 🔧 Compatibility Features\n\nEbin Player includes comprehensive compatibility adapters for seamless cross-browser experience:\n\n- **Autoplay Management** - Smart fallback strategies for different browsers\n- **Fullscreen/PiP Support** - Unified APIs across all platforms\n- **Subtitle Rendering** - Custom renderer bypassing browser limitations\n- **Touch Gestures** - Mobile-optimized interaction handling\n- **Memory Management** - Efficient resource usage for mobile devices\n\nSee [Browser Compatibility Guide](./docs/en/compatibility.md) for detailed information.\n\n## 📦 Build and Development\n\n### Development Environment\n\n```bash\n# Clone project\ngit clone https://github.com/your-org/ebin-player.git\ncd ebin-player\n\n# Install dependencies\npnpm install\n\n# Development mode (watch file changes)\npnpm run dev\n\n# Build production version\npnpm run build\n\n# Type checking\npnpm run type-check\n\n# Documentation development\npnpm run docs:dev\n```\n\n### Build Scripts\n\n```bash\n# Build CSS (development mode)\npnpm run build:css\n\n# Build CSS (production mode)\npnpm run build:css:prod\n\n# Build JavaScript\npnpm run build\n\n# Clean build files\npnpm run clean\n\n# Build documentation\npnpm run docs:build\n\n# Start documentation server\npnpm run docs:serve\n\n# Documentation development mode\npnpm run docs:dev\n\n# Complete build and start demo server\npnpm run demo\n```\n\n### Project Structure\n\n```\nsrc/\n├── core/                    # Core player\n│   ├── Player.ts           # Main player class\n│   ├── PlayerCore.ts       # Player core\n│   ├── PlayerStore.ts      # State management\n│   └── Logger.ts           # Logging system\n├── plugin/                 # Plugin system\n│   ├── BasePlugin.ts       # Plugin base class\n│   ├── PluginManager.ts    # Plugin manager\n│   └── built-in/           # Built-in plugins\n├── ui/                     # UI system\n│   ├── ImprovedDefaultUI.ts # Improved UI\n│   ├── UIManager.ts        # UI manager\n│   ├── components/         # UI components\n│   ├── theme/              # Theme management\n│   └── responsive/         # Responsive management\n├── types/                  # Type definitions\n└── index.ts               # Main entry file\n```\n\n## 📚 Documentation\n\n- [📖 Complete Documentation](./docs/en/README.md)\n- [🚀 Quick Start](./docs/en/quick-start.md)\n- [🔌 Plugin Development](./docs/en/examples/plugin-development.md)\n- [🎨 Theme Customization](./docs/en/examples/theming.md)\n- [🌐 Browser Compatibility](./docs/en/compatibility.md)\n- [📋 API Documentation](./docs-api/)\n\n## 🎯 Online Demos\n\n- [🎬 Complete Demo](./demos/)\n- [💻 Basic Example](./examples/basic/)\n- [🎨 Custom UI Example](./examples/custom-ui/)\n- [🔌 Plugin Example](./examples/plugins/)\n- [🎨 Theme Example](./examples/themes/)\n\n## 📖 Examples and Demos\n\n### Basic Usage Example\n\n```javascript\n// Basic player\nimport { PlayerInstance } from '@ebin-player/core';\n\nconst player = new EbinPlayer(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'advanced',\n    debug: true\n});\n\n// Listen to events\nplayer.on('play', () =\u003e console.log('Started playing'));\nplayer.on('pause', () =\u003e console.log('Paused playing'));\n\n// State subscription\nplayer.subscribe(state =\u003e {\n    console.log('Current time:', state.currentTime);\n    console.log('Playback state:', state.paused ? 'Paused' : 'Playing');\n});\n```\n\n### Plugin Usage Example\n\n```javascript\n// Use built-in plugins\nconst player = new EbinPlayer(container, {\n    src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',\n    uiMode: 'custom',\n    builtinPlugins: {\n        playbackRate: {\n            defaultRate: 1.25,\n            options: [\n                { value: 0.5, label: '0.5x' },\n                { value: 1, label: '1x' },\n                { value: 1.25, label: '1.25x' },\n                { value: 1.5, label: '1.5x' },\n                { value: 2, label: '2x' }\n            ]\n        }\n    }\n});\n\n// Custom plugin\nclass CustomPlugin extends BasePlugin {\n    meta = {\n        id: 'custom-plugin',\n        version: '1.0.0',\n        displayName: 'Custom Plugin'\n    };\n\n    async onInit(ctx) {\n        // Plugin initialization logic\n        return { customMethod: () =\u003e console.log('Custom method') };\n    }\n}\n\nplayer.use(new CustomPlugin());\n```\n\n## 🤝 Contributing\n\nWelcome to submit Issues and Pull Requests!\n\n### Development Guide\n\n1. Fork the project\n2. Create a feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n### Code Standards\n\n- Write in TypeScript\n- Follow ESLint configuration\n- Add appropriate type definitions\n- Write unit tests\n- Update documentation\n\n## 📄 License\n\nMIT License - See [LICENSE](LICENSE) file for details\n\n---\n\n**Ebin Player** - Making video playback simpler, more powerful, and more beautiful!\n\n\u003e Built with modern architecture design, providing complete type safety and powerful extensibility\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebingfeng%2Febin-player","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdebingfeng%2Febin-player","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebingfeng%2Febin-player/lists"}