Files
TeleWave/frontend/src/shared/ui/hls-video.tsx
T
Leonid Pershin 281d081e6b
ci / build-backend (push) Successful in 2m23s
ci / build-frontend (push) Successful in 54s
ci / tests (push) Successful in 2m18s
ci / sonar (push) Successful in 5m51s
Refactor admin panels to utilize CreateNameDialog for creating new entities
Updated the BumpersPanel, ChannelsPanel, CollectionsPanel, GroupsPanel, ClipGroupPanel, and ShowsPanel components to replace direct input fields with a CreateNameDialog for creating new items. This change enhances user experience by centralizing the creation process and improving UI consistency. Localization strings were also updated to reflect new dialog titles and labels in both English and Russian.
2026-07-29 23:26:32 +03:00

62 lines
2.5 KiB
TypeScript

import Hls from 'hls.js'
import { useEffect, useRef } from 'react'
import { getAccessToken } from '@/shared/api/client'
import { cn } from '@/shared/lib/cn'
/**
* Мини-плеер HLS для админки: плейлист и сегменты лежат под admin-роутами (JWT), поэтому запросы
* идут через hls.js с Bearer-заголовком. Нативный путь (Safari) — только там, где hls.js не нужен.
*/
export function HlsVideo({
src,
className,
autoPlay = false,
}: Readonly<{ src: string; className?: string; autoPlay?: boolean }>) {
const videoRef = useRef<HTMLVideoElement>(null)
useEffect(() => {
const video = videoRef.current
if (!video) return
// Атрибута autoplay мало: к моменту вставки <video> у него нет источника — плейлист доедет
// позже, и браузер стартовать будет уже нечему. Поэтому запускаем руками по готовности.
// Отказ глотаем: политика автовоспроизведения может не пустить, и это не ошибка — у плеера
// есть кнопка.
const start = () => void video.play().catch(() => undefined)
let hls: Hls | null = null
if (Hls.isSupported()) {
hls = new Hls({
xhrSetup: (xhr) => {
const token = getAccessToken()
if (token) xhr.setRequestHeader('Authorization', `Bearer ${token}`)
},
})
hls.loadSource(src)
hls.attachMedia(video)
if (autoPlay) hls.on(Hls.Events.MANIFEST_PARSED, start)
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = src
if (autoPlay) video.addEventListener('loadedmetadata', start, { once: true })
}
return () => {
video.removeEventListener('loadedmetadata', start)
hls?.destroy()
}
}, [src, autoPlay])
return (
<video
ref={videoRef}
controls
playsInline
className={cn('aspect-video w-full rounded-md border border-border bg-black', className)}
>
{/* Субтитров пайплайн не производит: ffmpeg режет видео и звук, дорожек с текстом нет.
Пустой track объявляет это явно, вместо молчаливого отсутствия. */}
<track kind="captions" />
</video>
)
}