import { h } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import { useApiHost } from '../../api'; interface OnTimeUpdateEvent { timestamp: number; isPlaying: boolean; } interface VideoProperties { posterUrl: string; videoUrl: string; height: number; } interface HistoryVideoProps { id: string; isPlaying: boolean; currentTime: number; onTimeUpdate: (event: OnTimeUpdateEvent) => void; onPause: () => void; onPlay: () => void; } const isNullOrUndefined = (object: any): boolean => object === null || object === undefined; export const HistoryVideo = ({ id, isPlaying: videoIsPlaying, currentTime, onTimeUpdate, onPause, onPlay, }: HistoryVideoProps) => { const apiHost = useApiHost(); const videoRef = useRef(); const [videoHeight, setVideoHeight] = useState(undefined); const [videoProperties, setVideoProperties] = useState(undefined); const initializeVideoContainerHeight = useCallback(() => { const video = videoRef.current; const videoExists = !isNullOrUndefined(video); if (videoExists) { const videoHeight = video.offsetHeight; const videoHasHeight = videoHeight > 0; if (videoHasHeight) { setVideoHeight(videoHeight); } } }, [videoRef.current]); useEffect(() => { initializeVideoContainerHeight(); }, [initializeVideoContainerHeight]); useEffect(() => { const idExists = !isNullOrUndefined(id); if (idExists) { setVideoProperties({ posterUrl: `${apiHost}/api/events/${id}/snapshot.jpg`, videoUrl: `${apiHost}/vod/event/${id}/index.m3u8`, height: videoHeight, }); } else { setVideoProperties(undefined); } }, [id, videoHeight]); useEffect(() => { const playVideo = (video: HTMLMediaElement) => { console.debug('playVideo: attempt playback'); video .play() .then(() => { console.debug('playVideo: video started'); }) .catch((e) => { console.error('Fail', { e }); }); }; const attemptPlayVideo = (video: HTMLMediaElement) => { const videoHasNotLoaded = video.readyState <= 1; console.debug('playVideo', { videoHasNotLoaded }); if (videoHasNotLoaded) { console.debug('playVideo: attempt to load video'); video.oncanplay = () => { console.debug('onLoad: video loaded'); playVideo(video); }; video.load(); } else { playVideo(video); } }; const video = videoRef.current; const videoExists = !isNullOrUndefined(video); if (videoExists) { console.log('check should start', { videoIsPlaying }); if (videoIsPlaying) { attemptPlayVideo(video); } else { video.pause(); } } }, [videoIsPlaying, videoRef]); useEffect(() => { const video = videoRef.current; const videoExists = !isNullOrUndefined(video); const hasSeeked = currentTime >= 0; if (videoExists && hasSeeked) { video.currentTime = currentTime; } }, [currentTime, videoRef]); const onTimeUpdateHandler = useCallback( (event: Event) => { const target = event.target as HTMLMediaElement; const timeUpdateEvent = { isPlaying: videoIsPlaying, timestamp: target.currentTime, }; onTimeUpdate(timeUpdateEvent); }, [videoIsPlaying] ); const videoPropertiesIsUndefined = isNullOrUndefined(videoProperties); if (videoPropertiesIsUndefined) { return
; } const { posterUrl, videoUrl, height } = videoProperties; return ( ); };