'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 { Switch } from '@/components/ui/Switch'; 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; videoTogetherEnabled?: boolean; onVideoTogetherEnabledChange?: (enabled: boolean) => 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, videoTogetherEnabled, onVideoTogetherEnabledChange, 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 ? (
内置代理端点
/api/proxy?url=<encoded-video-url>
此处不是第三方 HTTP/SOCKS 代理配置。播放器会按上方模式把播放地址交给当前 KVideo 部署的内置代理;该能力只在 Docker 或传统 Node.js 自托管完整模式下启用。
) : (
当前部署仅支持直连播放
{restrictionSummary}
内置代理端点为 /api/proxy,但当前部署模式已禁用该端点。
)}
{typeof videoTogetherEnabled === 'boolean' && onVideoTogetherEnabledChange ? ( <>

一起看 (VideoTogether)

关闭后不显示一起看悬浮入口;开启后仅在播放器和 IPTV 页面显示,且默认折叠为小图标,用户可自行展开。

) : null} {/* 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 }) => ( ))}
); }