-
Notifications
You must be signed in to change notification settings - Fork 98
Voice sending
Starting from version 1.5.0, discordrb supports sending audio data into a voice channel, which can for example be used to make music playing bots.
First of all, you need to connect to a voice channel. This is done using bot.voice_connect(channel)
, where channel
is a Channel
object. (It will fail if the channel is not a voice channel.) The call returns a VoiceBot
object which is used to do the actual sending; after connecting, the VoiceBot
for the particular server can also be accessed using bot.voice(server)
.
You can connect to multiple voice channels by calling voice_connect
multiple times, but note that you can't connect to two voice channels on the same server at once. For convenience, there's a MessageEvent#voice
method which means that in message events and commands you can do event.voice
to get the voice bot for the current server. This is the notation I'll be using in this tutorial, though remember that you can use bot.voice(server)
with any server to get the same results on that server.
You can play a file using event.voice.play_file
:
event.voice.play_file('/home/user/Music/file.mp3')
This call will block until the playback has finished, either by simply reaching the end of the file or by being prematurely interrupted due to something else being played. play_file
will also allow URLs to be played (note that it will attempt to read the entire URL/file before starting playback, which may cause overhead for large files).
Another possibility is play_io
, which plays from an arbitrary IO
object:
event.voice.play_io(open('http://example.com/file.mp3'))
Like play_file
it will block until the playback has finished, either by failing to read any more data or by an EOF in the stream.
event.voice.pause
and event.voice.continue
will pause and continue the playback, respectively. Note that these calls are not instant, but may have a delay of up to 0.1 seconds depending on timing. event.voice.stop_playing
will stop the playback completely with a possible delay of 0.02 seconds.
event.voice.volume
can be set (only set) to an arbitrary float. The default is 1; 0 is completely silent, 2 is twice the volume as 1 and 0.5 is half the volume as 1. This applies to both future playbacks, as well as the current stream.
The event.voice.stream_time
property returns the approximate current time (in seconds) for which the playback has been running. Due to the network latency adjustments, this isn't guaranteed to be continuous either - if you do two calls in rapid succession and there's a particularly bad network delay, the second call might return a value less than the first.
Here's a number of things to check if you can successfully connect to a voice channel, but no audio plays:
- Does the file/URL you're trying to play actually exist? Try
play_io
instead with anopen
call to test whether that might be the problem. - Old version of ffmpeg: for an unknown reason, old versions of ffmpeg (happened with 0.8.10, possibly later ones) cause playback to exit immediately. Updating it should fix it.
- 64-bit Ruby on Windows: the precompiled version of libopus is for 32 bit only, so unless you manually compile the source for 64-bit, you need to use 32-bit Ruby.
- If you're running your bot on c9.io, there may be some issues with the ports, causing voice not to work at all. Nobody has found a solution yet; if you have, please report it here.