improvement: migrated to videojs

This commit is contained in:
JohnMark Sill 2022-06-02 16:05:56 -05:00 committed by Blake Blackshear
parent 37011c2fda
commit 17b745434c

View File

@ -3,6 +3,12 @@ import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
import { useApiHost } from '../../api'; import { useApiHost } from '../../api';
import { isNullOrUndefined } from '../../utils/objectUtils'; import { isNullOrUndefined } from '../../utils/objectUtils';
import 'videojs-seek-buttons';
import 'video.js/dist/video-js.css';
import 'videojs-seek-buttons/dist/videojs-seek-buttons.css';
import videojs from 'video.js';
interface OnTimeUpdateEvent { interface OnTimeUpdateEvent {
timestamp: number; timestamp: number;
isPlaying: boolean; isPlaying: boolean;
@ -31,75 +37,45 @@ export const HistoryVideo = ({
onPlay, onPlay,
}: HistoryVideoProps) => { }: HistoryVideoProps) => {
const apiHost = useApiHost(); const apiHost = useApiHost();
const videoRef = useRef<HTMLVideoElement | null>(null); const videoRef = useRef<HTMLVideoElement>();
const [posterLoaded, setPosterLoaded] = useState(false);
const [videoHeight, setVideoHeight] = useState<number | undefined>(undefined);
const [videoProperties, setVideoProperties] = useState<VideoProperties>({ const [videoProperties, setVideoProperties] = useState<VideoProperties>({
posterUrl: '', posterUrl: '',
videoUrl: '', videoUrl: '',
}); });
const videoCallback = useCallback(
(domNode: any) => {
videoRef.current = domNode;
if (posterLoaded) {
setVideoHeight(videoRef.current?.offsetHeight);
}
},
[posterLoaded]
);
useEffect(() => { useEffect(() => {
const idExists = !isNullOrUndefined(id); let video: any;
if (idExists) { if (videoRef.current && id) {
if (videoRef.current && !videoRef.current.paused) { video = videojs(videoRef.current, {});
videoRef.current = null;
}
const posterUrl = `${apiHost}/api/events/${id}/snapshot.jpg`;
const poster = new Image();
poster.src = posterUrl;
poster.onload = () => {
setPosterLoaded(true);
};
setVideoProperties({
posterUrl,
videoUrl: `${apiHost}/vod/event/${id}/index.m3u8`,
});
} else {
setVideoProperties({
posterUrl: '',
videoUrl: '',
});
} }
}, [id, videoHeight, videoRef, apiHost]); }, [videoRef]);
useEffect(() => { useEffect(() => {
const playVideo = (video: HTMLMediaElement) => video.play(); if (!id) {
return;
}
const video = videojs(videoRef.current);
video.src({
src: `${apiHost}/vod/event/${id}/index.m3u8`,
type: 'application/vnd.apple.mpegurl',
});
video.poster(`${apiHost}/api/events/${id}/snapshot.jpg`);
if (videoIsPlaying) {
video.play();
}
}, [id]);
const attemptPlayVideo = (video: HTMLMediaElement) => { useEffect(() => {
const videoHasNotLoaded = video.readyState <= 1; if (!videoRef) {
if (videoHasNotLoaded) { return;
video.oncanplay = () => { }
playVideo(video);
};
video.load();
} else {
playVideo(video);
}
};
const video = videoRef.current; const video = videojs(videoRef.current);
const videoExists = !isNullOrUndefined(video); if (video.paused() && videoIsPlaying) {
if (video && videoExists) { video.play();
if (videoIsPlaying) { } else if (!video.paused() && !videoIsPlaying) {
attemptPlayVideo(video); video.pause();
} else {
video.pause();
}
} }
}, [videoIsPlaying, videoRef]); }, [videoIsPlaying, videoRef]);
@ -119,7 +95,6 @@ export const HistoryVideo = ({
isPlaying: videoIsPlaying, isPlaying: videoIsPlaying,
timestamp: target.currentTime, timestamp: target.currentTime,
}; };
onTimeUpdate && onTimeUpdate(timeUpdateEvent); onTimeUpdate && onTimeUpdate(timeUpdateEvent);
}, },
[videoIsPlaying, onTimeUpdate] [videoIsPlaying, onTimeUpdate]
@ -127,19 +102,17 @@ export const HistoryVideo = ({
const { posterUrl, videoUrl } = videoProperties; const { posterUrl, videoUrl } = videoProperties;
return ( return (
<video <div data-vjs-player>
ref={videoCallback} <video
key={posterUrl} ref={videoRef}
onTimeUpdate={onTimeUpdateHandler} onTimeUpdate={onTimeUpdateHandler}
onPause={onPause} onPause={onPause}
onPlay={onPlay} onPlay={onPlay}
poster={posterUrl} poster={posterUrl}
preload="metadata" src={videoUrl}
controls className="video-js vjs-fluid"
style={videoHeight ? { minHeight: `${videoHeight}px` } : {}} data-setup="{}"
playsInline />
> </div>
<source type="application/vnd.apple.mpegurl" src={videoUrl} />
</video>
); );
}; };