每日签到奶昔超市点数市场奶昔访达
返回列表 发布新帖
查看: 2182|回复: 1

[教程] 【支持DIYP类播放器】通过无服务环境搭建属于自己的EPG服务

发表于 2024-8-10 15:20:56 | 查看全部 |阅读模式

欢迎注册论坛,享受更多奶昔会员权益!

您需要 登录 才可以下载或查看,没有账号?注册

×
前言:


本文介绍通过Cloudflare的Worker服务来搭建属于自己的EPG服务。

无套路,无推广,非广告,回复可获取代码。


优点:

免维护自动更新
支持IPv6/IPv4双栈访问
无需自己的服务器无任何费用
支持xml格式和DIYP类播放器格式
DIPY接口支持历史多天EPG内容查询


部署步骤:

1、访问https://www.cloudflare.com 并登录
2、选择页面左侧的[Workers 和 Pages]
3、右上角选择[创建应用程序]——[创建Worker]——[部署]
4、点击部署后,会提示已部署,再点击[编辑代码]。
5、将下方代码全部复制粘贴至窗口左侧的worker.js完成替换:
  1. const Config = {
  2.     repository: 'live.fanmingming.com'
  3. };

  4. async function jq_fetch(request) {
  5.     let response = await fetch(request);
  6.     for (let i = 0; i < 5 && (response.status === 301 || response.status === 302 || response.redirected); i++) {
  7.         const location = response.headers.get('location') || response.url;
  8.         response = await fetch(new Request(location, { headers: { cookie: response.headers.get('set-cookie') } }));
  9.     }
  10.     return response;
  11. }

  12. function makeRes(body, status = 200, headers = { 'access-control-allow-origin': '*' }) {
  13.     return new Response(body, { status, headers });
  14. }

  15. function formatDateTime(time = '') {
  16.     const now = new Date();
  17.     const year = now.getFullYear();
  18.     const month = String(now.getMonth() + 1).padStart(2, '0');
  19.     const day = String(now.getDate()).padStart(2, '0');
  20.     const defaultDate = `${year}-${month}-${day}`;

  21.     if (time.length < 8) return { date: defaultDate, time: '' };

  22.     const [inputYear, inputMonth, inputDay] = [time.substring(0, 4), time.substring(4, 6), time.substring(6, 8)];
  23.     const formattedDate = `${inputYear}-${inputMonth}-${inputDay}`;
  24.     const formattedTime = time.length >= 12 ? `${time.substring(8, 10)}:${time.substring(10, 12)}` : '';

  25.     return { date: formattedDate, time: formattedTime };
  26. }

  27. async function diypHandle(channel, date, request) {
  28.     const tag = date.replace(/-/g, '.');
  29.     const res = await jq_fetch(new Request(`https://github.com/celetor/epg/releases/download/${tag}/112114.json`, request));
  30.     const data = await res.json();

  31.     const program_info = {
  32.         date,
  33.         channel_name: channel,
  34.         url: `https://${Config.repository}`,
  35.         epg_data: data.filter(element => element['@channel'] === channel && element['@start'].startsWith(date.replace(/-/g, '')))
  36.                       .map(element => ({
  37.                           start: formatDateTime(element['@start']).time,
  38.                           end: formatDateTime(element['@stop']).time,
  39.                           title: element['title']['#text'] || '未知节目',
  40.                           desc: element['desc']?.['#text'] || ''
  41.                       }))
  42.     };

  43.     if (program_info.epg_data.length === 0) {
  44.         program_info.epg_data.push({ start: "00:00", end: "23:59", title: "未知节目", desc: "" });
  45.     }

  46.     return makeRes(JSON.stringify(program_info), 200, { 'content-type': 'application/json' });
  47. }

  48. async function fetchHandler(event) {
  49.     const request = event.request;
  50.     const url = new URL(request.url);

  51.     if (url.pathname === '/' && !url.searchParams.has('ch')) {
  52.         return Response.redirect(`https://${Config.repository}/e.xml`, 302);
  53.     }

  54.     const channel = (url.searchParams.get("ch") || '').toUpperCase().replace(/-/g, '');
  55.     const dateParam = url.searchParams.get("date");
  56.     const date = formatDateTime(dateParam ? dateParam.replace(/\D+/g, '') : '').date;

  57.     if (parseInt(date.replace(/-/g, '')) >= 20240531) {
  58.         return diypHandle(channel, date, request);
  59.     } else {
  60.         return makeRes(JSON.stringify({
  61.             date,
  62.             channel_name: channel,
  63.             url: `https://${Config.repository}`,
  64.             epg_data: [{ start: "00:00", end: "23:59", title: "未知节目", desc: "" }]
  65.         }), 200, { 'content-type': 'application/json' });
  66.     }
  67. }

  68. addEventListener('fetch', event => {
  69.     event.respondWith(fetchHandler(event).catch(err => makeRes(`error:\n${err.stack}`, 502)));
  70. });
复制代码


6、替换完成后点击右上角的[部署]——[保存并部署]。
7、选择左上角返回,找到[设置]——[触发器],右侧选择[添加自定义域],将自己的域名与之绑定访问即可。



使用说明与演示示例:

部署完成后,EPG接口地址统一为您的自定义域名。
APTV及TiviMate或DIYP软件可直接将您的自定义域名设置为EPG地址。

DIYP类软件指定日期调用示例(以CCTV1为例):
epg.0472.org/?ch=CCTV1&date=20240601



搭建建议:
上方链接仅作为演示,可能会随时关闭,建议自行搭建来使用。
以上服务目前为测试阶段,Worker.js代码的bug问题与更新您可前往GitHub自取。
爱生活,爱奶昔~
回复

使用道具 举报

发表于 2024-8-11 17:21:41 | 查看全部
看看
爱生活,爱奶昔~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

© 2025 Nyarime 沪ICP备13020230号-1|沪公网安备 31010702007642号手机版小黑屋RSS
返回顶部 关灯 在本版发帖
快速回复 返回顶部 返回列表