From e0606d0b8be34c6c02a2464609f33924ee9b654a Mon Sep 17 00:00:00 2001 From: mtvpls Date: Mon, 9 Feb 2026 02:16:09 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8DOpenList=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E6=9C=AA=E5=90=AF=E7=94=A8=E6=97=B6=E4=BB=8D=E8=B5=B0?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在replaceAudioUrlsWithOpenList函数中添加OpenListCacheEnabled检查, 确保只有在启用OpenList缓存时才会执行代理逻辑。 --- src/app/api/music/route.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/api/music/route.ts b/src/app/api/music/route.ts index 70634c6..588f3f6 100644 --- a/src/app/api/music/route.ts +++ b/src/app/api/music/route.ts @@ -125,14 +125,16 @@ async function replaceAudioUrlsWithOpenList( quality: string, cachePath: string ): Promise { - if (!openListClient || !data?.data) { + // 获取配置,检查是否启用 OpenList 缓存 + const config = await getConfig(); + const cacheEnabled = config?.MusicConfig?.OpenListCacheEnabled ?? false; + const cacheProxyEnabled = config?.MusicConfig?.OpenListCacheProxyEnabled ?? true; + + // 如果没有启用 OpenList 缓存,直接返回原数据 + if (!cacheEnabled || !openListClient || !data?.data) { return data; } - // 获取配置,检查是否启用缓存代理 - const config = await getConfig(); - const cacheProxyEnabled = config?.MusicConfig?.OpenListCacheProxyEnabled ?? true; - // TuneHub 返回的数据结构是 { code: 0, data: { data: [...], total: 1 } } // 需要提取内层的 data 数组 const songsData = data.data.data || data.data; From 22b9242e3973497a6200efb4170c9a86da5fb5f3 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Tue, 10 Feb 2026 20:10:17 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dpostgres=E5=AF=BC?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/admin/data_migration/import/route.ts | 22 +++++++++++++++++++ src/app/music/page.tsx | 7 ++++++ 2 files changed, 29 insertions(+) diff --git a/src/app/api/admin/data_migration/import/route.ts b/src/app/api/admin/data_migration/import/route.ts index 96b33d0..c8c6c1d 100644 --- a/src/app/api/admin/data_migration/import/route.ts +++ b/src/app/api/admin/data_migration/import/route.ts @@ -151,6 +151,28 @@ export async function POST(req: NextRequest) { } catch (err) { console.error(`导入用户 ${username} 失败:`, err); } + } else if (storageType === 'postgres') { + // Postgres 存储:使用 createUserWithHashedPassword 方法 + try { + if (typeof storage.createUserWithHashedPassword === 'function') { + await storage.createUserWithHashedPassword( + username, + user.passwordV2, // 已经是hash过的密码 + role, + createdAt, + userV2?.tags, + userV2?.oidcSub, + userV2?.enabledApis, + userV2?.banned + ); + importedCount++; + console.log(`用户 ${username} 导入成功 (Postgres)`); + } else { + console.error(`Postgres storage 缺少 createUserWithHashedPassword 方法`); + } + } catch (err) { + console.error(`导入用户 ${username} 失败:`, err); + } } else { // Redis 存储:直接设置用户信息 const userInfoKey = `user:${username}:info`; diff --git a/src/app/music/page.tsx b/src/app/music/page.tsx index 60d0e52..14cc9ac 100644 --- a/src/app/music/page.tsx +++ b/src/app/music/page.tsx @@ -359,6 +359,13 @@ export default function MusicPage() { } }, [playRecords, pendingSongToPlay]); + // 同步音量状态到 audio 元素 + useEffect(() => { + if (audioRef.current) { + audioRef.current.volume = volume / 100; + } + }, [volume]); + // 执行前端 transform(用于 Cloudflare 环境) const executeTransform = (data: any) => { if (data && typeof data === 'object' && data.__transform) { From 84c5d7a9f0256b012030f0d92a63ab376a642cdc Mon Sep 17 00:00:00 2001 From: mtvpls Date: Wed, 11 Feb 2026 00:51:06 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dpostgrep=E7=9A=84?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/admin/data_migration/export/route.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/app/api/admin/data_migration/export/route.ts b/src/app/api/admin/data_migration/export/route.ts index c28fd56..0f023e4 100644 --- a/src/app/api/admin/data_migration/export/route.ts +++ b/src/app/api/admin/data_migration/export/route.ts @@ -170,6 +170,14 @@ async function getUserPasswordV2(username: string): Promise { // 检查存储类型 const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; + // PostgreSQL 存储:使用 getUserPasswordHash 方法 + if (storageType === 'postgres') { + if (typeof storage.getUserPasswordHash === 'function') { + return await storage.getUserPasswordHash(username); + } + return null; + } + // D1 存储:使用 getUserPasswordHash 方法 if (storageType === 'd1') { if (typeof storage.getUserPasswordHash === 'function') { From 7d004ee973803b421f595e6127c2588368f2ab4a Mon Sep 17 00:00:00 2001 From: mtvpls Date: Wed, 11 Feb 2026 16:01:58 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9D=9Ed1=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cloudflare-deploy.yml | 23 ++++++++++++++++++++--- README.md | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cloudflare-deploy.yml b/.github/workflows/cloudflare-deploy.yml index c855243..66987b0 100644 --- a/.github/workflows/cloudflare-deploy.yml +++ b/.github/workflows/cloudflare-deploy.yml @@ -67,13 +67,23 @@ jobs: echo "INIT_CONFIG=${{ secrets.INIT_CONFIG }}" >> $GITHUB_ENV echo "CONFIG_SUBSCRIPTION_URL=${{ secrets.CONFIG_SUBSCRIPTION_URL }}" >> $GITHUB_ENV - - name: Replace D1 Database ID in wrangler.toml + - name: Configure D1 Database in wrangler.toml run: | - if [ -n "${{ secrets.D1_DATABASE_ID }}" ]; then + STORAGE_TYPE="${{ secrets.NEXT_PUBLIC_STORAGE_TYPE }}" + + if [ "$STORAGE_TYPE" != "d1" ]; then + echo "Storage type is not d1 (current: $STORAGE_TYPE), removing D1 database configuration" + # Remove the entire [[d1_databases]] section including the comment + sed -i '/^# D1 数据库绑定$/,/^database_id = .*$/d' wrangler.toml + # Also remove any remaining [[d1_databases]] block + sed -i '/^\[\[d1_databases\]\]$/,/^$/{ /^\[\[d1_databases\]\]$/d; /^binding = /d; /^database_name = /d; /^database_id = /d; }' wrangler.toml + echo "D1 configuration removed from wrangler.toml" + elif [ -n "${{ secrets.D1_DATABASE_ID }}" ]; then sed -i 's/REPLACE_WITH_YOUR_D1_DATABASE_ID/${{ secrets.D1_DATABASE_ID }}/g' wrangler.toml echo "D1 Database ID replaced successfully" else - echo "D1_DATABASE_ID secret not set, skipping replacement" + echo "⚠️ Storage type is d1 but D1_DATABASE_ID secret not set" + exit 1 fi - name: Update wrangler.toml with environment variables @@ -130,6 +140,13 @@ jobs: - name: Run D1 Database Migrations run: | + STORAGE_TYPE="${{ secrets.NEXT_PUBLIC_STORAGE_TYPE }}" + + if [ "$STORAGE_TYPE" != "d1" ]; then + echo "Storage type is not d1 (current: $STORAGE_TYPE), skipping D1 migrations" + exit 0 + fi + if [ -z "${{ secrets.D1_DATABASE_ID }}" ]; then echo "D1_DATABASE_ID not set, skipping migrations" exit 0 diff --git a/README.md b/README.md index 2d29123..caf9b76 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ Cloudflare Workers 提供免费的边缘计算服务,通过 GitHub Actions 可 - 点击 "Create Token",选择 "Edit Cloudflare Workers" 模板 - 或使用自定义 Token,需要以下权限: - Account - Cloudflare Workers Scripts - Edit - - Account - Cloudflare Workers KV Storage - Edit + - Account - D1 - Edit(仅在使用 D1 数据库时需要) - 创建后复制生成的 API Token - 在 Dashboard 首页右侧可以看到你的 Account ID From f0cedc1651219a0e2320cbf8114160c6dcb3c547 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Wed, 11 Feb 2026 16:44:43 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dopenlist=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E5=8C=85=E5=90=AB=E6=96=87=E4=BB=B6=E6=97=B6=E6=89=AB?= =?UTF-8?q?=E6=8F=8F=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/admin/openlist/route.ts | 9 ++++++++- src/lib/openlist-refresh.ts | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/app/api/admin/openlist/route.ts b/src/app/api/admin/openlist/route.ts index 0728b23..b70afe5 100644 --- a/src/app/api/admin/openlist/route.ts +++ b/src/app/api/admin/openlist/route.ts @@ -14,11 +14,18 @@ export const runtime = 'nodejs'; */ function cleanPath(path: string): string { // 移除 UTF-8 BOM (U+FEFF) 和其他零宽度字符 - return path + let cleaned = path .replace(/^\uFEFF/, '') // 移除开头的 BOM .replace(/\uFEFF/g, '') // 移除所有 BOM .replace(/[\u200B-\u200D\uFEFF]/g, '') // 移除零宽度字符 .trim(); // 移除首尾空白 + + // 移除末尾的 /(除非路径就是 /) + if (cleaned.length > 1 && cleaned.endsWith('/')) { + cleaned = cleaned.slice(0, -1); + } + + return cleaned; } /** diff --git a/src/lib/openlist-refresh.ts b/src/lib/openlist-refresh.ts index 48b3f14..816cfdb 100644 --- a/src/lib/openlist-refresh.ts +++ b/src/lib/openlist-refresh.ts @@ -254,7 +254,8 @@ async function performScan( const pageFolders = listResponse.data.content.filter((item) => item.is_dir); folders.push(...pageFolders); - if (folders.length >= total) { + // 判断是否还有更多数据:当前页为 null 或数据量小于 pageSize 说明已经是最后一页 + if (!listResponse.data.content || listResponse.data.content.length < pageSize) { break; } From 7a5acbbe69288210d118ed79a7156de2400e495d Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 13 Feb 2026 17:13:17 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E7=94=9F=E6=80=81=E5=BA=94=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/icons/OrionTV.png | Bin 0 -> 14833 bytes public/icons/Selene.png | Bin 0 -> 30139 bytes src/components/UserMenu.tsx | 211 +++++++++++++++++++++++++++++++++++- 3 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 public/icons/OrionTV.png create mode 100644 public/icons/Selene.png diff --git a/public/icons/OrionTV.png b/public/icons/OrionTV.png new file mode 100644 index 0000000000000000000000000000000000000000..2bfd5abfaed4c27980f3dc6e3bc85bd58f16f4cb GIT binary patch literal 14833 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%0D2tr`w&d6;nSq--WxPZ{YVR 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 { const [isFavoritesPanelOpen, setIsFavoritesPanelOpen] = useState(false); const [isEmailSettingsOpen, setIsEmailSettingsOpen] = useState(false); const [isDeviceManagementOpen, setIsDeviceManagementOpen] = useState(false); + const [isEcoAppsOpen, setIsEcoAppsOpen] = useState(false); const [authInfo, setAuthInfo] = useState(null); const [storageType, setStorageType] = useState('localstorage'); const [mounted, setMounted] = useState(false); @@ -78,7 +80,7 @@ export const UserMenu: React.FC = () => { // Body 滚动锁定 - 使用 overflow 方式避免布局问题 useEffect(() => { - if (isSettingsOpen || isChangePasswordOpen || isSubscribeOpen || isOfflineDownloadPanelOpen || isEmailSettingsOpen || isDeviceManagementOpen) { + if (isSettingsOpen || isChangePasswordOpen || isSubscribeOpen || isOfflineDownloadPanelOpen || isEmailSettingsOpen || isDeviceManagementOpen || isEcoAppsOpen) { const body = document.body; const html = document.documentElement; @@ -97,7 +99,7 @@ export const UserMenu: React.FC = () => { html.style.overflow = originalHtmlOverflow; }; } - }, [isSettingsOpen, isChangePasswordOpen, isSubscribeOpen, isOfflineDownloadPanelOpen, isEmailSettingsOpen, isDeviceManagementOpen]); + }, [isSettingsOpen, isChangePasswordOpen, isSubscribeOpen, isOfflineDownloadPanelOpen, isEmailSettingsOpen, isDeviceManagementOpen, isEcoAppsOpen]); // 设置相关状态 const [defaultAggregateSearch, setDefaultAggregateSearch] = useState(true); @@ -1285,6 +1287,18 @@ export const UserMenu: React.FC = () => { )} + {/* 生态应用按钮 */} + + {/* 分割线 */}
@@ -2859,6 +2873,194 @@ export const UserMenu: React.FC = () => { ); + // 生态应用面板内容 + const ecoAppsPanel = ( + <> + {/* 背景遮罩 */} +
setIsEcoAppsOpen(false)} + onTouchMove={(e) => { + e.preventDefault(); + }} + onWheel={(e) => { + e.preventDefault(); + }} + style={{ + touchAction: 'none', + }} + /> + + {/* 生态应用面板 */} +
+
{ + e.stopPropagation(); + }} + style={{ + touchAction: 'auto', + }} + > + {/* 标题栏 */} +
+

