diff --git a/src/app/globals.css b/src/app/globals.css
index 4fb5dc9..e3c4f20 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -152,3 +152,22 @@ div[data-media-provider] video {
height: 100%;
object-fit: contain;
}
+
+/* Vidstack Menu 自定义样式:背景黑色,文字白色 */
+.vds-menu-items {
+ background-color: #000;
+ color: #fff;
+}
+
+.vds-menu-items .vds-radio {
+ padding: 0rem 1rem; /* 减少单项内边距 */
+ margin: 0; /* 清除默认外边距 */
+}
+
+.vds-menu-items .vds-radio + .vds-radio {
+ margin-top: 2px; /* 相邻项之间仅 2px 间隔 */
+}
+
+.vds-menu-items .vds-radio-label {
+ font-size: 0.875rem; /* 调小字号 */
+}
diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx
index a1140eb..683ae32 100644
--- a/src/app/play/page.tsx
+++ b/src/app/play/page.tsx
@@ -8,10 +8,13 @@ import {
isHLSProvider,
MediaPlayer,
MediaProvider,
+ Menu,
+ RadioGroup,
SeekButton,
} from '@vidstack/react';
import {
AirPlayIcon,
+ CheckIcon,
SeekBackward10Icon,
SeekForward10Icon,
} from '@vidstack/react/icons';
@@ -1433,7 +1436,10 @@ function PlayPageClient() {
>
-
+
{/* 自定义 AirPlay 按钮 */}
@@ -1787,8 +1793,10 @@ function PlayPageClient() {
const PlaybackRateButton = ({
playerRef,
+ playerContainerRef,
}: {
playerRef: React.RefObject;
+ playerContainerRef: React.RefObject;
}) => {
const [rate, setRate] = useState(1);
const rates = [0.75, 1.0, 1.25, 1.5, 2.0, 3.0];
@@ -1803,18 +1811,38 @@ const PlaybackRateButton = ({
return unsubscribe;
}, [playerRef]);
- const cycleRate = () => {
- const player = playerRef.current;
- if (!player) return;
- const currentIndex = rates.indexOf(rate);
- const nextIndex = (currentIndex + 1) % rates.length;
- player.playbackRate = rates[nextIndex];
- };
-
return (
-
+
+
+ 倍速
+
+
+ {
+ const player = playerRef.current;
+ if (!player) {
+ return;
+ }
+ player.playbackRate = Number(value);
+ playerContainerRef.current?.focus();
+ }}
+ >
+ {rates.reverse().map((rate) => (
+
+
+ {rate}
+
+ ))}
+
+
+
);
};