Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/strange-coats-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@alfalab/core-components-gallery': patch
---

- Импорт HLS заменён на light версию, только энкодер без дополнительных обвязок.
- Подгрузка модуля перенесена на время после загрузки основного js, для лучшей клиентской доступности основного приложения.
28 changes: 23 additions & 5 deletions packages/gallery/src/components/image-viewer/video/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import React, {
useContext,
useEffect,
useRef,
useState,
} from 'react';
import cn from 'classnames';
import Hls from 'hls.js';
import { type default as HlsType, type ErrorData, type Events } from 'hls.js/dist/hls.light.mjs';

import { Circle } from '@alfalab/core-components-icon-view/circle';
import PlayCompactMIcon from '@alfalab/icons-glyph/PlayCompactMIcon';
Expand All @@ -28,6 +29,7 @@ type Props = {
export const Video = ({ url, index, className, isActive }: Props) => {
const playerRef = useRef<HTMLVideoElement>(null);
const timer = useRef<ReturnType<typeof setTimeout>>();
const [HLSSupported, setHLSSupported] = useState<boolean>(true);

const {
setImageMeta,
Expand All @@ -50,10 +52,22 @@ export const Video = ({ url, index, className, isActive }: Props) => {
}, [index]);

useEffect(() => {
const hls = new Hls();
let hls: HlsType;

if (Hls.isSupported()) {
hls.on(Hls.Events.ERROR, (_, data) => {
async function initHls() {
const { default: Hls } = await import(
/* webpackChunkName: "hls-js-video" */ 'hls.js/dist/hls.light.mjs'
);

hls = new Hls();

if (!Hls.isSupported()) {
setHLSSupported(false);

return;
}

hls.on(Hls.Events.ERROR, (_: Events.ERROR, data: ErrorData) => {
if (data.fatal) {
switch (data.type) {
case Hls.ErrorTypes.MEDIA_ERROR:
Expand All @@ -70,12 +84,15 @@ export const Video = ({ url, index, className, isActive }: Props) => {
});

hls.loadSource(url);

if (playerRef.current) {
hls.attachMedia(playerRef.current);
hls.subtitleDisplay = false;
}
}

initHls().catch();

return () => {
if (hls) {
hls.destroy();
Expand All @@ -84,6 +101,7 @@ export const Video = ({ url, index, className, isActive }: Props) => {
clearTimeout(timer.current);
}
};

/* eslint-disable-next-line react-hooks/exhaustive-deps */
}, [url, index]);

Expand Down Expand Up @@ -183,7 +201,7 @@ export const Video = ({ url, index, className, isActive }: Props) => {
playsInline={true}
muted={mutedVideo}
loop={true}
src={Hls.isSupported() ? undefined : url}
src={HLSSupported ? undefined : url}
className={cn(styles.video, { [styles.mobile]: view === 'mobile' }, className)}
>
<track kind='captions' />
Expand Down
6 changes: 6 additions & 0 deletions packages/gallery/src/hls.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare module 'hls.js/dist/hls.light.mjs' {
import Hls, { ErrorData, Events } from 'hls';

export default Hls;
export { ErrorData, Events };
}