去广告增强
This commit is contained in:
+38
-5
@@ -8429,18 +8429,51 @@ const CustomAdFilterConfig = ({
|
|||||||
const defaultAdFilterCode = `function filterAdsFromM3U8(type: string, m3u8Content: string): string {
|
const defaultAdFilterCode = `function filterAdsFromM3U8(type: string, m3u8Content: string): string {
|
||||||
if (!m3u8Content) return '';
|
if (!m3u8Content) return '';
|
||||||
|
|
||||||
|
// 广告关键字列表
|
||||||
|
const adKeywords = [
|
||||||
|
'sponsor',
|
||||||
|
'/ad/',
|
||||||
|
'/ads/',
|
||||||
|
'advert',
|
||||||
|
'advertisement',
|
||||||
|
'/adjump',
|
||||||
|
'redtraffic'
|
||||||
|
];
|
||||||
|
|
||||||
// 按行分割M3U8内容
|
// 按行分割M3U8内容
|
||||||
const lines = m3u8Content.split('\\n');
|
const lines = m3u8Content.split('\\n');
|
||||||
const filteredLines = [];
|
const filteredLines = [];
|
||||||
|
|
||||||
let nextdelete = false;
|
let i = 0;
|
||||||
for (let i = 0; i < lines.length; i++) {
|
while (i < lines.length) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
|
|
||||||
// 只过滤#EXT-X-DISCONTINUITY标识
|
// 跳过 #EXT-X-DISCONTINUITY 标识
|
||||||
if (!line.includes('#EXT-X-DISCONTINUITY')) {
|
if (line.includes('#EXT-X-DISCONTINUITY')) {
|
||||||
filteredLines.push(line);
|
i++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是 EXTINF 行,检查下一行 URL 是否包含广告关键字
|
||||||
|
if (line.includes('#EXTINF:')) {
|
||||||
|
// 检查下一行 URL 是否包含广告关键字
|
||||||
|
if (i + 1 < lines.length) {
|
||||||
|
const nextLine = lines[i + 1];
|
||||||
|
const containsAdKeyword = adKeywords.some(keyword =>
|
||||||
|
nextLine.toLowerCase().includes(keyword.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (containsAdKeyword) {
|
||||||
|
// 跳过 EXTINF 行和 URL 行
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留当前行
|
||||||
|
filteredLines.push(line);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredLines.join('\\n');
|
return filteredLines.join('\\n');
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
import { getConfig } from '@/lib/config';
|
import { getConfig } from '@/lib/config';
|
||||||
|
|
||||||
export const runtime = 'nodejs';
|
export const runtime = 'nodejs';
|
||||||
|
export const dynamic = 'force-dynamic'; // 禁用缓存
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /api/ad-filter
|
* GET /api/ad-filter
|
||||||
|
|||||||
@@ -107,37 +107,51 @@ export async function GET(request: Request) {
|
|||||||
function filterAdsFromM3U8Default(type: string, m3u8Content: string): string {
|
function filterAdsFromM3U8Default(type: string, m3u8Content: string): string {
|
||||||
if (!m3u8Content) return '';
|
if (!m3u8Content) return '';
|
||||||
|
|
||||||
|
// 广告关键字列表
|
||||||
|
const adKeywords = [
|
||||||
|
'sponsor',
|
||||||
|
'/ad/',
|
||||||
|
'/ads/',
|
||||||
|
'advert',
|
||||||
|
'advertisement',
|
||||||
|
'/adjump',
|
||||||
|
'redtraffic'
|
||||||
|
];
|
||||||
|
|
||||||
// 按行分割M3U8内容
|
// 按行分割M3U8内容
|
||||||
const lines = m3u8Content.split('\n');
|
const lines = m3u8Content.split('\n');
|
||||||
const filteredLines = [];
|
const filteredLines = [];
|
||||||
|
|
||||||
let nextdelete = false;
|
let i = 0;
|
||||||
for (let i = 0; i < lines.length; i++) {
|
while (i < lines.length) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
|
|
||||||
if (nextdelete) {
|
// 跳过 #EXT-X-DISCONTINUITY 标识
|
||||||
nextdelete = false;
|
if (line.includes('#EXT-X-DISCONTINUITY')) {
|
||||||
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只过滤#EXT-X-DISCONTINUITY标识
|
// 如果是 EXTINF 行,检查下一行 URL 是否包含广告关键字
|
||||||
if (!line.includes('#EXT-X-DISCONTINUITY')) {
|
if (line.includes('#EXTINF:')) {
|
||||||
if (
|
// 检查下一行 URL 是否包含广告关键字
|
||||||
type === 'ruyi' &&
|
if (i + 1 < lines.length) {
|
||||||
(line.includes('EXTINF:5.640000') ||
|
const nextLine = lines[i + 1];
|
||||||
line.includes('EXTINF:2.960000') ||
|
const containsAdKeyword = adKeywords.some(keyword =>
|
||||||
line.includes('EXTINF:3.480000') ||
|
nextLine.toLowerCase().includes(keyword.toLowerCase())
|
||||||
line.includes('EXTINF:4.000000') ||
|
);
|
||||||
line.includes('EXTINF:0.960000') ||
|
|
||||||
line.includes('EXTINF:10.000000') ||
|
|
||||||
line.includes('EXTINF:1.266667'))
|
|
||||||
) {
|
|
||||||
nextdelete = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredLines.push(line);
|
if (containsAdKeyword) {
|
||||||
|
// 跳过 EXTINF 行和 URL 行
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保留当前行
|
||||||
|
filteredLines.push(line);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredLines.join('\n');
|
return filteredLines.join('\n');
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export default async function RootLayout({
|
|||||||
let aiDefaultMessageWithVideo = '';
|
let aiDefaultMessageWithVideo = '';
|
||||||
let enableMovieRequest = true;
|
let enableMovieRequest = true;
|
||||||
let webLiveEnabled = false;
|
let webLiveEnabled = false;
|
||||||
|
let customAdFilterVersion = 0;
|
||||||
let customCategories = [] as {
|
let customCategories = [] as {
|
||||||
name: string;
|
name: string;
|
||||||
type: 'movie' | 'tv';
|
type: 'movie' | 'tv';
|
||||||
@@ -130,6 +131,8 @@ export default async function RootLayout({
|
|||||||
enableMovieRequest = config.SiteConfig.EnableMovieRequest ?? true;
|
enableMovieRequest = config.SiteConfig.EnableMovieRequest ?? true;
|
||||||
// 网络直播功能配置
|
// 网络直播功能配置
|
||||||
webLiveEnabled = config.WebLiveEnabled ?? false;
|
webLiveEnabled = config.WebLiveEnabled ?? false;
|
||||||
|
// 自定义去广告代码版本号
|
||||||
|
customAdFilterVersion = config.SiteConfig?.CustomAdFilterVersion || 0;
|
||||||
// 检查是否启用了 OpenList 功能
|
// 检查是否启用了 OpenList 功能
|
||||||
openListEnabled = !!(
|
openListEnabled = !!(
|
||||||
config.OpenListConfig?.Enabled &&
|
config.OpenListConfig?.Enabled &&
|
||||||
@@ -186,6 +189,7 @@ export default async function RootLayout({
|
|||||||
AI_DEFAULT_MESSAGE_WITH_VIDEO: aiDefaultMessageWithVideo,
|
AI_DEFAULT_MESSAGE_WITH_VIDEO: aiDefaultMessageWithVideo,
|
||||||
ENABLE_MOVIE_REQUEST: enableMovieRequest,
|
ENABLE_MOVIE_REQUEST: enableMovieRequest,
|
||||||
WEB_LIVE_ENABLED: webLiveEnabled,
|
WEB_LIVE_ENABLED: webLiveEnabled,
|
||||||
|
CUSTOM_AD_FILTER_VERSION: customAdFilterVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
+37
-29
@@ -245,14 +245,8 @@ function PlayPageClient() {
|
|||||||
console.log('使用缓存的去广告代码');
|
console.log('使用缓存的去广告代码');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第一步:先只获取版本号,检查是否需要更新
|
// 从 window.RUNTIME_CONFIG 获取版本号
|
||||||
const versionResponse = await fetch('/api/ad-filter');
|
const version = (window as any).RUNTIME_CONFIG?.CUSTOM_AD_FILTER_VERSION || 0;
|
||||||
if (!versionResponse.ok) {
|
|
||||||
console.warn('获取去广告代码版本失败,使用缓存');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { version } = await versionResponse.json();
|
|
||||||
|
|
||||||
// 如果版本号为 0,说明去广告未设置,清空缓存并跳过
|
// 如果版本号为 0,说明去广告未设置,清空缓存并跳过
|
||||||
if (version === 0) {
|
if (version === 0) {
|
||||||
@@ -267,7 +261,7 @@ function PlayPageClient() {
|
|||||||
if (!cachedVersion || parseInt(cachedVersion) !== version) {
|
if (!cachedVersion || parseInt(cachedVersion) !== version) {
|
||||||
console.log('检测到去广告代码更新(版本 ' + version + '),获取最新代码');
|
console.log('检测到去广告代码更新(版本 ' + version + '),获取最新代码');
|
||||||
|
|
||||||
// 第二步:获取完整代码
|
// 获取完整代码
|
||||||
const fullResponse = await fetch('/api/ad-filter?full=true');
|
const fullResponse = await fetch('/api/ad-filter?full=true');
|
||||||
if (!fullResponse.ok) {
|
if (!fullResponse.ok) {
|
||||||
console.warn('获取完整去广告代码失败,使用缓存');
|
console.warn('获取完整去广告代码失败,使用缓存');
|
||||||
@@ -2499,37 +2493,51 @@ function PlayPageClient() {
|
|||||||
// 默认去广告规则
|
// 默认去广告规则
|
||||||
if (!m3u8Content) return '';
|
if (!m3u8Content) return '';
|
||||||
|
|
||||||
|
// 广告关键字列表
|
||||||
|
const adKeywords = [
|
||||||
|
'sponsor',
|
||||||
|
'/ad/',
|
||||||
|
'/ads/',
|
||||||
|
'advert',
|
||||||
|
'advertisement',
|
||||||
|
'/adjump',
|
||||||
|
'redtraffic'
|
||||||
|
];
|
||||||
|
|
||||||
// 按行分割M3U8内容
|
// 按行分割M3U8内容
|
||||||
const lines = m3u8Content.split('\n');
|
const lines = m3u8Content.split('\n');
|
||||||
const filteredLines = [];
|
const filteredLines = [];
|
||||||
|
|
||||||
let nextdelete = false;
|
let i = 0;
|
||||||
for (let i = 0; i < lines.length; i++) {
|
while (i < lines.length) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
|
|
||||||
if (nextdelete) {
|
// 跳过 #EXT-X-DISCONTINUITY 标识
|
||||||
nextdelete = false;
|
if (line.includes('#EXT-X-DISCONTINUITY')) {
|
||||||
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只过滤#EXT-X-DISCONTINUITY标识
|
// 如果是 EXTINF 行,检查下一行 URL 是否包含广告关键字
|
||||||
if (!line.includes('#EXT-X-DISCONTINUITY')) {
|
if (line.includes('#EXTINF:')) {
|
||||||
if (
|
// 检查下一行 URL 是否包含广告关键字
|
||||||
type == 'ruyi' &&
|
if (i + 1 < lines.length) {
|
||||||
(line.includes('EXTINF:5.640000') ||
|
const nextLine = lines[i + 1];
|
||||||
line.includes('EXTINF:2.960000') ||
|
const containsAdKeyword = adKeywords.some(keyword =>
|
||||||
line.includes('EXTINF:3.480000') ||
|
nextLine.toLowerCase().includes(keyword.toLowerCase())
|
||||||
line.includes('EXTINF:4.000000') ||
|
);
|
||||||
line.includes('EXTINF:0.960000') ||
|
|
||||||
line.includes('EXTINF:10.000000') ||
|
|
||||||
line.includes('EXTINF:1.266667'))
|
|
||||||
) {
|
|
||||||
nextdelete = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredLines.push(line);
|
if (containsAdKeyword) {
|
||||||
|
// 跳过 EXTINF 行和 URL 行
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保留当前行
|
||||||
|
filteredLines.push(line);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return filteredLines.join('\n');
|
return filteredLines.join('\n');
|
||||||
|
|||||||
Reference in New Issue
Block a user