+ 生态应用 +

+ +
+ + {/* 应用列表 */} +
+
+ {/* MoonTVPlus-PC 客户端 */} +
+
+
+ MoonTVPlus-PC +
+ +
+
+
+

+ MoonTVPlus-PC客户端 +

+

+ 专为Windows开发的客户端,完美支持私人影库mkv视频 +

+ + + 下载 + + +
+
+
+ + {/* Selene 跨平台客户端 */} +
+
+
+ Selene + + 二开 + +
+
+

+ Selene 跨平台客户端 +

+

+ 多平台客户端 +

+
+ + + 安卓下载 + + + +
+
+
+
+ + {/* OrionTV TV专用客户端 */} +
+
+
+ OrionTV + + 二开 + +
+
+

+ OrionTV TV专用客户端 +

+

+ tv专用 +

+ + + 下载 + + +
+
+
+
+
+ + {/* 底部说明 */} +
+

+ 选择适合您设备的客户端下载使用 +

+
+
+
+ + ); + return ( <>
@@ -2942,6 +3144,11 @@ export const UserMenu: React.FC = () => { mounted && createPortal(deviceManagementPanel, document.body)} + {/* 使用 Portal 将生态应用面板渲染到 document.body */} + {isEcoAppsOpen && + mounted && + createPortal(ecoAppsPanel, document.body)} + {/* 确认对话框 */} {confirmDialog.isOpen && mounted && From 41f241095e3f318bf940fe88f71cfbf6279dfc9c Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 13 Feb 2026 17:30:13 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E6=B1=82=E7=89=87=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/private-library/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/private-library/page.tsx b/src/app/private-library/page.tsx index 730b2a5..8b4d94b 100644 --- a/src/app/private-library/page.tsx +++ b/src/app/private-library/page.tsx @@ -579,6 +579,7 @@ export default function PrivateLibraryPage() {
+ + {/* 精确搜索 */} +
+
+

+ 精确搜索 +

+

+ 开启后,搜索结果将过滤掉不包含搜索词的内容 +

+
+ +
)} From 04bb7a1adae2fbd8232e647c3ba69473b8535169 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 13 Feb 2026 20:08:58 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E6=9B=B4=E9=89=B4=E6=9D=83=E7=9A=84m3u8?= =?UTF-8?q?=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/proxy-m3u8/route.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/app/api/proxy-m3u8/route.ts b/src/app/api/proxy-m3u8/route.ts index 1c86565..6d52a03 100644 --- a/src/app/api/proxy-m3u8/route.ts +++ b/src/app/api/proxy-m3u8/route.ts @@ -35,13 +35,22 @@ export async function GET(request: Request) { } // 获取当前请求的 origin - const requestUrl = new URL(request.url); - const origin = `${requestUrl.protocol}//${requestUrl.host}`; + // 优先级:SITE_BASE 环境变量 > 从请求头构建 + let origin = process.env.SITE_BASE; + if (!origin) { + const requestUrl = new URL(request.url); + origin = `${requestUrl.protocol}//${requestUrl.host}`; + } // 获取原始 m3u8 内容 + const m3u8UrlObj = new URL(m3u8Url); const response = await fetch(m3u8Url, { headers: { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Accept': '*/*', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Referer': `${m3u8UrlObj.protocol}//${m3u8UrlObj.host}/`, }, }); From fc7c5e48c5f003b8c4075ec35d515b9fb7f444ec Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 13 Feb 2026 20:11:50 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E5=88=A0=E9=99=A4=E6=9C=80=E5=90=8E=E4=B8=80=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/admin/page.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 8e6a8cd..201a5a7 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -3621,11 +3621,6 @@ const EmbyConfigComponent = ({ // 删除源 const handleDelete = async (source: any) => { - if (sources.length === 1) { - showError('至少需要保留一个Emby源', showAlert); - return; - } - if (!confirm(`确定要删除 "${source.name}" 吗?`)) { return; } From a46906c15783e4eb27c7b2f6ebf45cca34c6f2b7 Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 13 Feb 2026 20:47:05 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E6=97=A0=E6=B3=95=E8=B0=83=E8=8A=82=E9=9F=B3=E4=B9=90?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E9=9F=B3=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/music/page.tsx | 60 +++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/src/app/music/page.tsx b/src/app/music/page.tsx index 14cc9ac..1c62400 100644 --- a/src/app/music/page.tsx +++ b/src/app/music/page.tsx @@ -1178,6 +1178,52 @@ export default function MusicPage() { } }; + // 触摸/鼠标滑动音量调节(移动端兼容) + const handleVolumeSliderInteraction = (e: React.MouseEvent | React.TouchEvent) => { + e.preventDefault(); + e.stopPropagation(); + + const slider = e.currentTarget; + const rect = slider.getBoundingClientRect(); + + const updateVolume = (clientY: number) => { + // 计算相对于滑块顶部的位置 + const y = clientY - rect.top; + // 限制在滑块范围内 + const clampedY = Math.max(0, Math.min(rect.height, y)); + // 从上到下:0% -> 100%,从下到上:100% -> 0% + const percentage = 100 - (clampedY / rect.height) * 100; + const newVolume = Math.round(percentage); + + setVolume(newVolume); + if (audioRef.current) { + audioRef.current.volume = newVolume / 100; + } + }; + + // 获取初始触摸/点击位置 + const clientY = 'touches' in e ? e.touches[0]?.clientY || 0 : e.clientY; + updateVolume(clientY); + + const handleMove = (moveEvent: MouseEvent | TouchEvent) => { + moveEvent.preventDefault(); + const moveClientY = 'touches' in moveEvent ? moveEvent.touches[0]?.clientY || 0 : moveEvent.clientY; + updateVolume(moveClientY); + }; + + const handleEnd = () => { + document.removeEventListener('mousemove', handleMove); + document.removeEventListener('mouseup', handleEnd); + document.removeEventListener('touchmove', handleMove); + document.removeEventListener('touchend', handleEnd); + }; + + document.addEventListener('mousemove', handleMove); + document.addEventListener('mouseup', handleEnd); + document.addEventListener('touchmove', handleMove, { passive: false }); + document.addEventListener('touchend', handleEnd); + }; + // PiP 窗口管理 const togglePiPLyrics = () => { if (!('documentPictureInPicture' in window)) { @@ -1946,19 +1992,15 @@ export default function MusicPage() {
{volume} -
+
-