mirror of
https://github.com/fanmingming/live
synced 2026-04-03 12:17:24 +08:00
Add files from main branch to new-branch
This commit is contained in:
22
worker/README.md
Normal file
22
worker/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Worker.js
|
||||
### 通过Cloudflare的Workers服务实现一些功以及对m3u8链接跳转代理的脚本
|
||||
|
||||
---
|
||||
|
||||
## 说明:
|
||||
- `epg.js` 〔***支持DIYP类播放器的EPG服务***〕
|
||||
- `radio.js` 〔***支持logo输出的云听FM代理***〕
|
||||
|
||||
## 部署步骤:
|
||||
|
||||
- 访问https://www.cloudflare.com 并登录
|
||||
- 选择页面左侧的[`Workers 和 Pages`]
|
||||
- 右上角选择[`创建应用程序`]——[`创建Worker`]——[`部署`]
|
||||
- 点击部署后,会提示已部署,再点击[`编辑代码`]。
|
||||
- 复制`.js`文件全部内容粘贴至窗口左侧的完成替换。
|
||||
- 替换完成后点击右上角的[`部署`]——[`保存并部署`]。
|
||||
- 选择左上角返回,找到[`设置`]——[`触发器`],右侧选择[`添加自定义域`],将自己的域名与之绑定访问即可。
|
||||
|
||||
## 优点:
|
||||
- 支持IPv6/IPv4双栈访问
|
||||
- 无需自己的服务器无任何费用
|
||||
85
worker/epg.js
Normal file
85
worker/epg.js
Normal file
@@ -0,0 +1,85 @@
|
||||
const Config = {
|
||||
repository: 'live.fanmingming.com'
|
||||
};
|
||||
|
||||
async function jq_fetch(request) {
|
||||
let response = await fetch(request);
|
||||
for (let i = 0; i < 5 && (response.status === 301 || response.status === 302 || response.redirected); i++) {
|
||||
const location = response.headers.get('location') || response.url;
|
||||
response = await fetch(new Request(location, { headers: { cookie: response.headers.get('set-cookie') } }));
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
function makeRes(body, status = 200, headers = { 'access-control-allow-origin': '*' }) {
|
||||
return new Response(body, { status, headers });
|
||||
}
|
||||
|
||||
function formatDateTime(time = '') {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const defaultDate = `${year}-${month}-${day}`;
|
||||
|
||||
if (time.length < 8) return { date: defaultDate, time: '' };
|
||||
|
||||
const [inputYear, inputMonth, inputDay] = [time.substring(0, 4), time.substring(4, 6), time.substring(6, 8)];
|
||||
const formattedDate = `${inputYear}-${inputMonth}-${inputDay}`;
|
||||
const formattedTime = time.length >= 12 ? `${time.substring(8, 10)}:${time.substring(10, 12)}` : '';
|
||||
|
||||
return { date: formattedDate, time: formattedTime };
|
||||
}
|
||||
|
||||
async function diypHandle(channel, date, request) {
|
||||
const tag = date.replace(/-/g, '.');
|
||||
const res = await jq_fetch(new Request(`https://github.com/celetor/epg/releases/download/${tag}/112114.json`, request));
|
||||
const data = await res.json();
|
||||
|
||||
const program_info = {
|
||||
date,
|
||||
channel_name: channel,
|
||||
url: `https://${Config.repository}`,
|
||||
epg_data: data.filter(element => element['@channel'] === channel && element['@start'].startsWith(date.replace(/-/g, '')))
|
||||
.map(element => ({
|
||||
start: formatDateTime(element['@start']).time,
|
||||
end: formatDateTime(element['@stop']).time,
|
||||
title: element['title']['#text'] || '未知节目',
|
||||
desc: element['desc']?.['#text'] || ''
|
||||
}))
|
||||
};
|
||||
|
||||
if (program_info.epg_data.length === 0) {
|
||||
program_info.epg_data.push({ start: "00:00", end: "23:59", title: "未知节目", desc: "" });
|
||||
}
|
||||
|
||||
return makeRes(JSON.stringify(program_info), 200, { 'content-type': 'application/json' });
|
||||
}
|
||||
|
||||
async function fetchHandler(event) {
|
||||
const request = event.request;
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (url.pathname === '/' && !url.searchParams.has('ch')) {
|
||||
return Response.redirect(`https://${Config.repository}/e.xml`, 302);
|
||||
}
|
||||
|
||||
const channel = (url.searchParams.get("ch") || '').toUpperCase().replace(/-/g, '');
|
||||
const dateParam = url.searchParams.get("date");
|
||||
const date = formatDateTime(dateParam ? dateParam.replace(/\D+/g, '') : '').date;
|
||||
|
||||
if (parseInt(date.replace(/-/g, '')) >= 20240531) {
|
||||
return diypHandle(channel, date, request);
|
||||
} else {
|
||||
return makeRes(JSON.stringify({
|
||||
date,
|
||||
channel_name: channel,
|
||||
url: `https://${Config.repository}`,
|
||||
epg_data: [{ start: "00:00", end: "23:59", title: "未知节目", desc: "" }]
|
||||
}), 200, { 'content-type': 'application/json' });
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(fetchHandler(event).catch(err => makeRes(`error:\n${err.stack}`, 502)));
|
||||
});
|
||||
21
worker/radio.js
Normal file
21
worker/radio.js
Normal file
@@ -0,0 +1,21 @@
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
async function handleRequest(request) {
|
||||
const url = new URL(request.url)
|
||||
const id = url.searchParams.get('id') || '639'
|
||||
const logo = url.searchParams.has('logo')
|
||||
const d = new Date().toISOString().split('T')[0]
|
||||
const post = `startdate=&enddate=${d}&broadCastId=${id}`
|
||||
const apiUrl = 'https://ytapi.radio.cn/ytsrv/srv/interactive/program/list'
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'equipmentsource': 'WEB' },
|
||||
body: post
|
||||
})
|
||||
const data = await response.json()
|
||||
const playurl = logo ? data.broadcastLiveImg :
|
||||
(data.broadcastPlayUrlHighMp3?.includes('m3u8') ? data.broadcastPlayUrlHighMp3 :
|
||||
data.playUrlHigh || 'https://live.fanmingming.com/assets/nosignal.mp3')
|
||||
return Response.redirect(playurl, 302)
|
||||
}
|
||||
1399
worker/radio.m3u
Normal file
1399
worker/radio.m3u
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user