RSSHub/lib/v2/tingtingfm/program.js

105 lines
3.4 KiB
JavaScript

const got = require('@/utils/got');
const config = require('@/config').value;
const { art } = require('@/utils/render');
const { join } = require('path');
const { parseDate } = require('@/utils/parse-date');
const { getClientVal, sign } = require('./utils');
module.exports = async (ctx) => {
const { programId } = ctx.params;
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 ctx.cache.tryGet(`tingtingfm:program:${programId}`, async () => {
// the double slash here and below is not a typo
const { data: response } = await got.post(`${apiBaseUrl}//broadcast/get_program_v3_8`, {
searchParams: {
...params,
api_sign: sign(params),
},
});
if (response.errno !== 0) {
throw Error(response.error);
}
return response.data.info;
});
const latestAudio = await ctx.cache.tryGet(
`tingtingfm:audio_list:${programId}`,
async () => {
const { data: response } = await got.post(`${apiBaseUrl}//broadcast/get_program_audio_list`, {
searchParams: {
...params,
api_sign: sign(params),
},
});
if (response.errno !== 0) {
throw Error(response.error);
}
return response.data[0];
},
config.cache.routeExpire,
false
);
const audioList = await ctx.cache.tryGet(
`tingtingfm:play_audio:${programId}`,
async () => {
const playAudioParams = {
// remove h_program_id from params
...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.post(`${apiBaseUrl}//albumaudio/play_audio`, {
searchParams: {
...playAudioParams,
api_sign: sign(playAudioParams),
},
});
if (response.errno !== 0) {
throw Error(response.error);
}
return { radioCover: response.data.info.radio_cover, list: response.data.list };
},
config.cache.routeExpire,
false
);
const { radioCover, list } = audioList;
const items = list.map((audio) => ({
title: audio.title,
link: `${mobileBaseUrl}/v3/vod/2/${audio.h_audio_id}`,
description: art(join(__dirname, 'templates/audio.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',
}));
ctx.state.data = {
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,
};
};