Files
Toju/toju-app/src/app/domains/experimental-media/feature/experimental-vlc-player/experimental-vlc-player.component.ts
2026-05-17 15:14:52 +02:00

110 lines
2.4 KiB
TypeScript

import {
AfterViewInit,
Component,
ElementRef,
OnDestroy,
ViewChild,
inject,
input,
output,
signal
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
lucideDownload,
lucideRefreshCw,
lucideX
} from '@ng-icons/lucide';
import {
ExperimentalVlcPlayerHandle,
ExperimentalVlcRuntimeService
} from '../../infrastructure/services/experimental-vlc-runtime.service';
@Component({
selector: 'app-experimental-vlc-player',
standalone: true,
imports: [CommonModule, NgIcon],
viewProviders: [
provideIcons({
lucideDownload,
lucideRefreshCw,
lucideX
})
],
templateUrl: './experimental-vlc-player.component.html'
})
export class ExperimentalVlcPlayerComponent implements AfterViewInit, OnDestroy {
@ViewChild('playerMount') playerMount?: ElementRef<HTMLDivElement>;
src = input.required<string>();
filename = input.required<string>();
mime = input.required<string>();
sizeLabel = input<string>('');
closed = output<void>();
downloadRequested = output<void>();
private readonly runtime = inject(ExperimentalVlcRuntimeService);
private playerHandle: ExperimentalVlcPlayerHandle | null = null;
readonly status = signal<'loading' | 'ready' | 'error'>('loading');
readonly errorMessage = signal('');
ngAfterViewInit(): void {
void this.loadPlayer();
}
ngOnDestroy(): void {
this.destroyPlayer();
}
retry(): void {
this.destroyPlayer();
void this.loadPlayer();
}
close(): void {
this.closed.emit();
}
requestDownload(): void {
this.downloadRequested.emit();
}
private async loadPlayer(): Promise<void> {
const container = this.playerMount?.nativeElement;
if (!container) {
return;
}
this.status.set('loading');
this.errorMessage.set('');
container.replaceChildren();
try {
this.playerHandle = await this.runtime.createPlayer({
container,
sourceUrl: this.src(),
filename: this.filename(),
mime: this.mime()
});
this.status.set('ready');
} catch (error) {
this.status.set('error');
this.errorMessage.set(error instanceof Error ? error.message : 'Experimental VLC.js playback failed to start.');
}
}
private destroyPlayer(): void {
try {
this.playerHandle?.destroy?.();
} catch {}
this.playerHandle = null;
this.playerMount?.nativeElement.replaceChildren();
}
}