diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..b8dfd2f --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": ["WebSearch", "Bash(curl:*)"], + "deny": [], + "ask": [] + } +} diff --git a/.next b/.next deleted file mode 120000 index 27e4e2f..0000000 --- a/.next +++ /dev/null @@ -1 +0,0 @@ -/.next \ No newline at end of file diff --git a/public/players/iina.png b/public/players/iina.png new file mode 100644 index 0000000..c31681b Binary files /dev/null and b/public/players/iina.png differ diff --git a/public/players/mpv.png b/public/players/mpv.png new file mode 100644 index 0000000..d71e2d3 Binary files /dev/null and b/public/players/mpv.png differ diff --git a/public/players/mxplayer.png b/public/players/mxplayer.png new file mode 100644 index 0000000..252c4ca Binary files /dev/null and b/public/players/mxplayer.png differ diff --git a/public/players/nplayer.png b/public/players/nplayer.png new file mode 100644 index 0000000..12742e6 Binary files /dev/null and b/public/players/nplayer.png differ diff --git a/public/players/potplayer.png b/public/players/potplayer.png new file mode 100644 index 0000000..46310b0 Binary files /dev/null and b/public/players/potplayer.png differ diff --git a/public/players/vlc.png b/public/players/vlc.png new file mode 100644 index 0000000..8973916 Binary files /dev/null and b/public/players/vlc.png differ diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx index 1c78cf7..c841d44 100644 --- a/src/app/play/page.tsx +++ b/src/app/play/page.tsx @@ -328,8 +328,10 @@ function PlayPageClient() { console.log('播放源评分排序结果:'); resultsWithScore.forEach((result, index) => { console.log( - `${index + 1}. ${result.source.source_name - } - 评分: ${result.score.toFixed(2)} (${result.testResult.quality}, ${result.testResult.loadSpeed + `${index + 1}. ${ + result.source.source_name + } - 评分: ${result.score.toFixed(2)} (${result.testResult.quality}, ${ + result.testResult.loadSpeed }, ${result.testResult.pingTime}ms)` ); }); @@ -493,42 +495,42 @@ function PlayPageClient() { } }; - function filterAdsFromM3U8(type : string,m3u8Content: string): string { + function filterAdsFromM3U8(type: string, m3u8Content: string): string { if (!m3u8Content) return ''; // 按行分割M3U8内容 const lines = m3u8Content.split('\n'); const filteredLines = []; - let nextdelete = false + let nextdelete = false; for (let i = 0; i < lines.length; i++) { const line = lines[i]; - if (nextdelete){ - nextdelete = false - continue - } + if (nextdelete) { + nextdelete = false; + continue; + } // 只过滤#EXT-X-DISCONTINUITY标识 if (!line.includes('#EXT-X-DISCONTINUITY')) { - - if (type == "ruyi" && ( - line.includes('EXTINF:5.640000') || + if ( + type == 'ruyi' && + (line.includes('EXTINF:5.640000') || line.includes('EXTINF:2.960000') || line.includes('EXTINF:3.480000') || line.includes('EXTINF:4.000000') || line.includes('EXTINF:0.960000') || line.includes('EXTINF:10.000000') || - line.includes('EXTINF:1.266667') - )){ - nextdelete = true - continue + line.includes('EXTINF:1.266667')) + ) { + nextdelete = true; + continue; } filteredLines.push(line); } } - + return filteredLines.join('\n'); } @@ -653,7 +655,10 @@ function PlayPageClient() { // 如果是m3u8文件,处理内容以移除广告分段 if (response.data && typeof response.data === 'string') { // 过滤掉广告段 - 实现更精确的广告过滤逻辑 - response.data = filterAdsFromM3U8(currentSourceRef.current,response.data); + response.data = filterAdsFromM3U8( + currentSourceRef.current, + response.data + ); } return onSuccess(response, stats, context, null); }; @@ -707,13 +712,13 @@ function PlayPageClient() { const results = data.results.filter( (result: SearchResult) => result.title.replaceAll(' ', '').toLowerCase() === - videoTitleRef.current.replaceAll(' ', '').toLowerCase() && + videoTitleRef.current.replaceAll(' ', '').toLowerCase() && (videoYearRef.current ? result.year.toLowerCase() === videoYearRef.current.toLowerCase() : true) && (searchType ? (searchType === 'tv' && result.episodes.length > 1) || - (searchType === 'movie' && result.episodes.length === 1) + (searchType === 'movie' && result.episodes.length === 1) : true) ); setAvailableSources(results); @@ -1283,8 +1288,9 @@ function PlayPageClient() { // 非WebKit浏览器且播放器已存在,使用switch方法切换 if (!isWebkit && artPlayerRef.current) { artPlayerRef.current.switch = videoUrl; - artPlayerRef.current.title = `${videoTitle} - 第${currentEpisodeIndex + 1 - }集`; + artPlayerRef.current.title = `${videoTitle} - 第${ + currentEpisodeIndex + 1 + }集`; artPlayerRef.current.poster = videoCover; if (artPlayerRef.current?.video) { ensureVideoSource( @@ -1610,7 +1616,7 @@ function PlayPageClient() { skipConfigRef.current.outro_time < 0 && duration > 0 && currentTime > - artPlayerRef.current.duration + skipConfigRef.current.outro_time + artPlayerRef.current.duration + skipConfigRef.current.outro_time ) { if ( currentEpisodeIndexRef.current < @@ -1724,27 +1730,30 @@ function PlayPageClient() {
@@ -1755,11 +1764,11 @@ function PlayPageClient() { style={{ width: loadingStage === 'searching' || - loadingStage === 'fetching' + loadingStage === 'fetching' ? '33%' : loadingStage === 'preferring' - ? '66%' - : '100%', + ? '66%' + : '100%', }} >
@@ -1854,7 +1863,10 @@ function PlayPageClient() { {videoTitle || '影片标题'} {totalEpisodes > 1 && ( - {` > ${detail?.episodes_titles?.[currentEpisodeIndex] || `第 ${currentEpisodeIndex + 1} 集`}`} + {` > ${ + detail?.episodes_titles?.[currentEpisodeIndex] || + `第 ${currentEpisodeIndex + 1} 集` + }`} )} @@ -1873,8 +1885,9 @@ function PlayPageClient() { } >
{/* 播放器 */}
-
+ {/* 播放器容器 */} +
)}
+ + {/* 第三方应用打开按钮 */} + {videoUrl && ( +
+
+
+ {/* PotPlayer */} + + + {/* VLC */} + + + {/* MPV */} + + + {/* MX Player */} + + + {/* nPlayer */} + + + {/* IINA */} + +
+
+
+ )}
{/* 选集和换源 - 在移动端始终显示,在 lg 及以上可折叠 */}