diff --git a/docs/index.yml b/docs/index.yml index 4bf13c7e3..31de68b3a 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -6,6 +6,10 @@ path: updating.md - name: FAQ path: faq.md +- name: Topics + files: + - name: Voice + path: voice.md - name: Examples files: - name: Ping diff --git a/docs/topics/voice.md b/docs/topics/voice.md new file mode 100644 index 000000000..24fa405b0 --- /dev/null +++ b/docs/topics/voice.md @@ -0,0 +1,109 @@ +# Introduction to Voice +Voice in discord.js can be used for many things, such as music bots, recording or relaying audio. + +In discord.js, you can use voice by connecting to a `VoiceChannel` to obtain a `VoiceConnection`, where you can start streaming and receiving audio. + +To get started, make sure you have: +* ffmpeg - `npm install --global ffmpeg-binaries` +* an opus encoder, choose one from below: + * `npm install opusscript` + * `npm install node-opus` +* a good network connection + +## Joining a voice channel +The example below reacts to a message and joins the sender's voice channel, catching any errors. This is important +as it allows us to obtain a `VoiceConnection` that we can start to stream audio with + +```js +const Discord = require('discord.js'); +const client = new Discord.Client(); + +client.login('token here'); + +client.on('message', message => { + // voice only works in guilds, if the message does not come from a guild, + // we ignore it + if (!message.guild) return; + + if (message.content === '/join') { + // only try to join the sender's voice channel if they are in one themselves + if (message.member.voiceChannel) { + message.member.voiceChannel.join() + .then(connection => { // connection is an instance of VoiceConnection + message.reply('I have successfully connected to the channel!'); + }) + .catch(console.log); + } else { + message.reply('You need to join a voice channel first!'); + } + } +}); +``` + +## Streaming to a Voice Channel +In the previous example, we looked at how to join a voice channel in order to obtain a `VoiceConnection`. Now that we +have obtained a voice connection, we can start streaming audio to it. The following example shows how to stream an mp3 +file: + +**Playing a file:** +```js +// to play a file, we need to give an absolute path to it +const dispatcher = connection.playFile('C:/Users/Discord/Desktop/myfile.mp3'); +``` + +Your file doesn't have to be just an mp3; ffmpeg can convert videos and audios of many formats. + +The `dispatcher` variable is an instance of a `StreamDispatcher`, which manages streaming a specific resource to a voice +channel. We can do many things with the dispatcher, such as finding out when the stream ends or changing the volume: + +```js +dispatcher.on('end', () => { + // the song has finished +}); + +dispatcher.on('error', e => { + // catch any errors that may arise + console.log(e); +}); + +dispatcher.setVolume(0.5); // set the volume to 50% +dispatcher.setVolume(1); // set the volume back to 100% + +console.log(dispatcher.time); // the time in milliseconds that the stream dispatcher has been playing for + +dispatcher.pause(); // pause the stream +dispatcher.resume(); // carry on playing + +dispatcher.end(); // end the dispatcher, emits 'end' event +``` + +If you have an existing [ReadableStream](https://nodejs.org/api/stream.html#stream_readable_streams), +this can also be used: + +**Playing a ReadableStream:** +```js +connection.playStream(myReadableStream); + +// if you don't want to use absolute paths, you can use +// fs.createReadStream to circumvent it + +const fs = require('fs'); +const stream = fs.createReadStream('./test.mp3'); +connection.playStream(stream); +``` + +It's important to note that creating a readable stream to a file is less efficient than simply using `connection.playFile()`. + +**Playing anything else:** + +For anything else, such as a URL to a file, you can use `connection.playArbitraryInput()`. You should consult the [ffmpeg protocol documentation](https://ffmpeg.org/ffmpeg-protocols.html) to see what you can use this for. + +```js +// play an mp3 from a URL +connection.playArbitraryInput('http://mysite.com/sound.mp3'); +``` + +Again, playing a file from a URL like this is more performant than creating a ReadableStream to the file. + +## Advanced Topics +soon:tm: \ No newline at end of file