Class: Discorb::Voice::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/discorb/voice/core.rb

Overview

Client for voice connection.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, data) ⇒ Client

Returns a new instance of Client.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/discorb/voice/core.rb', line 27

def initialize(client, data)
  @client = client
  @token = data[:token]
  @guild_id = data[:guild_id]
  @endpoint = data[:endpoint]
  @status = :connecting
  @playing_status = :stopped
  @connect_condition = Async::Condition.new
  @paused_condition = Async::Condition.new
  @play_condition = Async::Condition.new
  Async do
    start_receive false
  end
end

Instance Attribute Details

#connect_conditionObject (readonly)



18
19
20
# File 'lib/discorb/voice/core.rb', line 18

def connect_condition
  @connect_condition
end

#playing_conditionAsync::Condition (readonly)

Returns The condition of playing audio.

Returns:

  • (Async::Condition)

    The condition of playing audio



24
25
26
# File 'lib/discorb/voice/core.rb', line 24

def playing_condition
  @playing_condition
end

#playing_status:stopped, :playing (readonly)

Returns The current status of playing audio.

Returns:

  • (:stopped, :playing)

    The current status of playing audio



22
23
24
# File 'lib/discorb/voice/core.rb', line 22

def playing_status
  @playing_status
end

#status:connecting, ... (readonly)

Returns The current status of the voice connection.

Returns:

  • (:connecting, :connected, :closed, :ready, :reconnecting)

    The current status of the voice connection



20
21
22
# File 'lib/discorb/voice/core.rb', line 20

def status
  @status
end

Instance Method Details

#disconnectObject

Disconnects from the voice server.



146
147
148
149
150
151
152
153
154
# File 'lib/discorb/voice/core.rb', line 146

def disconnect
  begin
    @connection.close
  rescue StandardError
    nil
  end
  @client.disconnect_voice(@guild_id)
  cleanup
end

#play(source, high_priority: false) ⇒ Object

Plays audio from a source.

Parameters:

  • source (Discorb::Voice::Source)

    data The audio source

  • high_priority (Boolean) (defaults to: false)

    Whether to play audio in high priority



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/discorb/voice/core.rb', line 71

def play(source, high_priority: false)
  @playing_task = Async do
    speaking(high_priority: high_priority)
    @playing_status = :playing
    @playing_condition = Async::Condition.new
    stream = OggStream.new(source.io)
    loops = 0
    @start_time = Time.now.to_f
    delay = OPUS_FRAME_LENGTH / 1000.0

    stream.packets.each_with_index do |packet, _i|
      if @playing_status == :stopped
        source.cleanup
        break
      elsif @playing_status == :paused
        @paused_condition.wait
      elsif @status != :ready
        sleep 0.02 while @status != :ready

        speaking(high_priority: high_priority)
      end
      # p i
      @timestamp += (OPUS_SAMPLE_RATE / 1000.0 * OPUS_FRAME_LENGTH).to_i
      @sequence += 1
      # puts packet.data[...10].unpack1("H*")
      # puts packet[-10..]&.unpack1("H*")
      send_audio(packet)
      # puts "Sent packet #{i}"
      loops += 1
      next_time = @start_time + (delay * (loops + 1))
      # p [next_time, Time.now.to_f, delay]
      sleep(next_time - Time.now.to_f) if next_time > Time.now.to_f
      # @voice_connection.flush
    end
    # p :e
    @playing_status = :stopped
    @playing_condition.signal
    source.cleanup
    stop_speaking
  end
end

#speaking(high_priority: false) ⇒ Object

Sends a speaking indicator to the server.

Parameters:

  • high_priority (Boolean) (defaults to: false)

    Whether to send audio in high priority.



47
48
49
50
51
52
53
54
55
# File 'lib/discorb/voice/core.rb', line 47

def speaking(high_priority: false)
  flag = 1
  flag |= 1 << 2 if high_priority
  send_connection_message(5, {
    speaking: flag,
    delay: 0,
    ssrc: @ssrc,
  })
end

#stopObject

Stop playing audio.



138
139
140
141
# File 'lib/discorb/voice/core.rb', line 138

def stop
  @playing_status = :stopped
  send_audio(OPUS_SILENCE)
end

#stop_speakingObject



57
58
59
60
61
62
63
# File 'lib/discorb/voice/core.rb', line 57

def stop_speaking
  send_connection_message(5, {
    speaking: false,
    delay: 0,
    ssrc: @ssrc,
  })
end