mirror of
https://github.com/warengroup/eximiabots-radiox.git
synced 2024-11-10 02:20:18 +00:00
commit
1d8ddc6084
@ -1,5 +1,5 @@
|
||||
DISCORD_TOKEN=
|
||||
RADIOX_STATIONSLISTURL=https://gitea.cwinfo.org/cwchristerw/radio/raw/branch/master/playlist.json
|
||||
RADIOX_STATIONSLISTURL=https://git.cwinfo.net/cwchristerw/radio/raw/branch/master/playlist.json
|
||||
DEV_MODE=false
|
||||
DEBUG_MODE=false
|
||||
STREAMER_MODE=manual
|
||||
|
2
.github/workflows/typescript-build.yml
vendored
2
.github/workflows/typescript-build.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: install node v16
|
||||
uses: actions/setup-node@v2.4.0
|
||||
uses: actions/setup-node@v2.4.1
|
||||
with:
|
||||
node-version: 16
|
||||
- name: npm install
|
||||
|
@ -1,8 +1,8 @@
|
||||
# RadioX by EximiaBots
|
||||
Internet Radio to your Discord guild
|
||||
|
||||
## [Radio Stations List](https://gitea.cwinfo.org/cwchristerw/radio)
|
||||
This bot is using Gitea repo to get radio stations from [playlist.json](https://gitea.cwinfo.org/cwchristerw/radio/raw/branch/master/playlist.json) file. List is currently maintained by Christer Warén. You can use alternative list with same format when using RADIOX_STATIONSLISTURL environment variable.
|
||||
## [Radio Stations List](https://git.cwinfo.net/cwchristerw/radio)
|
||||
This bot is using Gitea repo to get radio stations from [playlist.json](https://git.cwinfo.net/cwchristerw/radio/raw/branch/master/playlist.json) file. List is currently maintained by Christer Warén. You can use alternative list with same format when using RADIOX_STATIONSLISTURL environment variable.
|
||||
|
||||
## Docker
|
||||
1. `docker build -t warengroup/eximiabots-radiox . --pull`
|
||||
|
2427
package-lock.json
generated
2427
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eximiabots-radiox",
|
||||
"version": "0.3.11",
|
||||
"version": "0.3.12",
|
||||
"description": "Internet Radio to your Discord guild",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@ -18,31 +18,31 @@
|
||||
"url": "https://github.com/warengroup/eximiabots-radiox/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^0.6.0",
|
||||
"@discordjs/opus": "^0.6.0",
|
||||
"@discordjs/builders": "^0.8.2",
|
||||
"@discordjs/opus": "^0.7.0",
|
||||
"@discordjs/rest": "^0.1.1-canary.0",
|
||||
"@discordjs/voice": "^0.6.0",
|
||||
"discord-api-types": "^0.23.1",
|
||||
"discord.js": "^13.1.0",
|
||||
"@discordjs/voice": "^0.7.5",
|
||||
"discord-api-types": "^0.24.0",
|
||||
"discord.js": "^13.2.0",
|
||||
"dotenv": "^10.0.0",
|
||||
"libsodium-wrappers": "^0.7.9",
|
||||
"node-fetch": "^3.0.0",
|
||||
"node-fetch": "^3.1.0",
|
||||
"path": "^0.12.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.9.1",
|
||||
"@types/ws": "^7.4.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.1",
|
||||
"@typescript-eslint/parser": "^4.31.1",
|
||||
"eslint": "^7.32.0",
|
||||
"@types/node": "^16.11.10",
|
||||
"@types/ws": "^8.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"eslint": "^8.3.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"nodemon": "^2.0.12",
|
||||
"prettier": "^2.4.1",
|
||||
"nodemon": "^2.0.15",
|
||||
"prettier": "^2.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"ts-node": "^10.4.0",
|
||||
"tsc-watch": "^4.5.0",
|
||||
"typescript": "^4.4.2"
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.1",
|
||||
|
@ -41,9 +41,11 @@ module.exports = class Radio extends Map {
|
||||
if(voiceChannel.members.filter(member => !member.user.bot).size === 0) return;
|
||||
|
||||
|
||||
const sstation = await client.stations.search(state.station.name);
|
||||
const sstation = await client.stations.search(state.station.name, "direct");
|
||||
let station = sstation;
|
||||
|
||||
if(!station) return;
|
||||
|
||||
const construct = {
|
||||
textChannel: client.channels.cache.get(state.channels.text),
|
||||
voiceChannel: client.channels.cache.get(state.channels.voice),
|
||||
|
@ -17,7 +17,11 @@ module.exports = class Stations extends Array {
|
||||
if(list){
|
||||
this.length = 0;
|
||||
list.forEach(station => {
|
||||
this.push(station);
|
||||
try {
|
||||
this.push(station);
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
if(options.show){
|
||||
@ -27,6 +31,16 @@ module.exports = class Stations extends Array {
|
||||
});
|
||||
console.log("\n");
|
||||
}
|
||||
|
||||
list.forEach(async station => {
|
||||
try {
|
||||
let stationTest = await fetch(station.stream[station.stream.default]);
|
||||
if(stationTest.ok === true) return;
|
||||
this.splice(this.indexOf(station),1);
|
||||
} catch (error) {
|
||||
this.splice(this.indexOf(station),1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.logger('Stations', 'Successfully fetched list');
|
||||
@ -34,7 +48,7 @@ module.exports = class Stations extends Array {
|
||||
this.logger('Stations', 'Fetching list failed');
|
||||
console.error(error + "\n");
|
||||
|
||||
this.fetch(options);
|
||||
if(this.length == 0) this.fetch(options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,66 +60,79 @@ module.exports = class Stations extends Array {
|
||||
}
|
||||
}
|
||||
|
||||
search(key) {
|
||||
search(key, type) {
|
||||
if (this === null) return false;
|
||||
let foundStations = [];
|
||||
if (!key) return false;
|
||||
if (key == "radio") return false;
|
||||
if (!type) return false;
|
||||
|
||||
this
|
||||
.filter(
|
||||
x => x.name.toUpperCase().includes(key.toUpperCase()) || x === key
|
||||
)
|
||||
.forEach(x =>
|
||||
foundStations.push({ station: x, name: x.name, probability: 100 })
|
||||
);
|
||||
if(type == "direct"){
|
||||
let foundStation;
|
||||
this.forEach(station => {
|
||||
if(station.name != key) return false;
|
||||
foundStation = station;
|
||||
});
|
||||
|
||||
return foundStation;
|
||||
} else {
|
||||
|
||||
let foundStations = [];
|
||||
if (key == "radio") return false;
|
||||
|
||||
if (key.startsWith("radio ")) key = key.slice(6);
|
||||
const probabilityIncrement = 100 / key.split(" ").length / 2;
|
||||
for (let i = 0; i < key.split(" ").length; i++) {
|
||||
this
|
||||
.filter(
|
||||
x => x.name.toUpperCase().includes(key.split(" ")[i].toUpperCase()) || x === key
|
||||
x => x.name.toUpperCase().includes(key.toUpperCase()) || x === key
|
||||
)
|
||||
.forEach(x =>
|
||||
foundStations.push({ station: x, name: x.name, probability: probabilityIncrement })
|
||||
foundStations.push({ station: x, name: x.name, probability: 100 })
|
||||
);
|
||||
}
|
||||
if (foundStations.length === 0) return false;
|
||||
for (let i = 0; i < foundStations.length; i++) {
|
||||
for (let j = 0; j < foundStations.length; j++) {
|
||||
if (foundStations[i] === foundStations[j] && i !== j) foundStations.splice(i, 1);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < foundStations.length; i++) {
|
||||
if (foundStations[i].name.length > key.length) {
|
||||
foundStations[i].probability -=
|
||||
(foundStations[i].name.split(" ").length - key.split(" ").length) *
|
||||
(probabilityIncrement * 0.5);
|
||||
} else if (foundStations[i].name.length === key.length) {
|
||||
foundStations[i].probability += probabilityIncrement * 0.9;
|
||||
}
|
||||
|
||||
for (let j = 0; j < key.split(" ").length; j++) {
|
||||
if (!foundStations[i].name.toUpperCase().includes(key.toUpperCase().split(" ")[j])) {
|
||||
foundStations[i].probability -= probabilityIncrement * 0.5;
|
||||
if (key.startsWith("radio ")) key = key.slice(6);
|
||||
const probabilityIncrement = 100 / key.split(" ").length / 2;
|
||||
for (let i = 0; i < key.split(" ").length; i++) {
|
||||
this
|
||||
.filter(
|
||||
x => x.name.toUpperCase().includes(key.split(" ")[i].toUpperCase()) || x === key
|
||||
)
|
||||
.forEach(x =>
|
||||
foundStations.push({ station: x, name: x.name, probability: probabilityIncrement })
|
||||
);
|
||||
}
|
||||
if (foundStations.length === 0) return false;
|
||||
for (let i = 0; i < foundStations.length; i++) {
|
||||
for (let j = 0; j < foundStations.length; j++) {
|
||||
if (foundStations[i] === foundStations[j] && i !== j) foundStations.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
let highestProbabilityStation;
|
||||
for (let i = 0; i < foundStations.length; i++) {
|
||||
if (
|
||||
!highestProbabilityStation ||
|
||||
highestProbabilityStation.probability < foundStations[i].probability
|
||||
)
|
||||
highestProbabilityStation = foundStations[i];
|
||||
if (
|
||||
highestProbabilityStation &&
|
||||
highestProbabilityStation.probability === foundStations[i].probability
|
||||
) {
|
||||
highestProbabilityStation = foundStations[i].station;
|
||||
for (let i = 0; i < foundStations.length; i++) {
|
||||
if (foundStations[i].name.length > key.length) {
|
||||
foundStations[i].probability -=
|
||||
(foundStations[i].name.split(" ").length - key.split(" ").length) *
|
||||
(probabilityIncrement * 0.5);
|
||||
} else if (foundStations[i].name.length === key.length) {
|
||||
foundStations[i].probability += probabilityIncrement * 0.9;
|
||||
}
|
||||
|
||||
for (let j = 0; j < key.split(" ").length; j++) {
|
||||
if (!foundStations[i].name.toUpperCase().includes(key.toUpperCase().split(" ")[j])) {
|
||||
foundStations[i].probability -= probabilityIncrement * 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
let highestProbabilityStation;
|
||||
for (let i = 0; i < foundStations.length; i++) {
|
||||
if (
|
||||
!highestProbabilityStation ||
|
||||
highestProbabilityStation.probability < foundStations[i].probability
|
||||
)
|
||||
highestProbabilityStation = foundStations[i];
|
||||
if (
|
||||
highestProbabilityStation &&
|
||||
highestProbabilityStation.probability === foundStations[i].probability
|
||||
) {
|
||||
highestProbabilityStation = foundStations[i].station;
|
||||
}
|
||||
}
|
||||
return highestProbabilityStation;
|
||||
}
|
||||
return highestProbabilityStation;
|
||||
}
|
||||
};
|
||||
|
@ -49,12 +49,22 @@ module.exports = class {
|
||||
play(station) {
|
||||
let audioPlayer = this.map.get(station.name);
|
||||
if(!audioPlayer) {
|
||||
audioPlayer = createAudioPlayer({
|
||||
behaviors: {
|
||||
noSubscriber: NoSubscriberBehavior.Play,
|
||||
maxMissedFrames: Math.round(5000 / 20),
|
||||
},
|
||||
});
|
||||
if(this.mode == "auto"){
|
||||
audioPlayer = createAudioPlayer({
|
||||
behaviors: {
|
||||
noSubscriber: NoSubscriberBehavior.Play,
|
||||
maxMissedFrames: Math.round(5000 / 20),
|
||||
},
|
||||
});
|
||||
}
|
||||
if(this.mode == "manual"){
|
||||
audioPlayer = createAudioPlayer({
|
||||
behaviors: {
|
||||
noSubscriber: NoSubscriberBehavior.Stop,
|
||||
maxMissedFrames: Math.round(5000 / 20),
|
||||
},
|
||||
});
|
||||
}
|
||||
this.map.set(station.name, audioPlayer);
|
||||
}
|
||||
const url = station.stream[station.stream.default];
|
||||
@ -63,15 +73,12 @@ module.exports = class {
|
||||
resource.playStream
|
||||
.on("readable", () => {
|
||||
this.logger('Streamer', station.name + " / " + "Readable");
|
||||
this.map.set(station.name, audioPlayer);
|
||||
})
|
||||
.on("finish", () => {
|
||||
this.logger('Streamer', station.name + " / " + "Finished");
|
||||
this.play(station);
|
||||
})
|
||||
.on("error", error => {
|
||||
this.logger('Streamer', station.name + " / " + "Error");
|
||||
this.play(station);
|
||||
this.logger('Streamer', station.name + " / " + "Error" + "\n" + error);
|
||||
});
|
||||
|
||||
audioPlayer
|
||||
@ -80,21 +87,20 @@ module.exports = class {
|
||||
})
|
||||
.on('idle', () => {
|
||||
this.logger('Streamer', station.name + " / " + "Idle");
|
||||
audioPlayer.removeAllListeners();
|
||||
this.play(station);
|
||||
})
|
||||
.on('paused', () => {
|
||||
this.logger('Streamer', station.name + " / " + "Paused");
|
||||
this.play(station);
|
||||
})
|
||||
.on('buffering', () => {
|
||||
this.logger('Streamer', station.name + " / " + "Buffering");
|
||||
})
|
||||
.on('autopaused', () => {
|
||||
this.logger('Streamer', station.name + " / " + "AutoPaused");
|
||||
this.play(station);
|
||||
})
|
||||
.on('error', error => {
|
||||
this.logger('Streamer', station.name + " / " + "Error" + "\n" + error);
|
||||
this.play(station);
|
||||
});
|
||||
return audioPlayer;
|
||||
}
|
||||
@ -103,6 +109,7 @@ module.exports = class {
|
||||
let audioPlayer = this.map.get(station.name);
|
||||
if(audioPlayer){
|
||||
this.logger('Streamer', station.name + " / " + "Stop");
|
||||
audioPlayer.removeAllListeners();
|
||||
audioPlayer.stop();
|
||||
}
|
||||
this.map.delete(station.name);
|
||||
|
@ -84,7 +84,16 @@ module.exports = {
|
||||
content: client.messageEmojis["error"] + client.messages.tooShortSearch,
|
||||
ephemeral: true
|
||||
});
|
||||
const sstation = await client.stations.search(query, client);
|
||||
|
||||
let type = "";
|
||||
|
||||
if(interaction.values?.[0]){
|
||||
type = "direct";
|
||||
} else {
|
||||
type = "text";
|
||||
}
|
||||
|
||||
const sstation = await client.stations.search(query, type);
|
||||
if (!sstation) return interaction.reply({
|
||||
content: client.messageEmojis["error"] + client.messages.noSearchResults,
|
||||
ephemeral: true
|
||||
|
@ -6,7 +6,7 @@ module.exports = {
|
||||
token: process.env.DISCORD_TOKEN,
|
||||
|
||||
//radio stations
|
||||
stationslistUrl: process.env.RADIOX_STATIONSLISTURL || "https://gitea.cwinfo.org/cwchristerw/radio/raw/branch/master/playlist.json",
|
||||
stationslistUrl: process.env.RADIOX_STATIONSLISTURL || "https://git.cwinfo.net/cwchristerw/radio/raw/branch/master/playlist.json",
|
||||
|
||||
//support
|
||||
supportGuild: "https://discord.gg/rRA65Mn",
|
||||
|
Loading…
Reference in New Issue
Block a user