Lingo.Voice.Connection (Lingo v0.4.2)

Copy Markdown View Source

A connection to a Discord voice server (voice gateway v8): one per guild.

It takes the session details the main gateway hands out (session_id from VOICE_STATE_UPDATE, token and endpoint from VOICE_SERVER_UPDATE), so it depends on nothing global and several bots can run side by side.

Media is end-to-end encrypted with DAVE whenever the call uses it, then transport encrypted over UDP. Subscribers receive:

  • {:lingo_voice, guild_id, :ready} once connected; with DAVE on, audio is only sent once the group keys are in place, so playback asked for before then waits and starts from its first packet (see info/1)
  • {:lingo_voice, guild_id, {:audio, user_id, packet}} for each Opus packet received, where packet has :opus, :sequence and :timestamp
  • {:lingo_voice, guild_id, {:speaking, user_id, flags}}
  • {:lingo_voice, guild_id, :playback_finished}
  • {:lingo_voice, guild_id, {:playback_failed, reason}} when the audio source fails, for example ffmpeg can't read the input
  • {:lingo_voice, guild_id, {:disconnected, reason}}

Summary

Functions

Returns a specification to start this module under a supervisor.

The connection's state: status, readiness, SSRC, encryption details.

Plays a stream of Opus packets, replacing whatever is playing.

Starts a connection.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

disconnect(connection)

@spec disconnect(GenServer.server()) :: :ok

info(connection)

@spec info(GenServer.server()) :: map()

The connection's state: status, readiness, SSRC, encryption details.

play(connection, packets)

@spec play(GenServer.server(), Enumerable.t()) :: :ok

Plays a stream of Opus packets, replacing whatever is playing.

start_link(opts)

Starts a connection.

Required options: :guild_id, :channel_id, :user_id, :session_id, :token and :endpoint. Optional: :subscriber (a pid notified of events) and :name.

stop_playback(connection)

@spec stop_playback(GenServer.server()) :: :ok

subscribe(connection, pid \\ self())

@spec subscribe(GenServer.server(), pid()) :: :ok