'use client'; /** * PlayerSettings - Global settings for the video player * Following Liquid Glass design system */ import { Icons } from '@/components/ui/Icon'; import { useRuntimeFeatures } from '@/components/RuntimeFeaturesProvider'; import { type ProxyMode, DEFAULT_SEEK_STEP_SECONDS, MIN_SEEK_STEP_SECONDS, MAX_SEEK_STEP_SECONDS, } from '@/lib/store/settings-store'; interface PlayerSettingsProps { fullscreenType: 'auto' | 'native' | 'window'; onFullscreenTypeChange: (type: 'auto' | 'native' | 'window') => void; proxyMode: ProxyMode; onProxyModeChange: (mode: ProxyMode) => void; seekStepSeconds: number; onSeekStepSecondsChange: (value: number) => void; danmakuApiUrl: string; onDanmakuApiUrlChange: (url: string) => void; danmakuOpacity: number; onDanmakuOpacityChange: (value: number) => void; danmakuFontSize: number; onDanmakuFontSizeChange: (value: number) => void; danmakuDisplayArea: number; onDanmakuDisplayAreaChange: (value: number) => void; showDanmakuApi?: boolean; } const DANMAKU_FONT_SIZES = [14, 18, 20, 24, 28]; const DANMAKU_DISPLAY_AREAS = [ { value: 0.25, label: '1/4屏' }, { value: 0.5, label: '半屏' }, { value: 0.75, label: '3/4屏' }, { value: 1.0, label: '全屏' }, ]; const SEEK_STEP_PRESETS = [5, 10, 15, 30, 60]; export function PlayerSettings({ fullscreenType, onFullscreenTypeChange, proxyMode, onProxyModeChange, seekStepSeconds, onSeekStepSecondsChange, danmakuApiUrl, onDanmakuApiUrlChange, danmakuOpacity, onDanmakuOpacityChange, danmakuFontSize, onDanmakuFontSizeChange, danmakuDisplayArea, onDanmakuDisplayAreaChange, showDanmakuApi = true, }: PlayerSettingsProps) { const { mediaProxyEnabled, restrictionSummary } = useRuntimeFeatures(); const effectiveProxyMode = mediaProxyEnabled ? proxyMode : 'none'; return (

播放器设置

{/* Fullscreen Mode Selection */}

默认全屏方式

选择在桌面端点击播放器全屏按钮时的行为

快进 / 快退间隔

控制键盘 J / L、方向键和双击手势每次跳转的秒数

{SEEK_STEP_PRESETS.map((seconds) => ( ))}
{ if (e.target.value === '') return; const nextValue = Number(e.target.value); if (Number.isNaN(nextValue)) return; onSeekStepSecondsChange(nextValue); }} className="w-full px-4 py-2.5 bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] text-[var(--text-color)] placeholder:text-[var(--text-color-secondary)]/50 focus:outline-none focus:border-[var(--accent-color)] transition-colors text-sm" />

范围 {MIN_SEEK_STEP_SECONDS}-{MAX_SEEK_STEP_SECONDS} 秒,默认 {DEFAULT_SEEK_STEP_SECONDS} 秒

{/* Proxy Mode Selection */}

代理播放模式

控制视频播放时的网络请求策略

{mediaProxyEnabled ? (
) : (
当前部署仅支持直连播放
{restrictionSummary}
)}
{/* Danmaku Settings */}

弹幕设置

配置弹幕聚合 API 地址,在播放器菜单中开关弹幕

{/* API URL */}
{showDanmakuApi && (
onDanmakuApiUrlChange(e.target.value)} className="w-full px-4 py-2.5 bg-[var(--glass-bg)] border border-[var(--glass-border)] rounded-[var(--radius-2xl)] text-[var(--text-color)] placeholder:text-[var(--text-color-secondary)]/50 focus:outline-none focus:border-[var(--accent-color)] transition-colors text-sm" />

兼容 danmu_api 格式的弹幕聚合服务

)} {/* Opacity */}
onDanmakuOpacityChange(parseInt(e.target.value) / 100)} className="w-full accent-[var(--accent-color)] h-2" />
{/* Font Size */}
{DANMAKU_FONT_SIZES.map((size) => ( ))}
{/* Display Area */}
{DANMAKU_DISPLAY_AREAS.map(({ value, label }) => ( ))}
); }