rsshub
Version:
Make RSS Great Again!
121 lines (118 loc) • 4.26 kB
JavaScript
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs";
import { t as config } from "./config-C37vj7VH.mjs";
import { t as ViewType } from "./types-D84BRIt4.mjs";
import "./dist-BInvbO1W.mjs";
import "./logger-Czu8UMNd.mjs";
import "./ofetch-BIyrKU3Y.mjs";
import { t as parseDate } from "./parse-date-BrP7mxXf.mjs";
import { t as md5 } from "./md5-C8GRvctM.mjs";
import { t as cache_default } from "./cache-Bo__VnGm.mjs";
import "./helpers-DxBp0Pty.mjs";
import { t as art } from "./render-BQo6B4tL.mjs";
import { t as got_default } from "./got-KxxWdaxq.mjs";
import path from "node:path";
//#region lib/routes/tingtingfm/utils.ts
init_esm_shims();
const SALT = "1Ftjv0bfpVmqbE38";
const getClientVal = (length) => {
let result = "";
const randomChar = () => {
const random = Math.floor(62 * Math.random());
if (random < 10) return random;
else if (random < 36) return String.fromCharCode(random + 55);
else return String.fromCharCode(random + 61);
};
while (result.length < length) result += randomChar();
return `h5_${result}`;
};
const sign = (params) => {
const searchParams = new URLSearchParams(params);
searchParams.sort();
return md5(`${searchParams.toString()}_${SALT}`);
};
//#endregion
//#region lib/routes/tingtingfm/program.ts
const route = {
path: "/program/:programId",
categories: ["multimedia"],
view: ViewType.Audios,
example: "/tingtingfm/program/M7VJv6Jj4R",
parameters: { programId: "节目 ID,可以在 URL 中找到" },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: true,
supportScihub: false
},
radar: [{ source: ["mobile.tingtingfm.com/v3/program/:programId"] }],
name: "节目",
maintainers: ["TonyRL"],
handler
};
async function handler(ctx) {
const programId = ctx.req.param("programId");
const apiBaseUrl = "https://api-v3.tingtingfm.com";
const mobileBaseUrl = "https://mobile.tingtingfm.com";
const params = {
version: "h5_5.16",
client: getClientVal(30),
h_program_id: programId
};
const radioInfo = await cache_default.tryGet(`tingtingfm:program:${programId}`, async () => {
const { data: response } = await got_default.post(`${apiBaseUrl}//broadcast/get_program_v3_8`, { searchParams: {
...params,
api_sign: sign(params)
} });
if (response.errno !== 0) throw new Error(response.error);
return response.data.info;
});
const latestAudio = await cache_default.tryGet(`tingtingfm:audio_list:${programId}`, async () => {
const { data: response } = await got_default.post(`${apiBaseUrl}//broadcast/get_program_audio_list`, { searchParams: {
...params,
api_sign: sign(params)
} });
if (response.errno !== 0) throw new Error(response.error);
return response.data[0];
}, config.cache.routeExpire, false);
const { radioCover, list } = await cache_default.tryGet(`tingtingfm:play_audio:${programId}`, async () => {
const playAudioParams = {
...Object.fromEntries(Object.entries(params).filter(([key]) => key !== "h_program_id")),
type: "",
sort: "-1",
audio_id: latestAudio.h_audio_id
};
const { data: response } = await got_default.post(`${apiBaseUrl}//albumaudio/play_audio`, { searchParams: {
...playAudioParams,
api_sign: sign(playAudioParams)
} });
if (response.errno !== 0) throw new Error(response.error);
return {
radioCover: response.data.info.radio_cover,
list: response.data.list
};
}, config.cache.routeExpire, false);
const items = list.map((audio) => ({
title: audio.title,
link: `${mobileBaseUrl}/v3/vod/2/${audio.h_audio_id}`,
description: art(path.join(__dirname, "templates/audio-a76b0dc2.art"), { url: audio.play_url }),
pubDate: parseDate(audio.add_time, "X"),
itunes_item_image: radioCover,
itunes_duration: audio.duration,
enclosure_url: audio.play_url,
enclosure_type: "audio/x-m4a"
}));
return {
title: `${radioInfo.title} - ${radioInfo.belong_radio}${radioInfo.belong_fm}`,
description: radioInfo.description,
link: `${mobileBaseUrl}/v3/program/${programId}`,
image: radioInfo.cover.split("?x-oss")[0],
itunes_author: radioInfo.anchor.join(", "),
itunes_category: radioInfo.category,
itunes_explicit: false,
item: items
};
}
//#endregion
export { route };