From f00cbb2091baed3a3f6ec18217c4480a36ecbc1d Mon Sep 17 00:00:00 2001 From: ReaperOfVeriod Date: Sat, 31 Jan 2026 02:50:20 +0100 Subject: [PATCH] initial music stuff --- .dockerignore | 2 + commands/music/play.js | 78 ++++++++ compose.yaml | 9 + dockerfile | 16 ++ events/interactionCreate.js | 64 +++---- main.js | 7 +- package-lock.json | 365 +++++++++++++++++++++++++++++++++++- package.json | 5 +- temp.js | 24 +++ 9 files changed, 535 insertions(+), 35 deletions(-) create mode 100644 .dockerignore create mode 100644 commands/music/play.js create mode 100644 compose.yaml create mode 100644 dockerfile create mode 100644 temp.js diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fea6bc6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +node_modules +Dockerfile \ No newline at end of file diff --git a/commands/music/play.js b/commands/music/play.js new file mode 100644 index 0000000..b265a28 --- /dev/null +++ b/commands/music/play.js @@ -0,0 +1,78 @@ +const { SlashCommandBuilder } = require('discord.js'); +const { + joinVoiceChannel, + createAudioPlayer, + createAudioResource, + StreamType, +} = require('@discordjs/voice'); +const { spawn } = require('node:child_process'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('play') + .setDescription('Proof-of-life music command'), + + async execute(interaction) { + const voiceChannel = interaction.member.voice.channel; + if (!voiceChannel) { + return interaction.reply({ + content: '❌ You need to join a voice channel first!', + ephemeral: true, + }); + } + + // 1️⃣ Defer reply immediately to prevent 3s timeout + await interaction.deferReply(); + + try { + // 2️⃣ Spawn yt-dlp → ffmpeg → Discord + const ytdlp = spawn('yt-dlp', [ + '-f', 'bestaudio', + '-o', '-', + 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', // test URL + ]); + + const ffmpeg = spawn('ffmpeg', [ + '-i', 'pipe:0', + '-f', 's16le', // raw PCM for Discord + '-ar', '48000', // sample rate + '-ac', '2', // stereo + 'pipe:1', + ]); + + ytdlp.stdout.pipe(ffmpeg.stdin); + + const resource = createAudioResource(ffmpeg.stdout, { + inputType: StreamType.Raw, + }); + + const player = createAudioPlayer(); + player.play(resource); + + const connection = joinVoiceChannel({ + channelId: voiceChannel.id, + guildId: interaction.guild.id, + adapterCreator: interaction.guild.voiceAdapterCreator, + }); + + connection.subscribe(player); + + // 3️⃣ Edit deferred reply + await interaction.editReply('▶️ Now playing: Rick Astley!'); + + // Optional logging + ytdlp.stderr.on('data', (data) => console.error('yt-dlp:', data.toString())); + ffmpeg.stderr.on('data', (data) => console.error('ffmpeg:', data.toString())); + player.on('error', (err) => console.error('AudioPlayer error:', err)); + } catch (err) { + console.error(err); + + // 4️⃣ Safe error reply + if (interaction.deferred || interaction.replied) { + await interaction.editReply('❌ Failed to play audio!'); + } else { + await interaction.reply('❌ Failed to play audio!'); + } + } + }, +}; \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..da4cb17 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,9 @@ +services: + app: + container_name: reapersbeepboop + build: + context: . + dockerfile: Dockerfile + volumes: + - .:/opt/app + - /opt/app/node_modules \ No newline at end of file diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..2ee0a2b --- /dev/null +++ b/dockerfile @@ -0,0 +1,16 @@ +FROM node:24-alpine + +# Install system dependencies +RUN apk add --no-cache \ + ffmpeg \ + python3 \ + yt-dlp + +WORKDIR /app + +COPY package*.json ./ +RUN npm install --omit=dev + +COPY . . + +CMD ["node", "main.js"] \ No newline at end of file diff --git a/events/interactionCreate.js b/events/interactionCreate.js index 4e75cc4..3bde807 100644 --- a/events/interactionCreate.js +++ b/events/interactionCreate.js @@ -1,34 +1,38 @@ -const { Events, MessageFlags, Collection, GuildMember, PermissionsBitField } = require('discord.js'); +const { Events, MessageFlags, Collection } = require('discord.js'); + +async function safeReply(interaction, content) { + if (interaction.replied || interaction.deferred) { + await interaction.editReply(content).catch(() => { + interaction.followUp({ content, flags: MessageFlags.Ephemeral }).catch(console.error); + }); + } else { + await interaction.reply({ content, flags: MessageFlags.Ephemeral }).catch(console.error); + } +} module.exports = { name: Events.InteractionCreate, async execute(interaction) { if (interaction.isChatInputCommand()) { - const command = interaction.client.commands.get(interaction.commandName); - - if (!command) { - console.error(`No command matching ${interaction.commandName} was found.`); - return; - } + if (!command) return console.error(`No command matching ${interaction.commandName} found.`); const { cooldowns } = interaction.client; - - if (!cooldowns.has(command.data.name)) { - cooldowns.set(command.data.name, new Collection()); - } + if (!cooldowns.has(command.data.name)) cooldowns.set(command.data.name, new Collection()); const now = Date.now(); const timestamps = cooldowns.get(command.data.name); - const defaultCooldownDuration = 3; - const cooldownAmount = (command.cooldown ?? defaultCooldownDuration) * 1000; + const defaultCooldown = 3; + const cooldownAmount = (command.cooldown ?? defaultCooldown) * 1000; if (timestamps.has(interaction.user.id)) { const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount; - if (now < expirationTime) { - const expiredTimestamp = Math.round(expirationTime / 1000); - return interaction.reply({ content: `Please wait, you are on a cooldown for \`${command.data.name}\`. You can use it again .`, flags: MessageFlags.Ephemeral }); + const expired = Math.round(expirationTime / 1000); + return interaction.reply({ + content: `Please wait, you are on cooldown for \`${command.data.name}\`. Try again .`, + flags: MessageFlags.Ephemeral, + }); } } @@ -39,43 +43,39 @@ module.exports = { await command.execute(interaction); } catch (error) { console.error(error); - if (interaction.replied || interaction.deferred) { - await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } else { - await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral }); - } + await safeReply(interaction, '❌ There was an error while executing this command!'); } } else if (interaction.isButton()) { if (interaction.customId === 'acceptnotifications') { - const notifiRoleId = "1401849479149391882"; + const notifiRoleId = '1401849479149391882'; try { if (interaction.member.roles.cache.has(notifiRoleId)) { - await interaction.reply({ content: 'you already have the notification role!', flags: MessageFlags.Ephemeral }); + await interaction.reply({ content: 'You already have the notification role!', flags: MessageFlags.Ephemeral }); } else { await interaction.member.roles.add(notifiRoleId); - await interaction.reply({ content: 'Thank you hope to see you soon in my streams!', flags: MessageFlags.Ephemeral }); + await interaction.reply({ content: 'Thank you! Hope to see you soon in my streams!', flags: MessageFlags.Ephemeral }); } } catch (error) { - await interaction.reply({ content: 'something went wrong', flags: MessageFlags.Ephemeral }); - console.log(error); + console.error(error); + await interaction.reply({ content: 'Something went wrong', flags: MessageFlags.Ephemeral }); } } if (interaction.customId === 'acceptrules') { - const viewerRoleId = "1401153107601395774"; + const viewerRoleId = '1401153107601395774'; try { if (interaction.member.roles.cache.has(viewerRoleId)) { - await interaction.reply({ content: 'you already have accepted the rules!', flags: MessageFlags.Ephemeral }); + await interaction.reply({ content: 'You already accepted the rules!', flags: MessageFlags.Ephemeral }); } else { await interaction.member.roles.add(viewerRoleId); await interaction.reply({ content: 'Thank you for accepting the rules!', flags: MessageFlags.Ephemeral }); } } catch (error) { - await interaction.reply({ content: 'something went wrong', flags: MessageFlags.Ephemeral }); - console.log(error); + console.error(error); + await interaction.reply({ content: 'Something went wrong', flags: MessageFlags.Ephemeral }); } } } else if (interaction.isStringSelectMenu()) { - // respond to the select menu + // handle select menu } }, -}; +}; \ No newline at end of file diff --git a/main.js b/main.js index 72ecc45..d2e76ac 100644 --- a/main.js +++ b/main.js @@ -3,7 +3,12 @@ const path = require('node:path'); const { Client, Collection, Events, GatewayIntentBits, MessageFlags } = require('discord.js'); const { token } = require('./config.json'); -const client = new Client({ intents: [GatewayIntentBits.Guilds] }); +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildVoiceStates, + ], +}); client.cooldowns = new Collection(); client.commands = new Collection(); diff --git a/package-lock.json b/package-lock.json index 2fcda30..c56e578 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,10 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "discord.js": "^14.21.0" + "@discordjs/voice": "^0.19.0", + "@snazzah/davey": "^0.1.9", + "discord.js": "^14.21.0", + "opusscript": "^0.0.8" } }, "node_modules/@discordjs/builders": { @@ -104,6 +107,25 @@ "url": "https://github.com/discordjs/discord.js?sponsor" } }, + "node_modules/@discordjs/voice": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.19.0.tgz", + "integrity": "sha512-UyX6rGEXzVyPzb1yvjHtPfTlnLvB5jX/stAMdiytHhfoydX+98hfympdOwsnTktzr+IRvphxTbdErgYDJkEsvw==", + "license": "Apache-2.0", + "dependencies": { + "@types/ws": "^8.18.1", + "discord-api-types": "^0.38.16", + "prism-media": "^1.3.5", + "tslib": "^2.8.1", + "ws": "^8.18.3" + }, + "engines": { + "node": ">=22.12.0" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, "node_modules/@discordjs/ws": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.2.3.tgz", @@ -139,6 +161,53 @@ "url": "https://github.com/discordjs/discord.js?sponsor" } }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, "node_modules/@sapphire/async-queue": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", @@ -172,6 +241,268 @@ "npm": ">=7.0.0" } }, + "node_modules/@snazzah/davey": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey/-/davey-0.1.9.tgz", + "integrity": "sha512-vNZk5y+IsxjwzTAXikvzz5pqMLb35YytC64nVF2MAFVhjpXu9ITOKUriZ0JG/llwzCAi56jb5x0cXDRIyE2A2A==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "funding": { + "url": "https://github.com/sponsors/Snazzah" + }, + "optionalDependencies": { + "@snazzah/davey-android-arm-eabi": "0.1.9", + "@snazzah/davey-android-arm64": "0.1.9", + "@snazzah/davey-darwin-arm64": "0.1.9", + "@snazzah/davey-darwin-x64": "0.1.9", + "@snazzah/davey-freebsd-x64": "0.1.9", + "@snazzah/davey-linux-arm-gnueabihf": "0.1.9", + "@snazzah/davey-linux-arm64-gnu": "0.1.9", + "@snazzah/davey-linux-arm64-musl": "0.1.9", + "@snazzah/davey-linux-x64-gnu": "0.1.9", + "@snazzah/davey-linux-x64-musl": "0.1.9", + "@snazzah/davey-wasm32-wasi": "0.1.9", + "@snazzah/davey-win32-arm64-msvc": "0.1.9", + "@snazzah/davey-win32-ia32-msvc": "0.1.9", + "@snazzah/davey-win32-x64-msvc": "0.1.9" + } + }, + "node_modules/@snazzah/davey-android-arm-eabi": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-android-arm-eabi/-/davey-android-arm-eabi-0.1.9.tgz", + "integrity": "sha512-Dq0WyeVGBw+uQbisV/6PeCQV2ndJozfhZqiNIfQxu6ehIdXB7iHILv+oY+AQN2n+qxiFmLh/MOX9RF+pIWdPbA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-android-arm64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-android-arm64/-/davey-android-arm64-0.1.9.tgz", + "integrity": "sha512-OE16OZjv7F/JrD7Mzw5eL2gY2vXRPC8S7ZrmkcMyz/sHHJsGHlT+L7X5s56Bec1YDTVmzAsH4UBuvVBoXuIWEQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-darwin-arm64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-darwin-arm64/-/davey-darwin-arm64-0.1.9.tgz", + "integrity": "sha512-z7oORvAPExikFkH6tvHhbUdZd77MYZp9VqbCpKEiI+sisWFVXgHde7F7iH3G4Bz6gUYJfgvKhWXiDRc+0SC4dg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-darwin-x64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-darwin-x64/-/davey-darwin-x64-0.1.9.tgz", + "integrity": "sha512-f1LzGyRGlM414KpXml3OgWVSd7CgylcdYaFj/zDBb8bvWjxyvsI9iMeuPfe/cduloxRj8dELde/yCDZtFR6PdQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-freebsd-x64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-freebsd-x64/-/davey-freebsd-x64-0.1.9.tgz", + "integrity": "sha512-k6p3JY2b8rD6j0V9Ql7kBUMR4eJdcpriNwiHltLzmtGuz/nK5RGQdkEP68gTLc+Uj3xs5Cy0jRKmv2xJQBR4sA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-linux-arm-gnueabihf": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-linux-arm-gnueabihf/-/davey-linux-arm-gnueabihf-0.1.9.tgz", + "integrity": "sha512-xDaAFUC/1+n/YayNwKsqKOBMuW0KI6F0SjgWU+krYTQTVmAKNjOM80IjemrVoqTpBOxBsT80zEtct2wj11CE3Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-linux-arm64-gnu": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-linux-arm64-gnu/-/davey-linux-arm64-gnu-0.1.9.tgz", + "integrity": "sha512-t1VxFBzWExPNpsNY/9oStdAAuHqFvwZvIO2YPYyVNstxfi2KmAbHMweHUW7xb2ppXuhVQZ4VGmmeXiXcXqhPBw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-linux-arm64-musl": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-linux-arm64-musl/-/davey-linux-arm64-musl-0.1.9.tgz", + "integrity": "sha512-Xvlr+nBPzuFV4PXHufddlt08JsEyu0p8mX2DpqdPxdpysYIH4I8V86yJiS4tk04a6pLBDd8IxTbBwvXJKqd/LQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-linux-x64-gnu": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-linux-x64-gnu/-/davey-linux-x64-gnu-0.1.9.tgz", + "integrity": "sha512-6Uunc/NxiEkg1reroAKZAGfOtjl1CGa7hfTTVClb2f+DiA8ZRQWBh+3lgkq/0IeL262B4F14X8QRv5Bsv128qw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-linux-x64-musl": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-linux-x64-musl/-/davey-linux-x64-musl-0.1.9.tgz", + "integrity": "sha512-fFQ/n3aWt1lXhxSdy+Ge3gi5bR3VETMVsWhH0gwBALUKrbo3ZzgSktm4lNrXE9i0ncMz/CDpZ5i0wt/N3XphEQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-wasm32-wasi": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-wasm32-wasi/-/davey-wasm32-wasi-0.1.9.tgz", + "integrity": "sha512-xWvzej8YCVlUvzlpmqJMIf0XmLlHqulKZ2e7WNe2TxQmsK+o0zTZqiQYs2MwaEbrNXBhYlHDkdpuwoXkJdscNQ==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@snazzah/davey-win32-arm64-msvc": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-win32-arm64-msvc/-/davey-win32-arm64-msvc-0.1.9.tgz", + "integrity": "sha512-sTqry/DfltX2OdW1CTLKa3dFYN5FloAEb2yhGsY1i5+Bms6OhwByXfALvyMHYVo61Th2+sD+9BJpQffHFKDA3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-win32-ia32-msvc": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-win32-ia32-msvc/-/davey-win32-ia32-msvc-0.1.9.tgz", + "integrity": "sha512-twD3LwlkGnSwphsCtpGb5ztpBIWEvGdc0iujoVkdzZ6nJiq5p8iaLjJMO4hBm9h3s28fc+1Qd7AMVnagiOasnA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@snazzah/davey-win32-x64-msvc": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@snazzah/davey-win32-x64-msvc/-/davey-win32-x64-msvc-0.1.9.tgz", + "integrity": "sha512-eMnXbv4GoTngWYY538i/qHz2BS+RgSXFsvKltPzKqnqzPzhQZIY7TemEJn3D5yWGfW4qHve9u23rz93FQqnQMA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/node": { "version": "24.1.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz", @@ -260,6 +591,38 @@ "integrity": "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==", "license": "MIT" }, + "node_modules/opusscript": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz", + "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", + "license": "MIT" + }, + "node_modules/prism-media": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.3.5.tgz", + "integrity": "sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==", + "license": "Apache-2.0", + "peerDependencies": { + "@discordjs/opus": ">=0.8.0 <1.0.0", + "ffmpeg-static": "^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0", + "node-opus": "^0.3.3", + "opusscript": "^0.0.8" + }, + "peerDependenciesMeta": { + "@discordjs/opus": { + "optional": true + }, + "ffmpeg-static": { + "optional": true + }, + "node-opus": { + "optional": true + }, + "opusscript": { + "optional": true + } + } + }, "node_modules/ts-mixer": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", diff --git a/package.json b/package.json index 1a0f5dc..b6b4a5e 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "discord.js": "^14.21.0" + "@discordjs/voice": "^0.19.0", + "@snazzah/davey": "^0.1.9", + "discord.js": "^14.21.0", + "opusscript": "^0.0.8" } } diff --git a/temp.js b/temp.js new file mode 100644 index 0000000..d0c8426 --- /dev/null +++ b/temp.js @@ -0,0 +1,24 @@ +const { spawn } = require('node:child_process'); + +console.log('Starting smoke test...'); + +const ytdlp = spawn('yt-dlp', [ + '-f', 'bestaudio', + '-o', '-', + 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' +]); + +const ffmpeg = spawn('ffmpeg', [ + '-i', 'pipe:0', + '-f', 'null', + '-' +]); + +ytdlp.stdout.pipe(ffmpeg.stdin); + +ffmpeg.on('close', (code) => { + console.log('FFmpeg exited with code:', code); +}); + +ytdlp.on('error', err => console.error('yt-dlp error:', err)); +ffmpeg.on('error', err => console.error('ffmpeg error:', err)); \ No newline at end of file