BUR-58 добавлен видео-блок
This commit is contained in:
69
src/components/CameraView.tsx
Normal file
69
src/components/CameraView.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
type CameraViewProps = {
|
||||
title?: string;
|
||||
wsUrl: string;
|
||||
};
|
||||
|
||||
export function CameraView({ title = 'Камера', wsUrl }: CameraViewProps) {
|
||||
const videoRef = useRef<HTMLVideoElement | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current;
|
||||
let player: import('mpegts.js').default.Player | null = null;
|
||||
let cancelled = false;
|
||||
|
||||
if (!video) {
|
||||
return;
|
||||
}
|
||||
|
||||
const clearError = () => setError(null);
|
||||
video.addEventListener('playing', clearError);
|
||||
setError(null);
|
||||
|
||||
void import('mpegts.js').then(({ default: mpegts }) => {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mpegts.isSupported()) {
|
||||
setError('Браузер не поддерживает MPEG-TS поток');
|
||||
return;
|
||||
}
|
||||
|
||||
player = mpegts.createPlayer(
|
||||
{ type: 'mpegts', isLive: true, url: wsUrl },
|
||||
{ liveBufferLatencyChasing: true, liveBufferLatencyMaxLatency: 1.5 },
|
||||
);
|
||||
|
||||
player.attachMediaElement(video);
|
||||
player.load();
|
||||
|
||||
const playResult = player.play();
|
||||
if (playResult instanceof Promise) {
|
||||
void playResult.then(() => setError(null)).catch(() => setError('Не удалось запустить воспроизведение'));
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
video.removeEventListener('playing', clearError);
|
||||
player?.pause();
|
||||
player?.unload();
|
||||
player?.detachMediaElement();
|
||||
player?.destroy();
|
||||
};
|
||||
}, [wsUrl]);
|
||||
|
||||
return (
|
||||
<article className="camera-view">
|
||||
<video ref={videoRef} className="camera-view__video" controls autoPlay muted playsInline />
|
||||
<div className="camera-view__caption">
|
||||
<strong>{title}</strong>
|
||||
<span>{wsUrl}</span>
|
||||
</div>
|
||||
{error ? <div className="camera-view__error">{error}</div> : null}
|
||||
</article>
|
||||
);
|
||||
}
|
||||
7
src/components/CameraViewsContainer.tsx
Normal file
7
src/components/CameraViewsContainer.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { PropsWithChildren } from 'react';
|
||||
|
||||
type CameraViewsContainerProps = PropsWithChildren;
|
||||
|
||||
export function CameraViewsContainer({ children }: CameraViewsContainerProps) {
|
||||
return <div className="camera-views-grid">{children}</div>;
|
||||
}
|
||||
Reference in New Issue
Block a user