-
Notifications
You must be signed in to change notification settings - Fork 842
去插广技术文档
Hiram·Wong edited this page Jun 4, 2024
·
1 revision
本项目设计为M3U8播放地址处理工具,核心功能在于自动检测并移除嵌入在M3U8播放列表内的广告片段,同时兼容处理嵌套的M3U8链接。利用axios
进行网络通信以检索M3U8文件,提供无广告的纯净播放体验。
去除网络插播广告虽满足部分用户需求,但需谨慎行事,考虑到可能引发的法律、技术及道德后果。用户在寻求改善在线体验的同时,应选择合法、安全的方式,并尊重内容创作者和平台的权益
- 目标: 确保在所有环境下均可使用数组的倒序功能。
- 价值: 提高代码的跨环境兼容性。
- 功能: 实现URL的正确解析与片段的拼接,特别是在处理M3U8内相对路径时。
- 重要性: 确保资源引用的准确无误。
-
职责:
- 智能识别广告: 通过比对播放片段特征识别广告内容。
- 嵌套处理: 处理M3U8列表中嵌套的其他M3U8链接。
- URL修正: 转换所有播放片段URL为绝对路径。
-
技术亮点:
- 异步数据获取。
- 精准的广告识别算法。
- 详细的日志记录。
-
工作流程:
-
- 输入: 接收用户提供的M3U8播放地址。
-
-
获取M3U8内容: 使用
axios
执行网络请求。
-
获取M3U8内容: 使用
-
- 基础处理: 清理文本,转换URL为绝对形式。
-
- 广告识别与剔除:
- 4.1. 分析首尾播放片段,计算相似度。
- 4.2. 依据阈值移除疑似广告URL。
-
- 递归处理嵌套M3U8(如存在)。
-
- 输出: 返回处理后的纯净M3U8列表。
-
- 日志记录: 全程记录关键步骤和性能指标。
-
- 匹配精度
- 同域名广告识别
非本人原创代码,如有侵权,联系删除,请勿用于商业用途。
点我查看示例代码
import axios from 'axios';
import logger from '../../../logger';
if (typeof Array.prototype.toReversed !== 'function') {
Array.prototype.toReversed = function () {
const clonedList = this.slice();
// 倒序新数组
const reversedList = clonedList.reverse();
return reversedList;
};
}
const resolve = (from, to) => {
const resolvedUrl = new URL(to, new URL(from, 'resolve://'));
if (resolvedUrl.protocol === 'resolve:') {
const { pathname, search, hash } = resolvedUrl;
return pathname + search + hash;
}
return resolvedUrl.href;
};
/**
* url拼接
* @param fromPath 初始当前页面url
* @param nowPath 相对当前页面url
* @returns {*}
*/
const urljoin = (fromPath, nowPath) => {
fromPath = fromPath || '';
nowPath = nowPath || '';
return resolve(fromPath, nowPath);
};
/**
* 智能对比去除广告。支持嵌套m3u8。只需要传入播放地址
* @param m3u8_url m3u8播放地址
* @param headers 自定义访问m3u8的请求头,可以不传
* @returns {string}
*/
const fixAdM3u8Ai = async (m3u8_url: string, headers: object | null = null) => {
let ts = new Date().getTime();
let option = headers ? { headers } : {};
function b(s1, s2) {
let i = 0;
while (i < s1.length) {
if (s1[i] !== s2[i]) {
break;
}
i++;
}
return i;
}
function reverseString(str) {
return str.split('').reverse().join('');
}
//log('播放的地址:' + m3u8_url);
const m3u8_response = await axios.get(m3u8_url, option);
let m3u8 = m3u8_response.data;
//log('m3u8处理前:' + m3u8);
m3u8 = m3u8
.trim()
.split('\n')
.map((it) => (it.startsWith('#') ? it : urljoin(m3u8_url, it)))
.join('\n');
//log('m3u8处理后:============:' + m3u8);
// 获取嵌套m3u8地址
m3u8 = m3u8.replace(/\n\n/gi, '\n'); //删除多余的换行符
let last_url = m3u8.split('\n').slice(-1)[0];
if (last_url.length < 5) {
last_url = m3u8.split('\n').slice(-2)[0];
}
if (last_url.includes('.m3u8') && last_url !== m3u8_url) {
m3u8_url = urljoin(m3u8_url, last_url);
logger.info('嵌套的m3u8_url:' + m3u8_url);
const m3u8_nest_response = await axios.get(m3u8_url, option);
m3u8 = m3u8_nest_response.data;
}
//log('----处理有广告的地址----');
let s = m3u8
.trim()
.split('\n')
.filter((it) => it.trim())
.join('\n');
let ss = s.split('\n');
//找出第一条播放地址
let firststr = ss.find((x) => !x.startsWith('#'));
let maxl = 0; //最大相同字符
let firststrlen = firststr!.length;
//log('字符串长度:' + firststrlen);
let ml = Math.round(ss.length / 2).toString().length; //取数据的长度的位数
//log('数据条数的长度:' + ml);
//找出最后一条播放地址
let maxc = 0;
let laststr = ss.toReversed().find((x) => {
if (!x.startsWith('#')) {
let k = b(reverseString(firststr), reverseString(x));
maxl = b(firststr, x);
maxc++;
if (firststrlen - maxl <= ml + k || maxc > 10) {
return true;
}
}
return false;
});
logger.info('最后一条切片:' + laststr);
//log('最小相同字符长度:' + maxl);
let ad_urls: string[] = [];
for (let i = 0; i < ss.length; i++) {
let s = ss[i];
if (!s.startsWith('#')) {
if (b(firststr, s) < maxl) {
ad_urls.push(s); // 广告地址加入列表
ss.splice(i - 1, 2);
i = i - 2;
} else {
ss[i] = urljoin(m3u8_url, s);
}
} else {
ss[i] = s.replace(/URI=\"(.*)\"/, 'URI="' + urljoin(m3u8_url, '$1') + '"');
}
}
logger.info('处理的m3u8地址:' + m3u8_url);
logger.info('----广告地址----');
logger.info(ad_urls);
m3u8 = ss.join('\n');
//log('处理完成');
logger.info('处理耗时:' + (new Date().getTime() - ts).toString());
return m3u8;
};
export { fixAdM3u8Ai };
算法核心十分重要,微小的逻辑错误,可能引发连锁反应,导致误删非广告部分正常内容的关键数据。因此,在面临模棱两可的决策时,应更加谨慎细致,力求在保留数据的完整性与准确性的同时,实现体验的升级。
跨平台桌面端视频资源播放器,免费高颜值!