music: attempt 1 at porting to djs voice and such

This commit is contained in:
Cynthia Foxwell 2022-12-10 14:49:25 -07:00
parent cd08f98b74
commit 000bd0bb45
3 changed files with 67 additions and 96 deletions

View file

@ -24,9 +24,9 @@
"murmurhash": "^2.0.0", "murmurhash": "^2.0.0",
"node-ffprobe": "^3.0.0", "node-ffprobe": "^3.0.0",
"oceanic.js": "^1.1.2", "oceanic.js": "^1.1.2",
"play-dl": "^1.9.6",
"sharp": "^0.28.3", "sharp": "^0.28.3",
"sqlite3": "^5.0.2", "sqlite3": "^5.0.2"
"ytdl-core": "github:GreepTheSheep/node-ytdl-core"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^7.26.0", "eslint": "^7.26.0",

View file

@ -9,10 +9,10 @@ specifiers:
murmurhash: ^2.0.0 murmurhash: ^2.0.0
node-ffprobe: ^3.0.0 node-ffprobe: ^3.0.0
oceanic.js: ^1.1.2 oceanic.js: ^1.1.2
play-dl: ^1.9.6
prettier: ^2.3.0 prettier: ^2.3.0
sharp: ^0.28.3 sharp: ^0.28.3
sqlite3: ^5.0.2 sqlite3: ^5.0.2
ytdl-core: github:GreepTheSheep/node-ytdl-core
dependencies: dependencies:
'@ctrl/tinycolor': 3.4.1 '@ctrl/tinycolor': 3.4.1
@ -22,9 +22,9 @@ dependencies:
murmurhash: 2.0.0 murmurhash: 2.0.0
node-ffprobe: 3.0.0 node-ffprobe: 3.0.0
oceanic.js: 1.1.2 oceanic.js: 1.1.2
play-dl: 1.9.6
sharp: 0.28.3 sharp: 0.28.3
sqlite3: 5.0.2 sqlite3: 5.0.2
ytdl-core: github.com/GreepTheSheep/node-ytdl-core/17a77cbe7f3a9670d6536fba7cb3f574c6da596a
devDependencies: devDependencies:
eslint: 7.26.0 eslint: 7.26.0
@ -1479,14 +1479,6 @@ packages:
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
/m3u8stream/0.8.6:
resolution: {integrity: sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==}
engines: {node: '>=12'}
dependencies:
miniget: 4.2.2
sax: 1.2.4
dev: false
/mime-db/1.48.0: /mime-db/1.48.0:
resolution: {integrity: sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==} resolution: {integrity: sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -1518,11 +1510,6 @@ packages:
dom-walk: 0.1.2 dom-walk: 0.1.2
dev: false dev: false
/miniget/4.2.2:
resolution: {integrity: sha512-a7voNL1N5lDMxvTMExOkg+Fq89jM2vY8pAi9ZEWzZtfNmdfP6RXkvUtFnCAXoCv2T9k1v/fUJVaAEuepGcvLYA==}
engines: {node: '>=12'}
dev: false
/minimatch/3.0.4: /minimatch/3.0.4:
resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==}
dependencies: dependencies:
@ -1816,6 +1803,17 @@ packages:
pngjs: 3.4.0 pngjs: 3.4.0
dev: false dev: false
/play-audio/0.5.2:
resolution: {integrity: sha512-ZAqHUKkQLix2Iga7pPbsf1LpUoBjcpwU93F1l3qBIfxYddQLhxS6GKmS0d3jV8kSVaUbr6NnOEcEMFvuX93SWQ==}
dev: false
/play-dl/1.9.6:
resolution: {integrity: sha512-JW44bQbME9fNfGhGXQ/rdcsHr4BfgJabVlSgpS9QY/NscfprFH1asv+q9atrZThP3+hHIpgtFNABccg9rFWlwg==}
engines: {node: '>=16.0.0'}
dependencies:
play-audio: 0.5.2
dev: false
/pngjs/3.4.0: /pngjs/3.4.0:
resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==}
engines: {node: '>=4.0.0'} engines: {node: '>=4.0.0'}
@ -2475,14 +2473,3 @@ packages:
jimp: 0.16.1 jimp: 0.16.1
node-fetch: 2.6.1 node-fetch: 2.6.1
dev: false dev: false
github.com/GreepTheSheep/node-ytdl-core/17a77cbe7f3a9670d6536fba7cb3f574c6da596a:
resolution: {tarball: https://codeload.github.com/GreepTheSheep/node-ytdl-core/tar.gz/17a77cbe7f3a9670d6536fba7cb3f574c6da596a}
name: ytdl-core
version: 0.0.0-development
engines: {node: '>=12'}
dependencies:
m3u8stream: 0.8.6
miniget: 4.2.2
sax: 1.2.4
dev: false

View file

@ -1,5 +1,11 @@
const ytdl = require("ytdl-core");
const {Collection} = require("oceanic.js"); const {Collection} = require("oceanic.js");
const {
AudioPlayerStatus,
createAudioPlayer,
createAudioResource,
} = require("@discordjs/voice");
const playdl = require("play-dl");
const ffprobe = require("node-ffprobe"); const ffprobe = require("node-ffprobe");
const Command = require("../lib/command.js"); const Command = require("../lib/command.js");
@ -132,13 +138,28 @@ async function processPlaylist(
} }
async function createVoiceConnection(guild_id, voice_id, text_id) { async function createVoiceConnection(guild_id, voice_id, text_id) {
const connection = await hf.bot.joinVoiceChannel(voice_id); const state = {};
connection._music_text_id = text_id;
connection._music_queue = [];
connection._music_eventEnd = async function () { const guild = hf.bot.guilds.get(guild_id);
if (connection._music_queue.length > 0) { state.connection = hf.bot.joinVoiceChannel({
const next = connection._music_queue.splice(0, 1)[0]; channelID: voice_id,
guildID: guild_id,
selfDeaf: true,
selfMute: false,
voiceAdapterCreator: guild.voiceAdapterCreator,
});
state.text_id = text_id;
state.queue = [];
state.player = createAudioPlayer();
state.connection.subscribe(state.player);
state.player.on("stateChange", (oldState, newState) => {
state.status = newState.status;
});
state.onEnd = async function () {
if (state.queue.length > 0) {
const next = state.queue.splice(0, 1)[0];
await enqueue({ await enqueue({
guild_id, guild_id,
voice_id, voice_id,
@ -146,11 +167,11 @@ async function createVoiceConnection(guild_id, voice_id, text_id) {
url: next.url, url: next.url,
type: next.type, type: next.type,
addedBy: next.addedBy, addedBy: next.addedBy,
speex: next.speex,
}); });
} else { } else {
await connection.disconnect(); await state.player.stop();
if (!connection._music_leave) { await state.connection.disconnect();
if (!state.__leave) {
await hf.bot.guilds await hf.bot.guilds
.get(guild_id) .get(guild_id)
.channels.get(text_id) .channels.get(text_id)
@ -158,15 +179,14 @@ async function createVoiceConnection(guild_id, voice_id, text_id) {
":musical_note: Queue is empty, leaving voice channel." ":musical_note: Queue is empty, leaving voice channel."
); );
} }
connection.off("end", connection._music_eventEnd); state.player.off(AudioPlayerStatus.Idle, state.onEnd);
voiceStorage.delete(guild_id); voiceStorage.delete(guild_id);
} }
}; };
connection.on("end", connection._music_eventEnd); state.player.on(AudioPlayerStatus.Idle, state.End);
voiceStorage.set(guild_id, state);
voiceStorage.set(guild_id, connection); return state;
return connection;
} }
async function enqueue({ async function enqueue({
@ -178,7 +198,6 @@ async function enqueue({
addedBy, addedBy,
suppress = false, suppress = false,
queueNext = false, queueNext = false,
speex = false,
}) { }) {
if (!url) return; if (!url) return;
@ -210,7 +229,7 @@ async function enqueue({
].url ].url
.replace("vi_webp", "vi") .replace("vi_webp", "vi")
.replace(".webp", ".jpg"); .replace(".webp", ".jpg");
media = ytdl(url, { media = await playdl.stream(url, {
quality: "highestaudio", quality: "highestaudio",
filter: "audioonly", filter: "audioonly",
highWaterMark: 1 << 25, highWaterMark: 1 << 25,
@ -234,7 +253,7 @@ async function enqueue({
title = info.title; title = info.title;
length = info.duration; length = info.duration;
thumbnail = info.artwork_url; thumbnail = info.artwork_url;
media = streamUrl; media = await playdl.stream(streamUrl);
} else if (type == "file") { } else if (type == "file") {
title = url; title = url;
let info; let info;
@ -260,10 +279,10 @@ async function enqueue({
} }
length = info.duration ? Math.floor(info.duration) * 1000 : 0; length = info.duration ? Math.floor(info.duration) * 1000 : 0;
media = url; media = await playdl.stream(url);
} }
if (connection.playing) { if (connection.status != AudioPlayerStatus.Idle) {
const queueItem = { const queueItem = {
url, url,
type, type,
@ -271,14 +290,13 @@ async function enqueue({
length, length,
addedBy, addedBy,
stream, stream,
speex,
id: Math.random().toString(16).substring(2), id: Math.random().toString(16).substring(2),
}; };
if (queueNext === true) { if (queueNext === true) {
connection._music_queue.splice(0, 0, queueItem); connection.queue.splice(0, 0, queueItem);
} else { } else {
connection._music_queue.push(queueItem); connection.queue.push(queueItem);
} }
if (suppress === false) { if (suppress === false) {
@ -325,12 +343,8 @@ async function enqueue({
return; return;
} }
await connection.play(media, { const resource = createAudioResource(media.stream, {inputType: media.type});
inlineVolume: true, connection.player.play(resource);
voiceDataTimeout: -1,
samplingRate: speex ? 8000 : 48000,
encoderArgs: speex ? ["-acodec", "speex", "-b:a", "8000"] : null,
});
textChannel.createMessage({ textChannel.createMessage({
embeds: [ embeds: [
@ -409,10 +423,14 @@ command.addAlias("m");
command.category = "misc"; command.category = "misc";
command.helpText = "Music"; command.helpText = "Music";
command.usage = "help"; command.usage = "help";
command.callback = async function (msg, line) { command.callback = async function (
msg,
line,
[subcommand, ...args],
{shuffle = false, limit = -1, offset = 0, next = false}
) {
if (!msg.guildID) return "This command can only be used in guilds."; if (!msg.guildID) return "This command can only be used in guilds.";
const [subcommand, ...args] = line.split(" ");
let argStr = args.join(" "); let argStr = args.join(" ");
switch (subcommand) { switch (subcommand) {
@ -426,36 +444,6 @@ command.callback = async function (msg, line) {
} }
} }
let shuffle = false;
if (argStr.includes("--shuffle")) {
shuffle = true;
argStr = argStr.replace("--shuffle", "").trim();
}
let limit = -1;
if (argStr.match(/--limit=(\d+)/)) {
limit = argStr.match(/--limit=(\d+)/)[1];
argStr = argStr.replace(/--limit=(\d+)/, "").trim();
}
let offset = 0;
if (argStr.match(/--offset=(\d+)/)) {
offset = argStr.match(/--offset=(\d+)/)[1];
argStr = argStr.replace(/--offset=(\d+)/, "").trim();
}
let queueNext = false;
if (argStr.match(/--next/)) {
queueNext = true;
argStr = argStr.replace(/--next/, "").trim();
}
let speex = false;
if (argStr.match(/--speex/)) {
speex = true;
argStr = argStr.replace(/--speex/, "").trim();
}
let type; let type;
let playlist = false; let playlist = false;
@ -531,7 +519,6 @@ command.callback = async function (msg, line) {
type, type,
addedBy: msg.author.id, addedBy: msg.author.id,
supress: true, supress: true,
speex,
}); });
} }
await statusMessage.edit({ await statusMessage.edit({
@ -551,8 +538,7 @@ command.callback = async function (msg, line) {
url: argStr, url: argStr,
type, type,
addedBy: msg.author.id, addedBy: msg.author.id,
queueNext, queueNext: next,
speex,
}); });
} }
} else { } else {
@ -571,8 +557,7 @@ command.callback = async function (msg, line) {
url: argStr, url: argStr,
type: "file", type: "file",
addedBy: msg.author.id, addedBy: msg.author.id,
queueNext, queueNext: next,
speex,
}); });
} else { } else {
return "Unsupported content type."; return "Unsupported content type.";
@ -587,8 +572,7 @@ command.callback = async function (msg, line) {
url, url,
type: "yt", type: "yt",
addedBy: msg.author.id, addedBy: msg.author.id,
queueNext, queueNext: next,
speex,
}); });
} else { } else {
return url; return url;