alchemy v0.6.0 Alchemy.Voice

Contains the types and functions related to voice communication with discord.

To use the functions in this module, make sure to configure the paths to ffmpeg, as well as youtube-dl, like so:

config :alchemy,
  ffmpeg_path: "path/to/ffmpeg"
  youtube_dl_path: "path/to/youtube-dl"

If these are not configured, the necessary supervisors for maintaining voice connections won’t be started, and you’ll run into errors when trying to use the functions in this module.

Summary

Types

Represents the audio options that can be passed to different play methods

Represents a voice region

Represents the state of a user’s voice connection

Functions

Joins a voice channel in a guild

Disconnects from voice in a guild

Lets this process listen for the end of an audio track in a guild

Starts playing a music file on a guild’s voice connection

Starts playing audio from an iodata, or a stream of iodata

Starts playing audio from a url

Stops playing audio on a guild’s voice connection

Blocks the current process until audio has stopped playing in a guild

Returns which channel the client is connected to in a guild

Types

audio_options :: [{:vol, integer}]

Represents the audio options that can be passed to different play methods.

Options

  • vol audio volume, in %. Can go above 100 to multiply, e.g. 150.
region :: %Alchemy.VoiceRegion{custom: Boolean, deprecated: Boolean, id: snowflake, name: String.t, optimal: Boolean, sample_hostname: String.t, sample_port: Integer, vip: Boolean}

Represents a voice region.

  • id Represent the unique ID for this region.
  • name The name of this region.
  • sample_hostname An example hostname for the region.
  • sample_port An example port for the region.
  • vip True if this is a vip-only server.
  • optimal True for a single server that is closest to the client.
  • deprecated Whether this is a deprecated voice region.
  • custom Whether this is a custom voice region.
state :: %Alchemy.VoiceState{channel_id: snowflake, deaf: Boolean, guild_id: snowflake | nil, mute: Boolean, self_deaf: Boolean, self_mute: Boolean, session_id: String.t, suppress: Boolean, user_id: snowflake}

Represents the state of a user’s voice connection.

  • guild_id The guild id this state is for.
  • channel_id The channel id this user is connected to.
  • user_id The id of the user this state belongs to.
  • session_id The session id for this voice state.
  • deaf Whether this user is deafened by the server.
  • mute Whether this user is muted by the server.
  • self_deaf Whether this user is locally deafened.
  • self_mute Whether this user is locally muted.
  • suppress Whether this user is muted by the current user.

Functions

join(guild, channel, timeout \\ 6000)

Specs

join(snowflake, snowflake, integer) ::
  :ok |
  {:error, String.t}

Joins a voice channel in a guild.

Only one voice connection per guild is possible with the api. If you’re already connected to the guild, this will not restart the voice connections, but instead just move you to the channel.

This function also checks if you’re already connected to this channel, and does nothing if that is the case.

The timeout will be spread across 2 different message receptions, i.e. a timeout of 6000 will only wait 3s at every reception.

leave(guild)

Specs

leave(snowflake) :: :ok | {:error, String.t}

Disconnects from voice in a guild.

Returns an error if the connection hadn’t been established.

listen_for_end(guild)

Specs

listen_for_end(snowflake) :: :ok | {:error, String.t}

Lets this process listen for the end of an audio track in a guild.

This will subscribe this process up until the next time an audio track ends, to react to this, you’ll want to handle the message in some way, e.g.

Voice.listen_for_end(guild)
receive do
  {:audio_stopped, ^guild} -> IO.puts "audio has stopped"
end

This is mainly designed for use in genservers, or other places where you don’t want to block. If you do want to block and wait immediately, try wait_for_end/2 instead.

Examples

Use in a genserver:

def handle_info({:audio_stopped, guild}, state) do
  IO.puts "audio has stopped in #{guild}"
  Voice.listen_for_end(guild)
  {:noreply, state}
end
play_file(guild, file_path, options \\ [])

Specs

play_file(snowflake, Path.t, audio_options) ::
  :ok |
  {:error, String.t}

Starts playing a music file on a guild’s voice connection.

Returns an error if the client isn’t connected to the guild, or if the file does not exist.

Examples

Voice.join("666", "666")
Voice.play_file("666", "cool_song.mp3")
play_iodata(guild, data, options \\ [])

Specs

play_iodata(snowflake, iodata | Enumerable.t, audio_options) ::
  :ok |
  {:error, String.t}

Starts playing audio from an iodata, or a stream of iodata.

Similar to play_url/2 except it doesn’t create a stream from youtube-dl for you.

play_url(guild, url, options \\ [])

Specs

play_url(snowflake, String.t, audio_options) ::
  :ok |
  {:error, String.t}

Starts playing audio from a url.

For this to work, the url must be one of the supported sites. This function does not check the validity of this url, so if it’s invalid, an error will get logged, and no audio will be played.

stop_audio(guild)

Specs

stop_audio(snowflake) :: :ok | {:error, String.t}

Stops playing audio on a guild’s voice connection.

Returns an error if the connection hadn’t been established.

wait_for_end(guild, timeout \\ :infinity)

Specs

wait_for_end(snowflake, integer | :infinity) ::
  :ok |
  {:error, String.t}

Blocks the current process until audio has stopped playing in a guild.

This is a combination of listen_for_end/1 and a receive block, however this will return an error if the provided timeout is exceeded. This is useful for implementing automatic track listing, e.g.

def playlist(guild, tracks) do
  Enum.map(tracks, fn track ->
    Voice.play_file(guild, track)
    Voice.wait_for_end(guild)
  end)
end
which_channel(guild)

Specs

which_channel(snowflake) :: snowflake | nil

Returns which channel the client is connected to in a guild.

Returns nil if there is no connection.