ai-pages/src/lib/player.ts
2025-05-24 09:11:30 +08:00

76 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}