Explanation
I have this code that plays youtube video audio in voice channels.
When it joins the channel I get an error that says "ffmpeg not found". I ran the terminal command "npm i ffmpeg-static" and it worked fine but after a couple of minutes I get a long error and the music stops playing.
This is my code:
client.on("ready", async () => {
for (const channelId of Channels) {
joinChannel(channelId);
await new Promise(res => setTimeout(()=>res(2), 500))
}
function joinChannel(channelId) {
client.channels.fetch(channelId).then(channel => {
const VoiceConnection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator
});
const resource = createAudioResource(ytdl("https://youtu.be/0J2gdL87fVs", {
filter: "audioonly"
}), {
inlineVolume: true
});
resource.volume.setVolume(0.2);
const player = createAudioPlayer()
VoiceConnection.subscribe(player);
player.play(resource);
player.on("idle", () => {
try {
player.stop()
}catch (e) {}
try {
VoiceConnection.destory()
}catch (e) {}
joinChannel(channelId)
})
}).catch(console.error)
}
})
Related
I have been trying to create an audioPlayer with the Discord.js library. I created a /join command that joins my bot to the voice channel and then plays a local audio file.
const { SlashCommandBuilder, ChannelType } = require('discord.js');
const { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus } = require('#discordjs/voice')
const path = require('node:path');
const player = createAudioPlayer();
module.exports = {
data: new SlashCommandBuilder().setName('join').setDescription('Join to a voice channel').addChannelOption((option) =>
option.setName('channel').
setDescription('The channel to join').
setRequired(true).
addChannelTypes(ChannelType.GuildVoice)
),
async execute(interaction) {
const voiceChannel = interaction.options.getChannel('channel');
try {
const voiceConnection = joinVoiceChannel({
channelId: voiceChannel.id,
guildId: interaction.guild.id,
adapterCreator: interaction.guild.voiceAdapterCreator,
})
player.on(AudioPlayerStatus.Playing, () => {
console.log('The audio player has started playing!');
});
player.on('error', error => {
console.error(`Error: ${error.message} with resource ${error.resource.metadata.title}`);
});
let resource = createAudioResource('"C:\\Users\\gerso\\Documents\\CS-P\\discord-bot\\audio\\track.mp3"', { inlineVolume: true })
player.play(resource)
const subscription = voiceConnection.subscribe(player)
if(subscription) {
setTimeout(() => subscription.unsubscribe(), 15_000)
}
} catch (error) {
console.error(error)
}
await interaction.reply('player')
},
};
When I use the command on discord the bot joins the voice channel but it doesn't play any audio and the console doesn't show any error.
Note: I have already installed ffmpeg-static in my project.
(sry for my English)
I just want to make a simple reaction message, connection to vocal where user use one word as "exemple" in this "it is an exemple", and play one song.mp3, after the bot deconnect when he finish this song.mp3.
This is my index.js
const { Client, VoiceChannel, Intents } = require('discord.js');
const client = new Client({ intents: 32767 });
const dotenv = require('dotenv'); dotenv.config();
const {
joinVoiceChannel,
createAudioPlayer,
createAudioResource,
entersState,
StreamType,
AudioPlayerStatus,
VoiceConnectionStatus,
} = require ('#discordjs/voice');
const { createDiscordJSAdapter } = require ('./?');
const player = createAudioPlayer();
client.login(process.env.DISCORD_TOKEN);
function playSong() {
const resource = createAudioResource('./music/try.mp3', {
inputType: StreamType.Arbitrary,
});
player.play(resource);
return entersState(player, AudioPlayerStatus.Playing, 5e3);
};
client.on('ready', async () => {
console.log('Discord.js client is ready!');
try {
await playSong();
console.log('Song is ready to play!');
} catch (error) {
console.error(error);
}
});
async function connectToChannel(channel = VoiceChannel) {
const connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: createDiscordJSAdapter(channel),
});
try {
await entersState(connection, VoiceConnectionStatus.Ready, 30e3);
return connection;
} catch (error) {
connection.destroy();
throw error;
}
};
client.on('messageCreate', async (message) => {
if (!message.guild) return;
if (message.content === '-join') {
const channel = message.member?.voice.channel;
if (channel) {
try {
const connection = await connectToChannel(channel);
connection.subscribe(player);
await message.reply('Playing now!');
} catch (error) {
console.error(error);
}
} else {
void message.reply('Join a voice channel then try again!');
}
}
});
I have this error :
Screenshot of console error
This error is here in my index.js :
const { createDiscordJSAdapter } = require ('./?');
I just don't know how import this function createDiscordJSAdapter ....
I have my .env file true, (the bot is connected to my server).
I have my folder music with my song name "try.mp3".
And this index.js :D
If someone can help me to build this simple exemple,
Thx !
Sunclies
How do I play audio from a url with discord.js v13.
I used this code and it didn't work.
const connection = joinVoiceChannel({
channelId: channel_id.id,
guildId: guild_id,
adapterCreator: message.guild.voiceAdapterCreator,
});
const player = createAudioPlayer();
const resource = createAudioResource('http://radioplayer.kissfmuk.com/live/')
player.play(resource)
connection.subscribe(player)
I have activated all Intents, the bot shows a green circle but no audio is playing.
Do you have an Idea how it works?
A link of which you are trying to make a resource of, has to return an audio file.
Live audio broadcasts will not work with your current code.
If the url gives you E.g. an .mp3 file, the code should work.
Example Function:
const Discord = require('discord.js');
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_VOICE_STATES] });
const config = require('./config/config.json');
const { joinVoiceChannel, createAudioPlayer, NoSubscriberBehavior, createAudioResource, AudioPlayerStatus, VoiceConnectionStatus, entersState } = require('#discordjs/voice');
const { join } = require('path');
client.once('ready', () => {
console.log(config.onlineMessage);
const channels = client.guilds.cache.find(f => f.name==="<Server Name>").channels;
JoinChannel(channels.cache.find(r => r.name === "<Channel Name>"), './background.mp3', 0.025);
});
client.login(config.token);
function JoinChannel(channel, track, volume) {
const connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guildId,
adapterCreator: channel.guild.voiceAdapterCreator,
});
const player = createAudioPlayer();
resource = createAudioResource(join(__dirname, track), { inlineVolume: true });
resource.volume.setVolume(volume);
connection.subscribe(player);
connection.on(VoiceConnectionStatus.Ready, () => {console.log("ready"); player.play(resource);})
connection.on(VoiceConnectionStatus.Disconnected, async (oldState, newState) => {
try {
console.log("Disconnected.")
await Promise.race([
entersState(connection, VoiceConnectionStatus.Signalling, 5_000),
entersState(connection, VoiceConnectionStatus.Connecting, 5_000),
]);
} catch (error) {
connection.destroy();
}
});
player.on('error', error => {
console.error(`Error: ${error.message} with resource ${error.resource.metadata.title}`);
player.play(getNextResource());
});
player.on(AudioPlayerStatus.Playing, () => {
console.log('The audio player has started playing!');
});
player.on('idle', () => {
connection.destroy();
})
}
The answer was pretty simple, I just need to subscribe to the connection before I play the resource!
const connection = joinVoiceChannel({
channelId: channel_id.id,
guildId: guild_id,
adapterCreator: message.guild.voiceAdapterCreator,
});
const resource =
createAudioResource('https://streams.ilovemusic.de/iloveradio8.mp3', {
inlineVolume: true
})
const player = createAudioPlayer();
connection.subscribe(player)
player.play(resource)
I try to play a Youtube URL but when it starts playing it stops after 1 second. mp3 files are working fine, it just doesn't work when I try to play Youtube URLs.
Here is my Code:
case 'play':
{
const Channel = ['903334978199388271'];
for (const channelId of Channel) {
joinChannel(channelId);
}
function joinChannel(channelId) {
Client.channels
.fetch(channelId)
.then((channel) => {
const VoiceConnection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guild.id,
adapterCreator: channel.guild.voiceAdapterCreator,
});
const player = createAudioPlayer();
VoiceConnection.subscribe(player);
player.play(
createAudioResource(
ytdl('https://www.youtube.com/watch?v=sPPsOmQh76A'),
),
);
})
.catch(console.error);
}
}
break;
I had the same problem before, the problem is ytdl-core, so you can use ytdl-core-discord instead. Here is an example:
const { Client, Intents, MessageEmbed } = require('discord.js')
const ytdl = require('ytdl-core-discord')
const {
joinVoiceChannel,
createAudioPlayer,
createAudioResource,
StreamType
} = require('#discordjs/voice')
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MEMBERS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_VOICE_STATES /// <= Don't miss this :)
]
});
var prefix = '!'
client.on('ready', async () => {
console.log('Client is Ready...');
});
client.on('messageCreate', async (message) => {
if (message.content.trim().toLocaleLowerCase() === prefix + 'play') {
const channel = client.channels.cache.get('Channel ID Here')
const connection = joinVoiceChannel({
channelId: channel.id,
guildId: channel.guildId,
adapterCreator: channel.guild.voiceAdapterCreator
});
const player = createAudioPlayer();
const resource = createAudioResource(await ytdl('https://www.youtube.com/watch?v=sPPsOmQh76A'), { inputType: StreamType.Opus });
player.play(resource);
connection.subscribe(player);
}
});
client.login('Bot Token Here!');
I tried to make a music bot, but it wont execute the song. Below is the code for the section which should gather the information and execute the song.
Can someone help me get this right? I'm not sure how to fix this issue as I don't know where the error starts.
I pasted also the handleVideo and the play class in the end so you know what happens there.
if (command === 'play') {
const voiceChannel = message.member.voiceChannel;
if (!voiceChannel) return message.channel.send('I\'m sorry but you need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) {
return message.channel.send('I cannot connect to your voice channel, make sure I have the proper permissions!');
}
if (!permissions.has('SPEAK')) {
return message.channel.send('I cannot speak in this voice channel, make sure I have the proper permissions!');
}
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
const playlist = await youtube.getPlaylist(url);
const videos = await playlist.getVideos();
for (const video of Object.values(videos)) {
const video2 = await youtube.getVideoByID(video.id); // eslint-disable-line no-await-in-loop
await handleVideo(video2, message, voiceChannel, true); // eslint-disable-line no-await-in-loop
}
return message.channel.send(`✅ Playlist: **${playlist.title}** has been added to the queue!`);
} else {
try {
var video = await youtube.getVideo(url);
} catch (error) {
try {
var videos = await youtube.searchVideos(searchString, 10);
let index = 0;
message.channel.send(`
__**Song selection:**__
${videos.map(video2 => `**${++index} -** ${video2.title}`).join('\n')}
Please provide a value to select one of the search results ranging from 1-10.
`);
// eslint-disable-next-line max-depth
try {
var response = await message.channel.awaitMessages(msg2 => msg2.content > 0 && msg2.content < 11, {
maxMatches: 1,
time: 10000,
errors: ['time']
});
} catch (err) {
console.error(err);
return message.channel.send('No or invalid value entered, cancelling video selection.');
}
const videoIndex = parseInt(response.first().content);
var video = await youtube.getVideoByID(videos[videoIndex - 1].id);
} catch (err) {
console.error(err);
return message.channel.send('🆘 I could not obtain any search results.');
}
}
return handleVideo(video, message, voiceChannel);
}
}
async function handleVideo(video, message, voiceChannel, playlist = false) {
const serverQueue = queue.get(message.guild.id);
console.log(video);
const song = {
id: video.id,
title: Util.escapeMarkdown(video.title),
url: `https://www.youtube.com/watch?v=${video.id}`
};
if (!serverQueue) {
const queueConstruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true
};
queue.set(message.guild.id, queueConstruct);
queueConstruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueConstruct.connection = connection;
play(message.guild, queueConstruct.songs[0]);
} catch (error) {
console.error(`I could not join the voice channel: ${error}`);
queue.delete(message.guild.id);
return message.channel.send(`I could not join the voice channel: ${error}`);
}
} else {
serverQueue.songs.push(song);
console.log(serverQueue.songs);
if (playlist) return undefined;
else return message.channel.send(`✅ **${song.title}** has been added to the queue!`);
}
return undefined;
});
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
console.log(serverQueue.songs);
const dispatcher = serverQueue.connection.playStream(ytdl(song.url))
.on('end', reason => {
if (reason === 'Stream is not generating quickly enough.') console.log('Song ended.');
else console.log(reason);
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on('error', error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.textChannel.send(`🎶 Start playing: **${song.title}**`);
}
The error message:
TypeError [ERR_INVALID_ARG_TYPE]: The "file" argument must be of type string. Received type object
at validateString (internal/validators.js:125:11)
at normalizeSpawnArguments (child_process.js:411:3)
at Object.spawn (child_process.js:545:16)
at new FfmpegProcess (C:\Users\user\Desktop\ExoBot-master\node_modules\prism-media\src\transcoders\ffmpeg\FfmpegProcess.js:14:33)
at FfmpegTranscoder.transcode (C:\Users\user\Desktop\ExoBot-master\node_modules\prism-media\src\transcoders\ffmpeg\Ffmpeg.js:34:18)
at MediaTranscoder.transcode (C:\Users\user\Desktop\ExoBot-master\node_modules\prism-media\src\transcoders\MediaTranscoder.js:27:31)
at Prism.transcode (C:\Users\user\Desktop\ExoBot-master\node_modules\prism-media\src\Prism.js:13:28)
at AudioPlayer.playUnknownStream (C:\Users\user\Desktop\ExoBot-master\node_modules\discord.js\src\client\voice\player\AudioPlayer.js:97:35)
at VoiceConnection.playStream (C:\Users\user\Desktop\ExoBot-master\node_modules\discord.js\src\client\voice\VoiceConnection.js:478:24)
at play (C:\Users\user\Desktop\ExoBot-master\bot.js:322:44)