feat: seek bar on recordings

This commit is contained in:
Kieran 2023-12-05 11:39:03 +00:00
parent aaf832a9af
commit 6905fb63fd
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
2 changed files with 61 additions and 7 deletions

View File

@ -93,5 +93,15 @@
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.1732 7.17981C15.6262 6.86385 16.2495 6.97492 16.5655 7.4279C17.4696 8.7241 18 10.3016 18 12C18 13.6984 17.4696 15.2759 16.5655 16.5721C16.2495 17.0251 15.6262 17.1361 15.1732 16.8202C14.7202 16.5042 14.6092 15.8809 14.9251 15.4279C15.6027 14.4564 16 13.2761 16 12C16 10.7239 15.6027 9.54355 14.9251 8.57209C14.6092 8.11912 14.7202 7.49577 15.1732 7.17981Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.3823 2.71172C10.861 2.67405 11.3288 2.86781 11.6406 3.23293C11.9199 3.55988 11.9642 3.95313 11.9811 4.14402C12.0001 4.35799 12 4.62375 12 4.89413C12 4.90653 12 4.91895 12 4.93136L12 19.1059C12 19.3762 12.0001 19.642 11.9811 19.856C11.9642 20.0469 11.9199 20.4401 11.6406 20.7671C11.3288 21.1322 10.861 21.3259 10.3823 21.2883C9.95368 21.2545 9.64424 21.0078 9.4973 20.8848C9.33259 20.7469 9.14469 20.559 8.95353 20.3677L5.76153 17.1757C5.6689 17.0831 5.6225 17.037 5.58738 17.005L5.58472 17.0026L5.58114 17.0024C5.53365 17.0002 5.46826 17 5.33726 17L3.56812 17C3.31574 17 3.06994 17.0001 2.86178 16.983C2.63318 16.9644 2.36345 16.9203 2.09202 16.782C1.7157 16.5903 1.40974 16.2843 1.21799 15.908C1.07969 15.6366 1.03563 15.3668 1.01695 15.1382C0.999943 14.9301 0.999973 14.6843 1 14.4319L1.00001 9.59999C1.00001 9.58935 1 9.57872 1 9.5681C0.999973 9.31571 0.999943 9.06992 1.01695 8.86176C1.03563 8.63317 1.07969 8.36344 1.21799 8.09201C1.40974 7.71569 1.7157 7.40973 2.09202 7.21798C2.36345 7.07968 2.63318 7.03562 2.86178 7.01694C3.06993 6.99993 3.31572 6.99996 3.56811 6.99999C3.57873 6.99999 3.58936 6.99999 3.60001 6.99999H5.33726C5.46826 6.99999 5.53365 6.99976 5.58114 6.99758L5.58472 6.99741L5.58738 6.995C5.6225 6.96295 5.6689 6.91689 5.76153 6.82426L8.92721 3.65857C8.936 3.64979 8.94477 3.64101 8.95354 3.63224C9.1447 3.44102 9.33259 3.25308 9.4973 3.11518C9.64424 2.99217 9.95368 2.74546 10.3823 2.71172Z" fill="currentColor"/>
</symbol>
<symbol id="loading" viewBox="0 0 24 24" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 1.25C12.5523 1.25 13 1.69772 13 2.25V4.75C13 5.30228 12.5523 5.75 12 5.75C11.4477 5.75 11 5.30228 11 4.75V2.25C11 1.69772 11.4477 1.25 12 1.25Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 17C12.5523 17 13 17.4477 13 18V22C13 22.5523 12.5523 23 12 23C11.4477 23 11 22.5523 11 22V18C11 17.4477 11.4477 17 12 17Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.25 12C1.25 11.4477 1.69772 11 2.25 11H5.75C6.30228 11 6.75 11.4477 6.75 12C6.75 12.5523 6.30228 13 5.75 13H2.25C1.69772 13 1.25 12.5523 1.25 12Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.75 12C18.75 11.4477 19.1977 11 19.75 11H21.25C21.8023 11 22.25 11.4477 22.25 12C22.25 12.5523 21.8023 13 21.25 13H19.75C19.1977 13 18.75 12.5523 18.75 12Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.0429 17.0429C17.4334 16.6524 18.0666 16.6524 18.4571 17.0429L19.1642 17.75C19.5547 18.1405 19.5547 18.7737 19.1642 19.1642C18.7737 19.5547 18.1405 19.5547 17.75 19.1642L17.0429 18.4571C16.6524 18.0666 16.6524 17.4334 17.0429 17.0429Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.3713 4.70868C19.7618 5.0992 19.7618 5.73237 19.3713 6.12289L17.9571 7.53711C17.5666 7.92763 16.9334 7.92763 16.5429 7.53711C16.1524 7.14658 16.1524 6.51342 16.5429 6.12289L17.9571 4.70868C18.3476 4.31816 18.9808 4.31816 19.3713 4.70868Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.45711 15.5429C8.84763 15.9334 8.84763 16.5666 8.45711 16.9571L5.62868 19.7855C5.23815 20.1761 4.60499 20.1761 4.21447 19.7855C3.82394 19.395 3.82394 18.7618 4.21447 18.3713L7.04289 15.5429C7.43342 15.1524 8.06658 15.1524 8.45711 15.5429Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.42157 4.50157C4.8121 4.11105 5.44526 4.11105 5.83579 4.50157L7.95711 6.62289C8.34763 7.01342 8.34763 7.64658 7.95711 8.03711C7.56658 8.42763 6.93342 8.42763 6.54289 8.03711L4.42157 5.91579C4.03105 5.52526 4.03105 4.8921 4.42157 4.50157Z" fill="currentColor"/>
</symbol>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -25,8 +25,10 @@ export function LiveVideoPlayer(props: VideoPlayerProps) {
const [src, setSrc] = useState<string>();
const [levels, setLevels] = useState<Array<{ level: number; height: number }>>();
const [level, setLevel] = useState<number>(-1);
const [playState, setPlayState] = useState(true);
const [playState, setPlayState] = useState<"loading" | "playing" | "paused">("loading");
const [volume, setVolume] = useState(1);
const [position, setPosition] = useState<number>();
const [maxPosition, setMaxPosition] = useState<number>();
useEffect(() => {
if (streamCached && video.current) {
@ -59,6 +61,7 @@ export function LiveVideoPlayer(props: VideoPlayerProps) {
});
hls.on(Hls.Events.LEVEL_SWITCHING, (_, l) => {
console.debug("HLS Level Switch", l);
setMaxPosition(l.details?.totalduration);
});
// @ts-ignore Can write anyway
hlsObj.current = hls;
@ -88,9 +91,12 @@ export function LiveVideoPlayer(props: VideoPlayerProps) {
useEffect(() => {
if (video.current) {
video.current.onplaying = () => setPlayState(true);
video.current.onpause = () => setPlayState(false);
video.current.onplaying = () => setPlayState("playing");
video.current.onpause = () => setPlayState("paused");
video.current.onseeking = () => setPlayState("loading");
video.current.onplay = () => setPlayState("loading");
video.current.onvolumechange = () => setVolume(video.current?.volume ?? 1);
video.current.ontimeupdate = () => setPosition(video.current?.currentTime);
}
}, [video]);
@ -110,6 +116,31 @@ export function LiveVideoPlayer(props: VideoPlayerProps) {
}
}
function seek(e: React.MouseEvent) {
if (e.currentTarget === e.target) {
const bb = (e.target as HTMLDivElement).getBoundingClientRect();
const x = e.clientX - bb.x;
const pos = Math.max(0, Math.min(1.0, x / bb.width));
if (video.current && maxPosition) {
const ct = maxPosition * pos;
video.current.currentTime = ct;
setPosition(ct);
}
}
}
function playStateToIcon() {
switch (playState) {
case "playing":
return "pause";
case "paused":
return "play";
case "loading":
return "loading";
}
}
return (
<div className="relative">
{status === VideoStatus.Online && (
@ -117,19 +148,32 @@ export function LiveVideoPlayer(props: VideoPlayerProps) {
className="absolute opacity-0 hover:opacity-100 transition-opacity w-full h-full z-20 bg-[#00000055]"
onClick={() => {
if (video.current) {
if (playState) {
if (playState === "playing") {
video.current.pause();
} else {
} else if (playState === "paused") {
video.current.play();
}
}
}}>
<div className="absolute w-full h-full flex items-center justify-center pointer">
<Icon name={playState ? "pause" : "play"} size={80} />
<Icon
name={playStateToIcon()}
size={80}
className={playState === "loading" ? "animate-spin" : "animate-ping-once"}
/>
</div>
<div className="absolute flex gap-1 bottom-0 w-full bg-[rgba(0,0,0,0.5)]" onClick={e => e.stopPropagation()}>
<div className="grow">
<div className="flex grow gap-1">
<StatePill state={props.status as StreamState} />
{props.status === StreamState.Ended && playState && maxPosition && position && (
<div className="relative w-full h-full border" onClick={seek}>
<div
className="absolute h-full w-[4px] bg-white"
style={{
width: `${((position / maxPosition) * 100).toFixed(1)}%`,
}}></div>
</div>
)}
</div>
<div className="flex gap-1 items-center">
<Icon name="volume" />