3
0
mirror of https://github.com/Qortal/q-tube.git synced 2025-02-11 17:55:51 +00:00

Merge pull request #61 from QortalSeth/main

Videoplayer Updates:
This commit is contained in:
Qortal Dev 2025-01-03 16:06:35 -07:00 committed by GitHub
commit 7b9217eed2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 90 additions and 77 deletions

View File

@ -10,8 +10,7 @@ import {
ProgressSlider, ProgressSlider,
ReloadButton, ReloadButton,
VideoTime, VideoTime,
VolumeButton, VolumeControl,
VolumeSlider,
} from "./VideoControls.tsx"; } from "./VideoControls.tsx";
export const MobileControlsBar = () => { export const MobileControlsBar = () => {
@ -54,10 +53,6 @@ export const MobileControlsBar = () => {
}, },
}} }}
> >
<MenuItem>
<VolumeButton />
<VolumeSlider width={"100%"} />
</MenuItem>
<MenuItem> <MenuItem>
<ObjectFitButton /> <ObjectFitButton />
</MenuItem> </MenuItem>

View File

@ -1,4 +1,4 @@
import { IconButton, Slider, Typography } from "@mui/material"; import { Box, IconButton, Slider, Typography } from "@mui/material";
import { fontSizeExSmall, fontSizeSmall } from "../../../../constants/Misc.ts"; import { fontSizeExSmall, fontSizeSmall } from "../../../../constants/Misc.ts";
import { CustomFontTooltip } from "../../../../utils/CustomFontTooltip.tsx"; import { CustomFontTooltip } from "../../../../utils/CustomFontTooltip.tsx";
import { formatTime } from "../../../../utils/numberFunctions.ts"; import { formatTime } from "../../../../utils/numberFunctions.ts";
@ -18,7 +18,7 @@ import { useSignalEffect } from "@preact/signals-react";
export const PlayButton = () => { export const PlayButton = () => {
const { togglePlay, playing } = useVideoContext(); const { togglePlay, playing } = useVideoContext();
return ( return (
<CustomFontTooltip title="Pause/Play (Spacebar)" placement="top" arrow> <CustomFontTooltip title="Pause/Play (Spacebar)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
@ -34,7 +34,7 @@ export const PlayButton = () => {
export const ReloadButton = () => { export const ReloadButton = () => {
const { reloadVideo } = useVideoContext(); const { reloadVideo } = useVideoContext();
return ( return (
<CustomFontTooltip title="Reload Video (R)" placement="top" arrow> <CustomFontTooltip title="Reload Video (R)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
@ -57,7 +57,7 @@ export const ProgressSlider = () => {
max={videoRef.current?.duration || 100} max={videoRef.current?.duration || 100}
sx={{ sx={{
position: "absolute", position: "absolute",
bottom: "40px", bottom: "42px",
color: "#00abff", color: "#00abff",
padding: "0px", padding: "0px",
// prevents the slider from jumping up 20px in certain mobile conditions // prevents the slider from jumping up 20px in certain mobile conditions
@ -69,7 +69,8 @@ export const ProgressSlider = () => {
height: "16px", height: "16px",
}, },
"& .MuiSlider-thumb::after": { width: "20px", height: "20px" }, "& .MuiSlider-thumb::after": { width: "20px", height: "20px" },
"& .MuiSlider-rail": { opacity: 0.5 }, "& .MuiSlider-rail": { opacity: 0.5, height: "6px" },
"& .MuiSlider-track": { height: "6px", border: "0px" },
}} }}
/> />
); );
@ -81,7 +82,7 @@ export const VideoTime = () => {
return ( return (
<CustomFontTooltip <CustomFontTooltip
title="Seek video in 10% increments (0-9)" title="Seek video in 10% increments (0-9)"
placement="top" placement="bottom"
arrow arrow
> >
<Typography <Typography
@ -102,12 +103,12 @@ export const VideoTime = () => {
); );
}; };
export const VolumeButton = () => { const VolumeButton = () => {
const { isMuted, toggleMute } = useVideoContext(); const { isMuted, toggleMute } = useVideoContext();
return ( return (
<CustomFontTooltip <CustomFontTooltip
title="Toggle Mute (M), Raise (UP), Lower (DOWN)" title="Toggle Mute (M), Raise (UP), Lower (DOWN)"
placement="top" placement="bottom"
arrow arrow
> >
<IconButton <IconButton
@ -122,8 +123,13 @@ export const VolumeButton = () => {
); );
}; };
export const VolumeSlider = ({ width }: { width: string }) => { const VolumeSlider = ({ width }: { width: string }) => {
const { volume, onVolumeChange } = useVideoContext(); const { volume, onVolumeChange } = useVideoContext();
let color = "";
if (volume.value <= 0.5) color = "green";
else if (volume.value <= 0.75) color = "yellow";
else color = "red";
return ( return (
<Slider <Slider
value={volume.value} value={volume.value}
@ -134,18 +140,36 @@ export const VolumeSlider = ({ width }: { width: string }) => {
sx={{ sx={{
width, width,
marginRight: "10px", marginRight: "10px",
"& .MuiSlider-thumb::after": { width: "25px", height: "25px" }, color,
"& .MuiSlider-thumb": {
backgroundColor: "#fff",
width: "16px",
height: "16px",
},
"& .MuiSlider-thumb::after": { width: "16px", height: "16px" },
"& .MuiSlider-rail": { opacity: 0.5, height: "6px" },
"& .MuiSlider-track": { height: "6px", border: "0px" },
}} }}
/> />
); );
}; };
export const VolumeControl = ({ sliderWidth }: { sliderWidth: string }) => {
return (
<Box
sx={{ display: "flex", gap: "5px", alignItems: "center", width: "100%" }}
>
<VolumeButton />
<VolumeSlider width={sliderWidth} />
</Box>
);
};
export const PlaybackRate = () => { export const PlaybackRate = () => {
const { playbackRate, increaseSpeed, isScreenSmall } = useVideoContext(); const { playbackRate, increaseSpeed, isScreenSmall } = useVideoContext();
return ( return (
<CustomFontTooltip <CustomFontTooltip
title="Video Speed. Increase (+ or >), Decrease (- or <)" title="Video Speed. Increase (+ or >), Decrease (- or <)"
placement="top" placement="bottom"
arrow arrow
> >
<IconButton <IconButton
@ -170,7 +194,11 @@ export const PictureInPictureButton = () => {
return ( return (
<> <>
{!isFullscreen.value && ( {!isFullscreen.value && (
<CustomFontTooltip title="Picture in Picture (P)" placement="top" arrow> <CustomFontTooltip
title="Picture in Picture (P)"
placement="bottom"
arrow
>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
@ -189,7 +217,7 @@ export const PictureInPictureButton = () => {
export const ObjectFitButton = () => { export const ObjectFitButton = () => {
const { toggleObjectFit } = useVideoContext(); const { toggleObjectFit } = useVideoContext();
return ( return (
<CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="top" arrow> <CustomFontTooltip title="Toggle Aspect Ratio (O)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",
@ -206,7 +234,7 @@ export const ObjectFitButton = () => {
export const FullscreenButton = () => { export const FullscreenButton = () => {
const { toggleFullscreen } = useVideoContext(); const { toggleFullscreen } = useVideoContext();
return ( return (
<CustomFontTooltip title="Toggle Fullscreen (F)" placement="top" arrow> <CustomFontTooltip title="Toggle Fullscreen (F)" placement="bottom" arrow>
<IconButton <IconButton
sx={{ sx={{
color: "white", color: "white",

View File

@ -11,17 +11,15 @@ import {
ProgressSlider, ProgressSlider,
ReloadButton, ReloadButton,
VideoTime, VideoTime,
VolumeButton, VolumeControl,
VolumeSlider,
} from "./VideoControls.tsx"; } from "./VideoControls.tsx";
import { useSignalEffect } from "@preact/signals-react";
export const VideoControlsBar = () => { export const VideoControlsBar = () => {
const { from, canPlay, showControlsFullScreen, isScreenSmall, progress } = const { from, canPlay, showControlsFullScreen, isScreenSmall, progress } =
useVideoContext(); useVideoContext();
const showMobileControls = isScreenSmall && canPlay.value; const showMobileControls = isScreenSmall && canPlay.value;
const controlsHeight = "40px"; const controlsHeight = "42px";
const controlGroupSX = { const controlGroupSX = {
display: "flex", display: "flex",
gap: "5px", gap: "5px",
@ -46,8 +44,7 @@ export const VideoControlsBar = () => {
<ProgressSlider /> <ProgressSlider />
<VolumeButton /> <VolumeControl sliderWidth={"100px"} />
<VolumeSlider width={"100px"} />
<VideoTime /> <VideoTime />
</Box> </Box>

View File

@ -147,11 +147,6 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
if (!videoRef.current) return; if (!videoRef.current) return;
videoRef.current.currentTime = value as number; videoRef.current.currentTime = value as number;
progress.value = value as number; progress.value = value as number;
if (!playing.value) {
await videoRef.current.play();
playing.value = true;
}
}; };
const handleEnded = () => { const handleEnded = () => {
@ -198,9 +193,7 @@ export const useVideoPlayerState = (props: VideoPlayerProps, ref: any) => {
const target = event?.target; const target = event?.target;
if (target) { if (target) {
target.pause(); target.pause();
if (playing.value) { if (playing.value) playing.value = false;
playing.value = false;
}
} }
}; };

View File

@ -445,21 +445,21 @@ export const VideoPlayerGlobal: React.FC<VideoPlayerProps> = ({
} }
}; };
useEffect(() => { // useEffect(() => {
if (element) { // if (element) {
const oldElement = document.getElementById("videoPlayer"); // const oldElement = document.getElementById("videoPlayer");
if (oldElement && oldElement?.parentNode) { // if (oldElement && oldElement?.parentNode) {
oldElement?.parentNode.replaceChild(element, oldElement); // oldElement?.parentNode.replaceChild(element, oldElement);
videoRef.current = element; // videoRef.current = element;
setPlaying(true); // setPlaying(true);
setCanPlay(true); // setCanPlay(true);
setStartPlay(true); // setStartPlay(true);
//videoRef?.current?.addEventListener("click", () => {}); // //videoRef?.current?.addEventListener("click", () => {});
videoRef?.current?.addEventListener("timeupdate", updateProgress); // videoRef?.current?.addEventListener("timeupdate", updateProgress);
videoRef?.current?.addEventListener("ended", handleEnded); // videoRef?.current?.addEventListener("ended", handleEnded);
} // }
} // }
}, [element]); // }, [element]);
return ( return (
<VideoContainer <VideoContainer
@ -483,9 +483,9 @@ export const VideoPlayerGlobal: React.FC<VideoPlayerProps> = ({
}} }}
></CloseIcon> ></CloseIcon>
</div> </div>
<div onClick={togglePlay}> {/*<div onClick={togglePlay}>*/}
<VideoElement id="videoPlayer" /> {/* <VideoElement id="videoPlayer" />*/}
</div> {/*</div>*/}
<ControlsContainer <ControlsContainer
style={{ style={{
bottom: from === "create" ? "15px" : 0, bottom: from === "create" ? "15px" : 0,

View File

@ -121,7 +121,7 @@ export const VideoContent = () => {
color="textPrimary" color="textPrimary"
sx={{ sx={{
textAlign: "start", textAlign: "start",
marginTop: "10px", marginTop: isScreenSmall ? "20px" : "10px",
}} }}
> >
{videoData?.title} {videoData?.title}

View File

@ -228,30 +228,30 @@ const GlobalWrapper: React.FC<Props> = ({ children, setTheme }) => {
/> />
<EditVideo /> <EditVideo />
<EditPlaylist /> <EditPlaylist />
<Rnd {/*<Rnd*/}
onDragStart={onDragStart} {/* onDragStart={onDragStart}*/}
onDragStop={onDragStop} {/* onDragStop={onDragStop}*/}
style={{ {/* style={{*/}
display: videoPlaying ? "block" : "none", {/* display: videoPlaying ? "block" : "none",*/}
position: "fixed", {/* position: "fixed",*/}
height: "auto", {/* height: "auto",*/}
width: 350, {/* width: 350,*/}
zIndex: 1000, {/* zIndex: 1000,*/}
maxWidth: 800, {/* maxWidth: 800,*/}
}} {/* }}*/}
default={{ {/* default={{*/}
x: 0, {/* x: 0,*/}
y: 60, {/* y: 60,*/}
width: 350, {/* width: 350,*/}
height: "auto", {/* height: "auto",*/}
}} {/* }}*/}
// eslint-disable-next-line @typescript-eslint/no-empty-function {/* // eslint-disable-next-line @typescript-eslint/no-empty-function*/}
onDrag={() => {}} {/* onDrag={() => {}}*/}
> {/*>*/}
{videoPlaying && ( {/* {videoPlaying && (*/}
<VideoPlayerGlobal checkIfDrag={checkIfDrag} element={videoPlaying} /> {/* <VideoPlayerGlobal checkIfDrag={checkIfDrag} element={videoPlaying} />*/}
)} {/* )}*/}
</Rnd> {/*</Rnd>*/}
{children} {children}
</> </>