mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
improvement: migrated to videojs
This commit is contained in:
parent
37011c2fda
commit
17b745434c
@ -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>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user