Add RadioPlay playlist support

This commit is contained in:
Christer Warén 2023-11-28 22:54:22 +02:00
parent c21082c67b
commit 2a7dca38f2
6 changed files with 114 additions and 55 deletions

View File

@ -8,9 +8,10 @@ export interface station {
[key: string]: string [key: string]: string
}, },
playlist?: { playlist?: {
type: "supla" | "yle", type: "radioplay" | "supla" | "yle",
address: string | string address: string | string
} }
track?: string;
} }
export default class Stations extends Array { export default class Stations extends Array {

View File

@ -1,10 +1,13 @@
import { ButtonInteraction, ChatInputCommandInteraction, EmbedBuilder, StringSelectMenuInteraction } from "discord.js"; import { ApplicationCommandOptionType, ButtonInteraction, ChatInputCommandInteraction, EmbedBuilder, StringSelectMenuInteraction } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
import { station } from "../classes/Stations"; import { station } from "../classes/Stations";
export default { export default {
name: 'list', name: 'list',
description: 'List radio stations', description: 'List stations',
options: [
{ type: ApplicationCommandOptionType.String, name: "query", description: "Select list", choices: [{"name": "1", "value": "1"},{"name": "2", "value": "2"}], required: false}
],
category: 'radio', category: 'radio',
execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) { execute(interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) {
@ -15,6 +18,20 @@ export default {
}); });
} }
if(!interaction.guild) return;
let query: string | null = null;
if(interaction.isChatInputCommand()){
query = interaction.options?.getString("query");
}
if(interaction.isStringSelectMenu()){
query = interaction.values?.[0];
}
if(!query) query = "1";
if(!client.stations) { if(!client.stations) {
return interaction.reply({ return interaction.reply({
content: client.messages.emojis["error"] + client.messages.replace(client.messages.errorToGetPlaylist, { content: client.messages.emojis["error"] + client.messages.replace(client.messages.errorToGetPlaylist, {
@ -24,10 +41,10 @@ export default {
}); });
} }
const radio = client.radio?.get(interaction.guild?.id); const radio = client.radio?.get(interaction.guild.id);
if(radio && !client.config.maintenanceMode){ if(radio && !client.config.maintenanceMode){
client.funcs.listStations(client, interaction); client.funcs.listStations(client, interaction, query);
} else { } else {
let stations = `${client.stations.map((s: station) => `**#** ${s.name}`).join('\n')}` let stations = `${client.stations.map((s: station) => `**#** ${s.name}`).join('\n')}`
const hashs = stations.split('**#**').length; const hashs = stations.split('**#**').length;

View File

@ -183,7 +183,7 @@ export default {
client.user?.setStatus('idle'); client.user?.setStatus('idle');
client.radio?.save(client); client.radio?.save(client);
setInterval(() => { let timer : NodeJS.Timeout = setInterval(() => {
if(client.radio?.size == 0 && client.config.streamerMode == "manual" && client.config.maintenanceMode){ if(client.radio?.size == 0 && client.config.streamerMode == "manual" && client.config.maintenanceMode){
client.streamer?.leave(client); client.streamer?.leave(client);
client.streamer = new Streamer(); client.streamer = new Streamer();
@ -195,9 +195,9 @@ export default {
} }
if(!client.config.maintenanceMode){ if(!client.config.maintenanceMode){
clearInterval(undefined); clearInterval(timer);
} }
}, 500); }, 1000);
break; break;
case "11": case "11":
@ -207,7 +207,7 @@ export default {
client.user?.setStatus('idle'); client.user?.setStatus('idle');
client.radio?.save(client); client.radio?.save(client);
setInterval(() => { let timer2 : NodeJS.Timeout = setInterval(() => {
if(client.radio?.size == 0 && client.config.streamerMode == "auto" && client.config.maintenanceMode){ if(client.radio?.size == 0 && client.config.streamerMode == "auto" && client.config.maintenanceMode){
client.streamer?.leave(client); client.streamer?.leave(client);
client.streamer = new Streamer(); client.streamer = new Streamer();
@ -219,9 +219,9 @@ export default {
} }
if(!client.config.maintenanceMode){ if(!client.config.maintenanceMode){
clearInterval(undefined); clearInterval(timer2);
} }
}, 500); }, 1000);
break; break;
default: default:

View File

@ -13,6 +13,8 @@ export default {
category: "radio", category: "radio",
async execute(interaction: ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) { async execute(interaction: ChatInputCommandInteraction | StringSelectMenuInteraction, client: RadioClient) {
if(!interaction.guild) return;
if(client.config.maintenanceMode){ if(client.config.maintenanceMode){
return interaction.reply({ return interaction.reply({
content: client.messages.emojis["error"] + client.messages.maintenance, content: client.messages.emojis["error"] + client.messages.maintenance,
@ -40,10 +42,10 @@ export default {
} }
if(!query){ if(!query){
return client.funcs.listStations(client, interaction); return client.funcs.listStations(client, interaction, "1");
} }
const radio = client.radio?.get(interaction.guild?.id); const radio = client.radio?.get(interaction.guild.id);
if(!(interaction.member instanceof GuildMember)) return; if(!(interaction.member instanceof GuildMember)) return;
const voiceChannel = interaction.member?.voice.channel; const voiceChannel = interaction.member?.voice.channel;

View File

@ -1,11 +1,12 @@
import { ActionRowBuilder, ButtonInteraction, ChatInputCommandInteraction, SelectMenuComponentOptionData, StringSelectMenuBuilder, StringSelectMenuInteraction } from "discord.js"; import { ActionRowBuilder, ButtonInteraction, ChatInputCommandInteraction, SelectMenuComponentOptionData, StringSelectMenuBuilder, StringSelectMenuInteraction } from "discord.js";
import RadioClient from "../../Client"; import RadioClient from "../../Client";
export default function listStations(client: RadioClient, interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction){ export default function listStations(client: RadioClient, interaction: ButtonInteraction | ChatInputCommandInteraction | StringSelectMenuInteraction, offset: string){
if(!client.stations) return; if(!client.stations) return;
let options : SelectMenuComponentOptionData[] = new Array(); let options : SelectMenuComponentOptionData[] = new Array();
for (const station of client.stations){ for (const station of client.stations){
options.push({ options.push({
label: station.name, label: station.name,
@ -14,6 +15,17 @@ export default function listStations(client: RadioClient, interaction: ButtonInt
}); });
} }
switch(offset){
case "1":
options = options.slice(0,Math.round(options.length/2));
break;
case "2":
options = options.slice(Math.round(options.length/2),options.length-1);
break;
default:
options = options.slice(0,Math.round(options.length/2));
}
const menu = new ActionRowBuilder<StringSelectMenuBuilder>() const menu = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents( .addComponents(
new StringSelectMenuBuilder() new StringSelectMenuBuilder()

View File

@ -6,30 +6,43 @@ export default async function play(client: RadioClient, interaction: ChatInputCo
if(!guild) return; if(!guild) return;
const radio = client.radio?.get(guild.id); const radio = client.radio?.get(guild.id);
if(!radio) return;
const audioPlayer = client.streamer?.listen(station); const audioPlayer = client.streamer?.listen(station);
radio.connection.subscribe(audioPlayer); if(!audioPlayer) return;
radio.connection?.subscribe(audioPlayer);
client.funcs.logger('Radio', guild.id + " / " + "Play" + " / " + radio.station.name); client.funcs.logger('Radio', guild.id + " / " + "Play" + " / " + radio.station.name);
try { if(radio.station.playlist){
if(radio.station?.playlist?.type == "supla" || radio.station?.playlist?.type == "yle"){ if(radio.station.playlist.type == "radioplay" || radio.station.playlist.type == "supla" || radio.station.playlist.type == "yle"){
let playlist: any = await fetch(radio.station.playlist.address) let playlist: any = await fetch(radio.station.playlist.address)
.then((response: Response) => response.json()) .then((response: Response) => response.json())
.catch(error => { .catch(error => {
}); });
switch(radio.station?.playlist.type){ radio.station.track = "-";
if(playlist){
switch(radio.station.playlist.type){
case "radioplay":
if(playlist[0] && playlist[0].stationNowPlaying && playlist[0].stationNowPlaying.nowPlayingArtist && playlist[0].stationNowPlaying.nowPlayingTrack){
radio.station.track = "__" + playlist[0].stationNowPlaying.nowPlayingArtist + "__" + "\n" + playlist[0].stationNowPlaying.nowPlayingTrack;
}
break;
case "supla": case "supla":
radio.station.track = "__" + playlist.items[0]?.artist + "__" + "\n" + playlist.items[0]?.song; if(playlist.items && playlist.items[0] && playlist.items[0].artist && playlist.items[0].song){
radio.station.track = "__" + playlist.items[0].artist + "__" + "\n" + playlist.items[0].song;
}
break; break;
case "yle": case "yle":
radio.station.track = "-"; if(playlist.data && playlist.data.performer && playlist.data.title){
radio.station.track = "__" + playlist.data.performer + "__" + "\n" + playlist.data.title;
}
break; break;
default: default:
radio.station.track = "-"; radio.station.track = "-";
} }
} }
} catch(TypeError) { }
} }
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
@ -95,47 +108,61 @@ export default async function play(client: RadioClient, interaction: ChatInputCo
); );
if(!radio.message){ if(!radio.message){
radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }); radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }) ?? null;
} else { } else {
if(radio.textChannel.id == radio.message.channel.id){ if(radio.textChannel?.id == radio.message.channel.id){
radio.message.edit({ embeds: [embed], components: [buttons] }); radio.message.edit({ embeds: [embed], components: [buttons] });
} else { } else {
radio.message?.delete(); radio.message?.delete();
radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }); radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }) ?? null;
} }
} }
setInterval(async function(){ const oldRadio = {...radio};
let timer : NodeJS.Timeout = setInterval(async function(){
const radio = client.radio?.get(guild.id); const radio = client.radio?.get(guild.id);
let changed = false;
try { if(!radio || !oldRadio || radio.station.name != oldRadio.station.name) {
if(radio.station?.playlist?.type == "supla" || radio.station?.playlist?.type == "yle"){ return clearInterval(timer);
}
if(radio.station.playlist){
if(radio.station.playlist.type == "radioplay" || radio.station.playlist.type == "supla" || radio.station.playlist.type == "yle"){
let playlist: any = await fetch(radio.station.playlist.address) let playlist: any = await fetch(radio.station.playlist.address)
.then((response: Response) => response.json()) .then((response: Response) => response.json())
.catch(error => { .catch(error => {
}); });
switch(radio.station?.playlist.type){ radio.station.track = "-";
if(playlist){
switch(radio.station.playlist?.type){
case "radioplay":
if(playlist[0] && playlist[0].stationNowPlaying && playlist[0].stationNowPlaying.nowPlayingArtist && playlist[0].stationNowPlaying.nowPlayingTrack){
radio.station.track = "__" + playlist[0].stationNowPlaying.nowPlayingArtist + "__" + "\n" + playlist[0].stationNowPlaying.nowPlayingTrack;
}
break;
case "supla": case "supla":
if(radio.station.track != "__" + playlist.items[0]?.artist + "__" + "\n" + playlist.items[0].song){ if(playlist.items && playlist.items[0] && playlist.items[0].artist && playlist.items[0].song){
radio.station.track = "__" + playlist.items[0].artist + "__" + "\n" + playlist.items[0].song; radio.station.track = "__" + playlist.items[0].artist + "__" + "\n" + playlist.items[0].song;
} }
break; break;
case "yle": case "yle":
radio.station.track = "-"; if(playlist.data && playlist.data.performer && playlist.data.title){
radio.station.track = "__" + playlist.data.performer + "__" + "\n" + playlist.data.title;
}
break; break;
default: default:
radio.station.track = "-"; radio.station.track = "-";
} }
} }
} catch(TypeError) { }
} }
let date = new Date(); let date = new Date();
radio.currentTime = date.getTime(); radio.currentTime = date.getTime();
radio.playTime = parseInt(radio.currentTime)-parseInt(radio.startTime); radio.playTime = radio.currentTime - radio.startTime;
const completed = (radio.playTime); const completed = (radio.playTime);
const embed = new EmbedBuilder() const embed = new EmbedBuilder()
@ -169,16 +196,16 @@ export default async function play(client: RadioClient, interaction: ChatInputCo
if(!radio.message){ if(!radio.message){
radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }); radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }) ?? null;
} else { } else {
if(radio.textChannel.id == radio.message.channel.id){ if(radio.textChannel?.id == radio.message.channel.id){
radio.message.edit({ embeds: [embed], components: [buttons] }); radio.message?.edit({ embeds: [embed], components: [buttons] });
} else { } else {
radio.message?.delete(); radio.message?.delete();
radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }); radio.message = await radio.textChannel?.send({ embeds: [embed], components: [buttons] }) ?? null;
} }
} }
},15000); },2500);
interaction?.reply({ interaction?.reply({
content: client.messages.emojis["play"] + client.messages.replace(client.messages.play, { content: client.messages.emojis["play"] + client.messages.replace(client.messages.play, {