Question | Answer |
---|---|
I'm getting Error: Invalid converter command , why? |
Either you don't have FFmpeg/avconv binaries installed or it isn't in your environment variables (see below) |
Can I use the ffmpeg from NPM? | No, the ffmpeg module on NPM is used to interact with an installed FFmpeg binary, it is not FFmpeg itself |
- node-gyp and its dependencies, but in summary:
- Python 3.6/3.7/3.8/3.9 (or latest version from the Windows Store if applicable)
- C/C++ compiler toolchain (GCC as an example)
- FFmpeg (see below) or avconv
- Update your apt package list:
$ sudo apt update
- Install the FFmpeg package:
$ sudo apt install ffmpeg
- Make sure FFmpeg is successfully installed (the latest version at time of writing is 4.1.6 on Debian 10, 4.2.4 on Ubuntu 20.04, 4.3.1 on Ubuntu 20.10 and 4.3.2 on Ubuntu 21.04):
$ ffmpeg -version
- Download the Windows build from either gyan.dev (scroll down and click on the
ffmpeg-git-full.7z
link) or BtbN (find thewin64-gpl
zip file)* - Extract the contents of the 7z/zip file to
C:\Program Files\ffmpeg
(should contain at minimum thebin
folder) - Open the System Properties window (Settings → System → About → Advanced System Settings or search for "View Advanced System Settings")
- Open the Environment Variables window
- Select the "Path" variable then click "Edit..."
- In the Edit Environment Variable window, click on "New", then type
C:\Program Files\ffmpeg\bin
- Click "OK" in the Edit Environment Variable and Environment Variables windows
- Make sure FFmpeg is successfully installed (the current latest version at time of writing is 4.4):
ffmpeg -version
* These links are not official FFmpeg websites and may not be affiliated with FFmpeg. They are simply trustworthy sources to download precompiled Windows binaries for FFmpeg, as they do not distribute precompiled binaries themselves. These links, however, are linked from FFmpeg's website
- Update your homebrew package list:
$ brew update
- Install the FFmpeg package:
$ brew install ffmpeg
- Make sure FFmpeg is successfully installed (the current latest version at time of writing is 4.4):
$ ffmpeg -version
Please follow the relevant compilation guide for your operating system
NOTE I must stress that the following code are basic instructions on how to use voice with Eris. Please do not copy this code blindly as your code will almost certainly differ to the example guide given here.
To play audio, you must first connect to a voice channel
const Eris = require("eris");
const bot = new Eris.Client("Bot TOKEN"); // Replace TOKEN with your bot account token
// After client ready and after invokation (must be inside an asynchronous function if not using promise callbacks)
const voiceConnection = await bot.joinVoiceChannel(channelID);
After connecting to the voice channel, you must wait for Discord to tell your bot that it has connected successfully
voiceConnection.on("ready", () => {
console.log("Successfully connected to the voice channel");
});
Now your bot is ready to start streaming audio to the voice channel. We can either play a local audio file or something from YouTube (in this example we'll use ytdl-core
) (make sure you do this in the ready event)
voiceConnection.on("ready", () => {
console.log("Successfully connected to the voice channel");
voiceConnection.play(pathToFile);
});
const ytdl = require("ytdl-core");
voiceConnection.on("ready", () => {
console.log("Successfully connected to the voice channel");
voiceConnection.play(ytdl(youtubeURL));
});
In some cases you might want to pass a ReadableStream directly into Eris, in this case, follow the same format as playing a local file, but set the parameter to the ReadableStream instead of a filepath string
Combining all of this (as well as adding some other checks and user friendly indications), you might get something along the lines of this:
const Eris = require("eris");
const bot = new Eris.Client("Bot TOKEN"); // Replace TOKEN with your bot account token
const playCommand = "!play";
bot.on("ready", () => { // When the bot is ready
console.log("Ready!"); // Log "Ready!"
});
bot.on("error", (err) => {
console.error(err); // or your preferred logger
});
bot.on("messageCreate", async (msg) => { // When a message is created
if(msg.content.startsWith(playCommand)) { // If the message content starts with "!play "
if(msg.content.length <= playCommand.length + 1) { // Check if a filename was specified
bot.createMessage(msg.channel.id, "Please specify a filename.");
return;
}
if(!msg.channel.guild) { // Check if the message was sent in a guild
bot.createMessage(msg.channel.id, "This command can only be run in a server.");
return;
}
if(!msg.member.voiceState.channelID) { // Check if the user is in a voice channel
bot.createMessage(msg.channel.id, "You are not in a voice channel.");
return;
}
const filename = msg.content.substring(playCommand.length + 1); // Get the filename
try {
const voiceConnection = await bot.joinVoiceChannel(msg.member.voiceState.channelID);
voiceConnection.on("ready", () => {
console.log("Successfully connected to the voice channel");
if(voiceConnection.playing) { // Stop playing if the connection is playing something
voiceConnection.stopPlaying();
}
voiceConnection.play(filename); // Play the file and notify the user
bot.createMessage(msg.channel.id, `Now playing **${filename}**`);
voiceConnection.once("end", () => {
bot.createMessage(msg.channel.id, `Finished **${filename}**`); // Say when the file has finished playing
});
});
} catch (error) {
bot.createMessage(msg.channel.id, "Error joining voice channel: " + error.message); // Notify the user if there is an error
console.log(error); // Log the error
}
}
});
bot.connect(); // Get the bot to connect to Discord
You can modify this to support ytdl-core and searching videos on YouTube.