fix: destroy hls.js instance on media unmount (#749)

This commit is contained in:
Wesley Luyten
2026-03-06 11:30:48 +11:00
committed by GitHub
parent 5fc52aa969
commit c4e8bbd3a2
4 changed files with 21 additions and 7 deletions
+5 -4
View File
@@ -53,10 +53,11 @@ export function MediaDelegateMixin<Base extends Constructor<any>, Delegate exten
} }
return DelegateMedia as unknown as Constructor< return DelegateMedia as unknown as Constructor<
InstanceType<Base> & { InstanceType<Base> &
attach(target: EventTarget): void; InstanceType<Delegate> & {
detach(): void; attach(target: EventTarget): void;
} detach(): void;
}
> & > &
Omit<Base, 'prototype'>; Omit<Base, 'prototype'>;
} }
+4
View File
@@ -28,6 +28,10 @@ export class HlsMediaDelegateBase implements MediaDelegate {
this.#engine.detachMedia(); this.#engine.detachMedia();
} }
destroy(): void {
this.#engine.destroy();
}
set src(src: string) { set src(src: string) {
this.#engine.loadSource(src); this.#engine.loadSource(src);
} }
@@ -25,4 +25,12 @@ export class HlsVideo extends HlsCustomMedia {
this.src = newValue ?? ''; this.src = newValue ?? '';
} }
} }
disconnectedCallback(): void {
super.disconnectedCallback();
if (!this.hasAttribute('keep-alive')) {
this.destroy();
}
}
} }
+4 -3
View File
@@ -1,10 +1,11 @@
import { HlsMedia } from '@videojs/core/dom/media/hls'; import { HlsMedia } from '@videojs/core/dom/media/hls';
import type { PropsWithChildren, VideoHTMLAttributes } from 'react'; import type { PropsWithChildren, VideoHTMLAttributes } from 'react';
import { forwardRef, useEffect, useMemo } from 'react'; import { forwardRef, useMemo } from 'react';
import { useMediaRegistration } from '../../player/context'; import { useMediaRegistration } from '../../player/context';
import { attachMediaElement } from '../../utils/attach-media-element'; import { attachMediaElement } from '../../utils/attach-media-element';
import { mediaProps } from '../../utils/media-props'; import { mediaProps } from '../../utils/media-props';
import { useComposedRefs } from '../../utils/use-composed-refs'; import { useComposedRefs } from '../../utils/use-composed-refs';
import { useDestroy } from '../../utils/use-destroy';
export type HlsVideoProps = PropsWithChildren<VideoHTMLAttributes<HTMLVideoElement>>; export type HlsVideoProps = PropsWithChildren<VideoHTMLAttributes<HTMLVideoElement>>;
@@ -12,9 +13,9 @@ export const HlsVideo = forwardRef<HTMLVideoElement, HlsVideoProps>(({ children,
const mediaApi = useMemo(() => new HlsMedia(), []); const mediaApi = useMemo(() => new HlsMedia(), []);
const setMedia = useMediaRegistration(); const setMedia = useMediaRegistration();
useEffect(() => { useDestroy(mediaApi, () => {
setMedia?.(mediaApi); setMedia?.(mediaApi);
}, [mediaApi, setMedia]); });
const composedRef = useComposedRefs(attachMediaElement(mediaApi), ref); const composedRef = useComposedRefs(attachMediaElement(mediaApi), ref);
return ( return (