https://github.com/debingfeng/ebin-player
A modern, modular web video player built with TypeScript, featuring a brand-new architecture design with powerful plugin system and highly customizable UI.
https://github.com/debingfeng/ebin-player
javascript player player-video typescript video-player
Last synced: 5 months ago
JSON representation
A modern, modular web video player built with TypeScript, featuring a brand-new architecture design with powerful plugin system and highly customizable UI.
- Host: GitHub
- URL: https://github.com/debingfeng/ebin-player
- Owner: debingfeng
- License: mit
- Created: 2025-10-06T02:38:44.000Z (9 months ago)
- Default Branch: master
- Last Pushed: 2025-10-15T16:00:16.000Z (8 months ago)
- Last Synced: 2025-11-27T16:56:40.875Z (7 months ago)
- Topics: javascript, player, player-video, typescript, video-player
- Language: HTML
- Homepage: https://debingfeng.github.io/ebin-player/
- Size: 1.05 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# π¬ Ebin Player
A modern, modular web video player built with TypeScript, featuring a brand-new architecture design with powerful plugin system and highly customizable UI.
> Framework integrations: React, Vue 2, Vue 3, Angular. See Framework Bindings and the docs/frameworks overview.
## β¨ Core Features
### ποΈ Modern Architecture
- β
**Layered Architecture Design** - Separated PlayerCore, PlayerStore, PluginManager layers
- β
**Reactive State Management** - Subscription-based state synchronization system
- β
**Event-Driven Architecture** - Complete event listening and dispatching mechanism
- β
**Plugin Design** - Modern plugin system with service, command, and configuration management
- β
**TypeScript Native** - Complete type definitions and type safety
### π¨ Smart UI System
- β
**Multiple UI Modes** - Native, custom, advanced, and no-UI modes
- β
**Component Architecture** - Modular UI components based on UIManager
- β
**Responsive Design** - Auto-adaptation for mobile, tablet, and desktop
- β
**Theme System** - Dynamic theme switching based on ThemeManager
- β
**Accessibility Support** - Complete ARIA labels and keyboard navigation
### π Powerful Plugin System
- β
**Modern Plugin Architecture** - Declarative plugins based on PluginDefinition
- β
**Service Location** - Plugin service registration and discovery mechanism
- β
**Command System** - Inter-plugin command invocation and communication
- β
**Configuration Management** - Plugin configuration validation, version control, and migration
- β
**Permission Control** - Fine-grained plugin permission management
### π Player Features
- β
**Complete Playback Control** - Play/pause, fast forward/rewind, playback rate adjustment
- β
**Fullscreen Support** - Fullscreen and picture-in-picture modes
- β
**Volume Control** - Volume adjustment and mute functionality
- β
**Progress Control** - Precise time control and progress display
- β
**Keyboard Shortcuts** - Complete keyboard operation support
## π Quick Start
### Installation
```bash
pnpm add @ebin-player/core
# or
npm install @ebin-player/core
# or
yarn add @ebin-player/core
```
### Framework Bindings
Ebin Player provides official bindings for popular frontend frameworks:
#### React
```bash
npm install @ebin-player/react @ebin-player/core
```
```tsx
import { EbinPlayer } from '@ebin-player/react';
import '@ebin-player/core/styles';
function App() {
return (
console.log('Player ready')}
/>
);
}
```
#### Vue 2
```bash
npm install @ebin-player/vue2 @ebin-player/core
```
```vue
import { EbinPlayer } from '@ebin-player/vue2';
import '@ebin-player/core/styles';
export default {
components: { EbinPlayer },
data() {
return { videoSrc: 'video.mp4' };
},
methods: {
onReady() { console.log('Player ready'); }
}
};
```
#### Vue 3
```bash
npm install @ebin-player/vue3 @ebin-player/core
```
#### Angular
```bash
npm install @ebin-player/angular @ebin-player/core
```
```ts
// 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 {}
```
```html
```
```vue
import { ref } from 'vue';
import { EbinPlayer } from '@ebin-player/vue3';
import '@ebin-player/core/styles';
const videoSrc = ref('video.mp4');
const onReady = () => console.log('Player ready');
```
### Basic Usage
#### HTML Import
```html
const player = new EbinPlayer(
document.getElementById('player-container'),
{
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
uiMode: 'advanced',
debug: true
}
);
```
#### ES6 Module Usage
```javascript
import { PlayerInstance } from '@ebin-player/core';
import '@ebin-player/core/styles';
const player = new EbinPlayer(container, {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
uiMode: 'advanced',
debug: true
});
```
#### Using createPlayer Factory Function
```javascript
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 Modes
Ebin Player provides three UI modes to meet different scenario requirements:
### 1. Native Control Bar Mode (`native`)
Uses browser native HTML5 control bar for optimal performance:
```javascript
const player = new PlayerInstance(container, {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
uiMode: 'native'
});
```
### 2. Custom UI Mode (`custom`)
Modern custom interface based on ImprovedDefaultUI:
```javascript
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. No UI Mode (`none`)
Pure player core, suitable for custom development:
```javascript
const player = new PlayerInstance(container, {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
uiMode: 'none'
});
// Manually listen to events and state
player.on('play', () => console.log('Started playing'));
player.subscribe(state => console.log('State updated:', state));
```
## β¨οΈ Keyboard Shortcuts
| Shortcut | Function |
|----------|----------|
| `Space` / `Enter` | Play/Pause |
| `F` | Toggle fullscreen |
| `M` | Mute/Unmute |
| `C` | Toggle captions |
| `J` | Rewind 10 seconds |
| `L` | Forward 10 seconds |
| `β` | Rewind 5 seconds |
| `β` | Forward 5 seconds |
| `β` | Increase volume |
| `β` | Decrease volume |
| `Shift + <` | Decrease playback rate |
| `Shift + >` | Increase playback rate |
## π§ API Reference
### PlayerInstance
Main player class that integrates core functionality, state management, and plugin system.
#### Constructor
```typescript
new EbinPlayer(container: HTMLElement, options: PlayerOptions)
```
#### Core Methods
##### Playback Control
```typescript
// Async playback control
player.play(): Promise
player.pause(): PlayerInstance
player.load(): PlayerInstance
// Time control
player.getCurrentTime(): number
player.setCurrentTime(time: number): PlayerInstance
player.getDuration(): number
// Volume control
player.getVolume(): number
player.setVolume(volume: number): PlayerInstance
player.getMuted(): boolean
player.setMuted(muted: boolean): PlayerInstance
// Playback rate
player.getPlaybackRate(): number
player.setPlaybackRate(rate: number): PlayerInstance
```
##### State Management
```typescript
// State access
player.getState(): PlayerState
player.setState(state: Partial): void
// State subscription
player.subscribe(
callback: (state: PlayerState) => void,
keys?: (keyof PlayerState)[]
): () => void
```
##### Event System
```typescript
// Event listening
player.on(
event: T,
callback: (event: PlayerEventBase) => void
): () => void
player.off(
event: T,
callback: (event: PlayerEventBase) => void
): void
player.emit(
event: T,
data?: EventPayloadMap[T]
): PlayerInstance
```
##### Fullscreen and Picture-in-Picture
```typescript
// Fullscreen control
player.requestFullscreen(): Promise
player.exitFullscreen(): Promise
player.isFullscreen(): boolean
// Picture-in-picture
player.requestPictureInPicture(): Promise
player.exitPictureInPicture(): Promise
player.isPictureInPicture(): boolean
```
##### Plugin System
```typescript
// Plugin management
player.use(plugin: PluginDefinition): PlayerInstance
player.unuse(pluginId: string): PlayerInstance
player.getPlugin(pluginId: string): PluginDefinition | undefined
```
##### UI Control
```typescript
// UI management
player.updateUIMode(uiMode: UIMode): PlayerInstance
player.updateUIConfig(config: ControlBarConfig): PlayerInstance
player.updateUITheme(theme: PlayerTheme): PlayerInstance
player.getUIMode(): UIMode
// Element access
player.getContainer(): HTMLElement
player.getVideoElement(): HTMLVideoElement
```
##### Utility Methods
```typescript
// Player info
player.getInfo(): {
version: string;
lifecycle: string;
plugins: string[];
state: PlayerState;
uiMode: UIMode;
}
// Debug
player.setDebug(enabled: boolean): void
// Destroy
player.destroy(): void
```
### Configuration Options
#### PlayerOptions
```typescript
interface PlayerOptions {
// Basic configuration
src: string; // Video source
autoplay?: boolean; // Auto play
muted?: boolean; // Muted
volume?: number; // Volume (0-1)
playbackRate?: number; // Playback rate
poster?: string; // Poster image
width?: number | string; // Width
height?: number | string; // Height
loop?: boolean; // Loop playback
preload?: 'none' | 'metadata' | 'auto'; // Preload strategy
crossOrigin?: 'anonymous' | 'use-credentials' | ''; // CORS settings
playsInline?: boolean; // Inline playback
// UI configuration
uiMode?: UIMode; // UI mode
uiConfig?: ControlBarConfig; // UI component configuration
theme?: PlayerTheme; // Theme configuration
// Plugin configuration
builtinPlugins?: { // Built-in plugin configuration
playbackRate?: boolean | {
defaultRate?: number;
options?: Array<{ value: number; label: string }>;
};
};
// Debug configuration
debug?: boolean; // Debug mode
logger?: Logger; // Custom logger
}
```
#### ControlBarConfig
```typescript
interface ControlBarConfig {
// Basic controls
playButton?: boolean;
progressBar?: boolean;
timeDisplay?: boolean;
volumeControl?: boolean;
fullscreenButton?: boolean;
// Advanced features
playbackRateControl?: boolean;
pictureInPictureButton?: boolean;
qualitySelector?: boolean;
subtitleToggle?: boolean;
aspectRatio?: boolean;
screenshot?: boolean;
skipButtons?: boolean;
// Custom components
customButtons?: UIComponent[];
}
```
#### PlayerTheme
```typescript
interface PlayerTheme {
primaryColor?: string; // Primary color
secondaryColor?: string; // Secondary color
backgroundColor?: string; // Background color
textColor?: string; // Text color
controlBarHeight?: number; // Control bar height
borderRadius?: number; // Border radius
fontFamily?: string; // Font family
}
```
#### PlayerState
```typescript
interface PlayerState {
// Basic playback state
src: string;
currentTime: number;
duration: number;
paused: boolean;
muted: boolean;
volume: number;
playbackRate: number;
// Media state
readyState: number;
networkState: number;
error: MediaError | null;
ended: boolean;
loading: boolean;
seeking: boolean;
// Video dimensions
videoWidth: number;
videoHeight: number;
// Buffer state
buffered: TimeRanges | null;
seekable: TimeRanges | null;
// Playback quality
quality: string;
bitrate: number;
}
```
## π¨ Theme Customization
### CSS Variables
```css
:root {
--ebin-primary: #3b82f6;
--ebin-secondary: #6b7280;
--ebin-bg: rgba(0, 0, 0, 0.8);
--ebin-text: #ffffff;
}
```
### Custom Styles
```css
/* Custom control bar styles */
.ebin-control-bar {
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
border-radius: 12px;
}
/* Custom button styles */
.ebin-play-button {
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
border-radius: 50%;
}
```
## π Modern Plugin System
Ebin Player adopts a brand-new plugin architecture based on `PluginDefinition` design, providing powerful extensibility and excellent developer experience.
### Plugin Architecture Features
- **Declarative Configuration** - Metadata-driven based on `PluginDefinition`
- **Service Location** - Plugin service registration and discovery mechanism
- **Command System** - Inter-plugin command invocation and communication
- **Configuration Management** - Configuration validation, version control, and migration
- **Permission Control** - Fine-grained plugin permission management
- **Lifecycle** - Complete plugin lifecycle management
### Built-in Plugin Configuration
Built-in plugins can be automatically enabled through configuration options:
```javascript
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' }
]
}
}
});
```
### Plugin Development
#### Base Plugin Class
```typescript
import { BasePlugin, PluginDefinition, PluginContext } from '@ebin-player/core';
interface MyPluginConfig {
enabled: boolean;
customOption: string;
}
interface MyPluginExports {
getStatus(): boolean;
doSomething(): void;
}
class MyPlugin extends BasePlugin {
meta = {
id: 'my-plugin',
version: '1.0.0',
displayName: 'My Plugin',
description: 'An example plugin',
capabilities: ['custom-feature'],
permissions: ['player:control']
};
defaultConfig: MyPluginConfig = {
enabled: true,
customOption: 'default'
};
validateConfig = (config: unknown) => {
const c = config as Partial;
return {
valid: typeof c?.enabled === 'boolean',
errors: c?.enabled === undefined ? ['enabled must be boolean'] : []
};
};
commands = {
toggle: (args: any) => {
const enabled = !this.ctx.getConfig().enabled;
this.ctx.setConfig({ enabled });
return { enabled };
}
};
async onInit(ctx: PluginContext): Promise {
// Register service
this.registerService('myService', {
doSomething: () => console.log('Service call')
});
// Listen to player events
this.on('play', () => console.log('Started playing'));
return {
getStatus: () => this.ctx.getConfig().enabled,
doSomething: () => console.log('Execute operation')
};
}
onStart() {
console.log('Plugin started');
}
onConfigChange(newConfig: Partial) {
console.log('Configuration updated:', newConfig);
}
}
// Use plugin
const plugin = new MyPlugin();
player.use(plugin);
```
#### Plugin Context API
```typescript
interface PluginContext {
player: PlayerInstance;
logger: Logger;
// Event system
on(event: T, callback: (event: PlayerEventBase) => void): () => void;
off(event: T, callback: (event: PlayerEventBase) => void): void;
emit(event: T, data?: EventPayloadMap[T]): void;
onAnyPlayerEvent(callback: (event: PlayerEvent) => void): () => void;
// Inter-plugin communication
onPluginEvent(pluginId: string, type: string, callback: (data: any) => void): () => void;
emitPluginEvent(pluginId: string, type: string, data?: any): void;
// Service system
registerService(name: string, service: T): void;
getService(name: string): T | undefined;
// Configuration management
getConfig(): T;
setConfig(partial: Partial): void;
// Storage system
storage: {
get(key: string): T | undefined;
set(key: string, value: T): void;
delete(key: string): void;
keys(): string[];
};
// Permission check
hasPermission?(perm: PluginPermission): boolean;
}
```
### Built-in Plugins
#### PlaybackRatePlugin
Playback rate control plugin, automatically integrated into control bar:
```typescript
// Enable through configuration
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' }
]
}
}
// Or manually install
import { PlaybackRatePlugin } from '@ebin-player/core';
player.use(PlaybackRatePlugin);
```
### Plugin Development Best Practices
1. **Extend BasePlugin** - Use base class for common functionality
2. **Declare Permissions** - Clearly specify required permissions
3. **Provide Configuration Validation** - Ensure configuration correctness
4. **Implement Lifecycle** - Properly handle initialization and destruction
5. **Use Service System** - Collaborate with other plugins through services
6. **Error Handling** - Gracefully handle exception cases
7. **Type Safety** - Use TypeScript to ensure type safety
## π± Responsive Design
Intelligent responsive system based on `ResponsiveManager`:
- **Mobile** (< 768px): Large buttons, touch-friendly, simplified control bar
- **Tablet** (768px - 1024px): Moderate control size, balanced functionality and space
- **Desktop** (> 1024px): Complete functionality display, all control options
```typescript
// Responsive configuration
const player = new EbinPlayer(container, {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
uiMode: 'advanced',
uiConfig: {
// Responsive control bar configuration
controlBar: {
mobile: {
height: 60,
showAdvancedControls: false
},
tablet: {
height: 50,
showAdvancedControls: true
},
desktop: {
height: 40,
showAdvancedControls: true
}
}
}
});
```
## βΏ Accessibility
Complete accessibility support based on `ErrorHandler` and ARIA standards:
- β
**ARIA Labels** - All interactive elements have appropriate labels
- β
**Keyboard Navigation** - Complete Tab key navigation support
- β
**Screen Reader** - Compatible with mainstream screen readers
- β
**High Contrast** - Support for high contrast mode
- β
**Focus Management** - Clear focus indicators
- β
**Error Handling** - Graceful error prompts and recovery
## π Browser Support
- **Chrome** 60+
- **Firefox** 55+
- **Safari** 12+
- **Edge** 79+
- **Mobile Browsers** iOS Safari 12+, Chrome Mobile 60+
### π§ Compatibility Features
Ebin Player includes comprehensive compatibility adapters for seamless cross-browser experience:
- **Autoplay Management** - Smart fallback strategies for different browsers
- **Fullscreen/PiP Support** - Unified APIs across all platforms
- **Subtitle Rendering** - Custom renderer bypassing browser limitations
- **Touch Gestures** - Mobile-optimized interaction handling
- **Memory Management** - Efficient resource usage for mobile devices
See [Browser Compatibility Guide](./docs/en/compatibility.md) for detailed information.
## π¦ Build and Development
### Development Environment
```bash
# Clone project
git clone https://github.com/your-org/ebin-player.git
cd ebin-player
# Install dependencies
pnpm install
# Development mode (watch file changes)
pnpm run dev
# Build production version
pnpm run build
# Type checking
pnpm run type-check
# Documentation development
pnpm run docs:dev
```
### Build Scripts
```bash
# Build CSS (development mode)
pnpm run build:css
# Build CSS (production mode)
pnpm run build:css:prod
# Build JavaScript
pnpm run build
# Clean build files
pnpm run clean
# Build documentation
pnpm run docs:build
# Start documentation server
pnpm run docs:serve
# Documentation development mode
pnpm run docs:dev
# Complete build and start demo server
pnpm run demo
```
### Project Structure
```
src/
βββ core/ # Core player
β βββ Player.ts # Main player class
β βββ PlayerCore.ts # Player core
β βββ PlayerStore.ts # State management
β βββ Logger.ts # Logging system
βββ plugin/ # Plugin system
β βββ BasePlugin.ts # Plugin base class
β βββ PluginManager.ts # Plugin manager
β βββ built-in/ # Built-in plugins
βββ ui/ # UI system
β βββ ImprovedDefaultUI.ts # Improved UI
β βββ UIManager.ts # UI manager
β βββ components/ # UI components
β βββ theme/ # Theme management
β βββ responsive/ # Responsive management
βββ types/ # Type definitions
βββ index.ts # Main entry file
```
## π Documentation
- [π Complete Documentation](./docs/en/README.md)
- [π Quick Start](./docs/en/quick-start.md)
- [π Plugin Development](./docs/en/examples/plugin-development.md)
- [π¨ Theme Customization](./docs/en/examples/theming.md)
- [π Browser Compatibility](./docs/en/compatibility.md)
- [π API Documentation](./docs-api/)
## π― Online Demos
- [π¬ Complete Demo](./demos/)
- [π» Basic Example](./examples/basic/)
- [π¨ Custom UI Example](./examples/custom-ui/)
- [π Plugin Example](./examples/plugins/)
- [π¨ Theme Example](./examples/themes/)
## π Examples and Demos
### Basic Usage Example
```javascript
// Basic player
import { PlayerInstance } from '@ebin-player/core';
const player = new EbinPlayer(container, {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
uiMode: 'advanced',
debug: true
});
// Listen to events
player.on('play', () => console.log('Started playing'));
player.on('pause', () => console.log('Paused playing'));
// State subscription
player.subscribe(state => {
console.log('Current time:', state.currentTime);
console.log('Playback state:', state.paused ? 'Paused' : 'Playing');
});
```
### Plugin Usage Example
```javascript
// Use built-in plugins
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' }
]
}
}
});
// Custom plugin
class CustomPlugin extends BasePlugin {
meta = {
id: 'custom-plugin',
version: '1.0.0',
displayName: 'Custom Plugin'
};
async onInit(ctx) {
// Plugin initialization logic
return { customMethod: () => console.log('Custom method') };
}
}
player.use(new CustomPlugin());
```
## π€ Contributing
Welcome to submit Issues and Pull Requests!
### Development Guide
1. Fork the project
2. Create a feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
### Code Standards
- Write in TypeScript
- Follow ESLint configuration
- Add appropriate type definitions
- Write unit tests
- Update documentation
## π License
MIT License - See [LICENSE](LICENSE) file for details
---
**Ebin Player** - Making video playback simpler, more powerful, and more beautiful!
> Built with modern architecture design, providing complete type safety and powerful extensibility