2022-02-27 15:04:12 +01:00
|
|
|
import { h } from 'preact';
|
2022-06-24 17:52:17 +02:00
|
|
|
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
|
2022-02-27 15:04:12 +01:00
|
|
|
import { useApiHost } from '../../api';
|
|
|
|
import { isNullOrUndefined } from '../../utils/objectUtils';
|
|
|
|
|
2022-06-02 23:05:56 +02:00
|
|
|
import 'videojs-seek-buttons';
|
|
|
|
import 'video.js/dist/video-js.css';
|
|
|
|
import 'videojs-seek-buttons/dist/videojs-seek-buttons.css';
|
|
|
|
|
2022-06-24 17:52:17 +02:00
|
|
|
import videojs, { VideoJsPlayer } from 'video.js';
|
2022-06-02 23:05:56 +02:00
|
|
|
|
2022-02-27 15:04:12 +01:00
|
|
|
interface OnTimeUpdateEvent {
|
|
|
|
timestamp: number;
|
|
|
|
isPlaying: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface HistoryVideoProps {
|
2022-03-06 05:16:31 +01:00
|
|
|
id?: string;
|
2022-02-27 15:04:12 +01:00
|
|
|
isPlaying: boolean;
|
|
|
|
currentTime: number;
|
|
|
|
onTimeUpdate?: (event: OnTimeUpdateEvent) => void;
|
|
|
|
onPause: () => void;
|
|
|
|
onPlay: () => void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const HistoryVideo = ({
|
|
|
|
id,
|
|
|
|
isPlaying: videoIsPlaying,
|
|
|
|
currentTime,
|
|
|
|
onTimeUpdate,
|
|
|
|
onPause,
|
|
|
|
onPlay,
|
|
|
|
}: HistoryVideoProps) => {
|
|
|
|
const apiHost = useApiHost();
|
2022-06-24 16:35:56 +02:00
|
|
|
const videoRef = useRef<HTMLVideoElement>(null);
|
2022-02-27 15:04:12 +01:00
|
|
|
|
2022-06-24 17:52:17 +02:00
|
|
|
const [video, setVideo] = useState<VideoJsPlayer>();
|
|
|
|
|
2022-02-27 15:04:12 +01:00
|
|
|
useEffect(() => {
|
2022-06-24 17:52:17 +02:00
|
|
|
let video: VideoJsPlayer
|
|
|
|
if (videoRef.current) {
|
|
|
|
video = videojs(videoRef.current, {})
|
|
|
|
setVideo(video)
|
2022-02-27 15:04:12 +01:00
|
|
|
}
|
2022-06-24 17:52:17 +02:00
|
|
|
() => video?.dispose()
|
2022-06-02 23:05:56 +02:00
|
|
|
}, [videoRef]);
|
2022-02-27 15:04:12 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
2022-06-24 17:52:17 +02:00
|
|
|
if (!video) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-06-02 23:05:56 +02:00
|
|
|
if (!id) {
|
2022-06-24 17:52:17 +02:00
|
|
|
video.pause()
|
|
|
|
return
|
2022-06-02 23:05:56 +02:00
|
|
|
}
|
2022-06-24 17:52:17 +02:00
|
|
|
|
2022-06-02 23:05:56 +02:00
|
|
|
video.src({
|
2022-08-17 17:28:32 +02:00
|
|
|
src: `${apiHost}/vod/event/${id}/master.m3u8`,
|
2022-06-02 23:05:56 +02:00
|
|
|
type: 'application/vnd.apple.mpegurl',
|
|
|
|
});
|
|
|
|
video.poster(`${apiHost}/api/events/${id}/snapshot.jpg`);
|
|
|
|
if (videoIsPlaying) {
|
|
|
|
video.play();
|
|
|
|
}
|
2022-11-13 17:31:36 +01:00
|
|
|
}, [video, id, apiHost, videoIsPlaying]);
|
2022-02-27 15:04:12 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const video = videoRef.current;
|
|
|
|
const videoExists = !isNullOrUndefined(video);
|
|
|
|
const hasSeeked = currentTime >= 0;
|
2022-03-06 05:16:31 +01:00
|
|
|
if (video && videoExists && hasSeeked) {
|
2022-02-27 15:04:12 +01:00
|
|
|
video.currentTime = currentTime;
|
|
|
|
}
|
|
|
|
}, [currentTime, videoRef]);
|
|
|
|
|
|
|
|
const onTimeUpdateHandler = useCallback(
|
|
|
|
(event: Event) => {
|
|
|
|
const target = event.target as HTMLMediaElement;
|
|
|
|
const timeUpdateEvent = {
|
|
|
|
isPlaying: videoIsPlaying,
|
|
|
|
timestamp: target.currentTime,
|
|
|
|
};
|
|
|
|
onTimeUpdate && onTimeUpdate(timeUpdateEvent);
|
|
|
|
},
|
|
|
|
[videoIsPlaying, onTimeUpdate]
|
|
|
|
);
|
|
|
|
|
2022-06-24 17:52:17 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (video && video.readyState() >= 1) {
|
|
|
|
if (videoIsPlaying) {
|
|
|
|
video.play()
|
|
|
|
} else {
|
|
|
|
video.pause()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, [video, videoIsPlaying])
|
|
|
|
|
|
|
|
const onLoad = useCallback(() => {
|
|
|
|
if (video && video.readyState() >= 1 && videoIsPlaying) {
|
|
|
|
video.play()
|
|
|
|
}
|
|
|
|
}, [video, videoIsPlaying])
|
2022-11-13 17:31:36 +01:00
|
|
|
|
2022-02-27 15:04:12 +01:00
|
|
|
return (
|
2022-06-02 23:05:56 +02:00
|
|
|
<div data-vjs-player>
|
|
|
|
<video
|
|
|
|
ref={videoRef}
|
|
|
|
onTimeUpdate={onTimeUpdateHandler}
|
2022-06-24 17:52:17 +02:00
|
|
|
onLoadedMetadata={onLoad}
|
2022-06-02 23:05:56 +02:00
|
|
|
onPause={onPause}
|
|
|
|
onPlay={onPlay}
|
|
|
|
className="video-js vjs-fluid"
|
|
|
|
data-setup="{}"
|
|
|
|
/>
|
|
|
|
</div>
|
2022-02-27 15:04:12 +01:00
|
|
|
);
|
|
|
|
};
|