8 changed files with 197 additions and 13 deletions
@ -0,0 +1,47 @@ |
|||||||
|
import { useCallback, useRef } from "react"; |
||||||
|
import { useVideoPlayerState } from "../VideoContext"; |
||||||
|
|
||||||
|
export function ProgressControl() { |
||||||
|
const { videoState } = useVideoPlayerState(); |
||||||
|
const ref = useRef<HTMLDivElement>(null); |
||||||
|
|
||||||
|
const watchProgress = `${( |
||||||
|
(videoState.time / videoState.duration) * |
||||||
|
100 |
||||||
|
).toFixed(2)}%`;
|
||||||
|
const bufferProgress = `${( |
||||||
|
(videoState.buffered / videoState.duration) * |
||||||
|
100 |
||||||
|
).toFixed(2)}%`;
|
||||||
|
|
||||||
|
const handleClick = useCallback( |
||||||
|
(e: React.MouseEvent<HTMLElement>) => { |
||||||
|
if (!ref.current) return; |
||||||
|
const rect = ref.current.getBoundingClientRect(); |
||||||
|
const pos = (e.pageX - rect.left) / ref.current.offsetWidth; |
||||||
|
videoState.setTime(pos * videoState.duration); |
||||||
|
}, |
||||||
|
[videoState, ref] |
||||||
|
); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
ref={ref} |
||||||
|
className="relative m-1 my-4 h-4 w-48 overflow-hidden rounded-full border border-white bg-denim-100" |
||||||
|
onClick={handleClick} |
||||||
|
> |
||||||
|
<div |
||||||
|
className="absolute inset-y-0 left-0 bg-denim-700 opacity-50" |
||||||
|
style={{ |
||||||
|
width: bufferProgress, |
||||||
|
}} |
||||||
|
/> |
||||||
|
<div |
||||||
|
className="absolute inset-y-0 left-0 bg-denim-700" |
||||||
|
style={{ |
||||||
|
width: watchProgress, |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
import { useCallback, useRef } from "react"; |
||||||
|
import { useVideoPlayerState } from "../VideoContext"; |
||||||
|
|
||||||
|
export function VolumeControl() { |
||||||
|
const { videoState } = useVideoPlayerState(); |
||||||
|
const ref = useRef<HTMLDivElement>(null); |
||||||
|
|
||||||
|
const percentage = `${(videoState.volume * 100).toFixed(2)}%`; |
||||||
|
|
||||||
|
const handleClick = useCallback( |
||||||
|
(e: React.MouseEvent<HTMLElement>) => { |
||||||
|
if (!ref.current) return; |
||||||
|
const rect = ref.current.getBoundingClientRect(); |
||||||
|
const pos = (e.pageX - rect.left) / ref.current.offsetWidth; |
||||||
|
videoState.setVolume(pos); |
||||||
|
}, |
||||||
|
[videoState, ref] |
||||||
|
); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
ref={ref} |
||||||
|
className="relative m-1 my-4 h-4 w-48 overflow-hidden rounded-full border border-white bg-bink-300" |
||||||
|
onClick={handleClick} |
||||||
|
> |
||||||
|
<div |
||||||
|
className="absolute inset-y-0 left-0 bg-bink-700" |
||||||
|
style={{ |
||||||
|
width: percentage, |
||||||
|
}} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
export function handleBuffered(time: number, buffered: TimeRanges): number { |
||||||
|
for (let i = 0; i < buffered.length; i += 1) { |
||||||
|
if (buffered.start(buffered.length - 1 - i) < time) { |
||||||
|
return buffered.end(buffered.length - 1 - i); |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
Loading…
Reference in new issue