generated from template/astro-template
76 lines
1.9 KiB
TypeScript
76 lines
1.9 KiB
TypeScript
import { EventEmitter } from 'eventemitter3';
|
||
type VideoPlayerOptions = {
|
||
url?: string;
|
||
emitter?: EventEmitter;
|
||
};
|
||
export class VideoPlayer {
|
||
url?: string;
|
||
isPlaying = false;
|
||
audio?: HTMLAudioElement;
|
||
emitter?: EventEmitter;
|
||
private endedHandler?: () => void;
|
||
constructor(opts?: VideoPlayerOptions) {
|
||
this.url = opts?.url;
|
||
this.emitter = opts?.emitter || new EventEmitter();
|
||
}
|
||
init() {
|
||
if (!this.emitter) {
|
||
this.emitter = new EventEmitter();
|
||
}
|
||
return this.emitter;
|
||
}
|
||
play(url?: string) {
|
||
if (this.isPlaying) {
|
||
return { code: 400 };
|
||
}
|
||
const playUrl = url || this.url;
|
||
if (!playUrl) {
|
||
return { code: 404 };
|
||
}
|
||
if (playUrl !== this.url) {
|
||
this.url = playUrl;
|
||
}
|
||
// 创建新的Audio对象前,确保清理之前的资源
|
||
if (this.audio && this.endedHandler) {
|
||
this.audio.removeEventListener('ended', this.endedHandler);
|
||
}
|
||
|
||
this.audio = new Audio(playUrl);
|
||
this.audio.play();
|
||
this.isPlaying = true;
|
||
this.emitter?.emit('start', { url: playUrl, status: 'start' });
|
||
|
||
// 保存引用以便于后续移除
|
||
this.endedHandler = () => {
|
||
this.audio = undefined;
|
||
this.isPlaying = false;
|
||
this.emitter?.emit('stop', this.url);
|
||
};
|
||
|
||
this.audio.addEventListener('ended', this.endedHandler);
|
||
return { code: 200 };
|
||
}
|
||
stop() {
|
||
if (this.isPlaying) {
|
||
// 移除事件监听器
|
||
if (this.audio && this.endedHandler) {
|
||
this.audio.removeEventListener('ended', this.endedHandler);
|
||
}
|
||
this.audio?.pause();
|
||
this.audio = undefined;
|
||
this.isPlaying = false;
|
||
}
|
||
this.emitter?.emit('stop', this.url);
|
||
}
|
||
onStop(callback: (url: string) => void) {
|
||
this.emitter?.on('stop', callback);
|
||
return () => {
|
||
this.emitter?.off('stop', callback);
|
||
};
|
||
}
|
||
close() {
|
||
this.emitter?.removeAllListeners();
|
||
this.emitter = undefined;
|
||
}
|
||
}
|