Class: Discordrb::Voice::VoiceBot

Inherits:
Object
  • Object
show all
Defined in:
lib/discordrb/voice/voice_bot.rb

Overview

This class represents a connection to a Discord voice server and channel. It can be used to play audio files and streams and to control playback on currently playing tracks. The method Bot#voice_connect can be used to connect to a voice channel.

discordrb does latency adjustments every now and then to improve playback quality. I made sure to put useful defaults for the adjustment parameters, but if the sound is patchy or too fast (or the speed varies a lot) you should check the parameters and adjust them to your connection: #adjust_interval, #adjust_offset, and #adjust_average.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(channel, bot, token, session, endpoint, encrypted) ⇒ VoiceBot

Returns a new instance of VoiceBot.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/discordrb/voice/voice_bot.rb', line 51

def initialize(channel, bot, token, session, endpoint, encrypted)
  @bot = bot
  @ws = VoiceWS.new(channel, bot, token, session, endpoint)
  @udp = @ws.udp
  @udp.encrypted = encrypted

  @sequence = @time = 0

  @adjust_interval = 100
  @adjust_offset = 10
  @adjust_average = false

  @encoder = Encoder.new
  @ws.connect
end

Instance Attribute Details

#adjust_averagetrue, false

This value determines whether or not the adjustment length should be averaged with the previous value. This may be useful on slower connections where latencies vary a lot. In general, it will make adjustments more smooth, but whether that is desired behaviour should be tried on a case-by-case basis.

Returns:

  • (true, false)

    whether adjustment lengths should be averaged with the respective previous value.

See Also:



49
50
51
# File 'lib/discordrb/voice/voice_bot.rb', line 49

def adjust_average
  @adjust_average
end

#adjust_intervalInteger

discordrb will occasionally measure the time it takes to send a packet, and adjust future delay times based on that data. This makes voice playback more smooth, because if packets are sent too slowly, the audio will sound patchy, and if they're sent too quickly, packets will "pile up" and occasionally skip some data or play parts back too fast. How often these measurements should be done depends a lot on the system, and if it's done too quickly, especially on slow connections, the playback speed will vary wildly; if it's done too slowly however, small errors will cause quality problems for a longer time.

Returns:

  • (Integer)

    how frequently audio length adjustments should be done, in ideal packets (20 ms).



34
35
36
# File 'lib/discordrb/voice/voice_bot.rb', line 34

def adjust_interval
  @adjust_interval
end

#adjust_offsetInteger

This particular value is also important because ffmpeg may take longer to process the first few packets. It is recommended to set this to 10 at maximum, otherwise it will take too long to make the first adjustment, but it shouldn't be any higher than #adjust_interval, otherwise no adjustments will take place. If #adjust_interval is at a value higher than 10, this value should not be changed at all.

Returns:

  • (Integer)

    the packet number (1 packet = 20 ms) at which length adjustments should start.

See Also:



42
43
44
# File 'lib/discordrb/voice/voice_bot.rb', line 42

def adjust_offset
  @adjust_offset
end

#encoderEncoder (readonly)

Returns the encoder used to encode audio files into the format required by Discord.

Returns:

  • (Encoder)

    the encoder used to encode audio files into the format required by Discord.



25
26
27
# File 'lib/discordrb/voice/voice_bot.rb', line 25

def encoder
  @encoder
end

#stream_timeInteger? (readonly)

Returns the amount of time the stream has been playing, or nil if nothing has been played yet.

Returns:

  • (Integer, nil)

    the amount of time the stream has been playing, or nil if nothing has been played yet.



22
23
24
# File 'lib/discordrb/voice/voice_bot.rb', line 22

def stream_time
  @stream_time
end

Instance Method Details

#continueObject

Continue playback. This change may take up to 100 ms to take effect, which is usually negligible.



91
92
93
# File 'lib/discordrb/voice/voice_bot.rb', line 91

def continue
  @paused = false
end

#destroyObject

Permanently disconnects from the voice channel; to reconnect you will have to call Bot#voice_connect again.



112
113
114
115
116
# File 'lib/discordrb/voice/voice_bot.rb', line 112

def destroy
  stop_playing
  @ws.destroy
  @encoder.destroy
end

#encrypted?true, false

Returns whether audio data sent will be encrypted.

Returns:

  • (true, false)

    whether audio data sent will be encrypted.



80
81
82
# File 'lib/discordrb/voice/voice_bot.rb', line 80

def encrypted?
  @udp.encrypted?
end

#pauseObject

Pause playback. This is not instant; it may take up to 20 ms for this change to take effect. (This is usually negligible.)



86
87
88
# File 'lib/discordrb/voice/voice_bot.rb', line 86

def pause
  @paused = true
end

#play(encoded_io) ⇒ Object

Plays a stream of raw data to the channel. All playback methods are blocking, i. e. they wait for the playback to finish before exiting the method. This doesn't cause a problem if you just use discordrb events/commands to play stuff, as these are fully threaded, but if you don't want this behaviour anyway, be sure to call these methods in separate threads.

Parameters:

  • encoded_io (IO)

    A stream of raw PCM data (s16le)



123
124
125
126
127
# File 'lib/discordrb/voice/voice_bot.rb', line 123

def play(encoded_io)
  stop_playing if @playing
  @io = encoded_io
  play_internal
end

#play_file(file) ⇒ Object

Plays an encoded audio file of arbitrary format to the channel.



132
133
134
# File 'lib/discordrb/voice/voice_bot.rb', line 132

def play_file(file)
  play @encoder.encode_file(file)
end

#play_io(io) ⇒ Object Also known as: play_stream

Plays a stream of encoded audio data of arbitrary format to the channel.



139
140
141
# File 'lib/discordrb/voice/voice_bot.rb', line 139

def play_io(io)
  play @encoder.encode_io(io)
end

#speaking=(value) ⇒ Object

Sets whether or not the bot is speaking (green circle around user).

Parameters:

  • value (true, false)

    whether or not the bot should be speaking.



97
98
99
100
# File 'lib/discordrb/voice/voice_bot.rb', line 97

def speaking=(value)
  @playing = value
  @ws.send_speaking(value)
end

#stop_playingObject

Stops the current playback entirely.



103
104
105
106
107
108
109
# File 'lib/discordrb/voice/voice_bot.rb', line 103

def stop_playing
  @was_playing_before = @playing
  @speaking = false
  @io.close if @io
  @io = nil
  sleep IDEAL_LENGTH / 1000.0 if @was_playing_before
end

#volumeInteger, String

Returns the current encoder volume.

Returns:

See Also:



75
76
77
# File 'lib/discordrb/voice/voice_bot.rb', line 75

def volume
  @encoder.volume
end

#volume=(value) ⇒ Object

Set the volume. Only applies to future playbacks

See Also:



69
70
71
# File 'lib/discordrb/voice/voice_bot.rb', line 69

def volume=(value)
  @encoder.volume = value
end