mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat: initialize Video.js 10 monorepo with core architecture
- Set up monorepo structure with core, HTML, React, and React Native packages - Add TypeScript configuration with project references - Create foundational packages: media-store, playback-engine, media, icons - Implement platform-specific packages for HTML, React, and React Native - Add comprehensive documentation and development tooling - Include CLAUDE.md with development guidelines and conventional commits 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
export interface MediaSource {
|
||||
src: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface PlaybackEngineOptions {
|
||||
autoplay?: boolean;
|
||||
preload?: 'none' | 'metadata' | 'auto';
|
||||
}
|
||||
|
||||
export abstract class PlaybackEngine {
|
||||
protected element: HTMLMediaElement | null = null;
|
||||
protected options: PlaybackEngineOptions;
|
||||
|
||||
constructor(options: PlaybackEngineOptions = {}) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
abstract attach(element: HTMLMediaElement): void;
|
||||
abstract detach(): void;
|
||||
abstract load(source: MediaSource): Promise<void>;
|
||||
abstract play(): Promise<void>;
|
||||
abstract pause(): void;
|
||||
abstract seekTo(time: number): void;
|
||||
|
||||
getElement(): HTMLMediaElement | null {
|
||||
return this.element;
|
||||
}
|
||||
}
|
||||
|
||||
export class NativePlaybackEngine extends PlaybackEngine {
|
||||
attach(element: HTMLMediaElement): void {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
detach(): void {
|
||||
this.element = null;
|
||||
}
|
||||
|
||||
async load(source: MediaSource): Promise<void> {
|
||||
if (!this.element) {
|
||||
throw new Error('No media element attached');
|
||||
}
|
||||
|
||||
this.element.src = source.src;
|
||||
await new Promise((resolve, reject) => {
|
||||
const onLoad = () => {
|
||||
this.element!.removeEventListener('loadedmetadata', onLoad);
|
||||
this.element!.removeEventListener('error', onError);
|
||||
resolve(void 0);
|
||||
};
|
||||
const onError = () => {
|
||||
this.element!.removeEventListener('loadedmetadata', onLoad);
|
||||
this.element!.removeEventListener('error', onError);
|
||||
reject(new Error('Failed to load media'));
|
||||
};
|
||||
|
||||
this.element.addEventListener('loadedmetadata', onLoad);
|
||||
this.element.addEventListener('error', onError);
|
||||
});
|
||||
}
|
||||
|
||||
async play(): Promise<void> {
|
||||
if (!this.element) {
|
||||
throw new Error('No media element attached');
|
||||
}
|
||||
await this.element.play();
|
||||
}
|
||||
|
||||
pause(): void {
|
||||
if (!this.element) {
|
||||
throw new Error('No media element attached');
|
||||
}
|
||||
this.element.pause();
|
||||
}
|
||||
|
||||
seekTo(time: number): void {
|
||||
if (!this.element) {
|
||||
throw new Error('No media element attached');
|
||||
}
|
||||
this.element.currentTime = time;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user