fix(artplayer): manage Hls instance and centralize player teardown

Add a dedicated hls field and a destroyPlayer() helper to ensure Hls
instances are properly destroyed when the component is torn down or
re-initialized. Replace inline Hls creation with a guarded pattern that
destroys any existing hls before creating a new one, preventing leaks or
duplicate attachments. Use destroyPlayer() from ngOnDestroy and when the
channel input changes to centralize teardown logic and keep lifecycle
handling consistent.
This commit is contained in:
4gray committed 2025-11-23 21:53:01 +01:00
1 parent 5f35d22076
commit 573ca01925
1 file changed
+20 -10
@@ -38,6 +38,7 @@ export class ArtPlayerComponent implements OnInit, OnDestroy, OnChanges {
@Input() showCaptions = false;
private player!: Artplayer;
private hls: Hls | null = null;
private readonly elementRef = inject(ElementRef);
@@ -46,20 +47,26 @@ export class ArtPlayerComponent implements OnInit, OnDestroy, OnChanges {
}
ngOnDestroy(): void {
if (this.player) {
this.player.destroy();
}
this.destroyPlayer();
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['channel'] && !changes['channel'].firstChange) {
if (this.player) {
this.player.destroy();
}
this.destroyPlayer();
this.initPlayer();
}
}
private destroyPlayer(): void {
if (this.hls) {
this.hls.destroy();
this.hls = null;
}
if (this.player) {
this.player.destroy();
}
}
private initPlayer(): void {
const el = this.elementRef.nativeElement.querySelector(
'.artplayer-container'
@@ -89,11 +96,14 @@ export class ArtPlayerComponent implements OnInit, OnDestroy, OnChanges {
mutex: true,
theme: '#ff0000',
customType: {
m3u8: function (video: HTMLVideoElement, url: string) {
m3u8: (video: HTMLVideoElement, url: string) => {
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
if (this.hls) {
this.hls.destroy();
}
this.hls = new Hls();
this.hls.loadSource(url);
this.hls.attachMedia(video);
} else if (
video.canPlayType('application/vnd.apple.mpegurl')
) {