Welcome to discord-haskell-voice
! This library provides you with a high-level
interface for interacting with Discord's Voice API, building on top of the
discord-haskell
library.
For a quick intuitive introduction to what this library enables you to do, see the following snippet of code:
rickroll :: Channel -> DiscordHandler ()
rickroll c@(ChannelVoice {}) = do
runVoice $ do
join (channelGuild c) (channelId c)
res <- createYoutubeResource "https://www.youtube.com/watch?v=dQw4w9WgXcQ" Nothing
play res UnknownCodec
The library actively uses and supports conduit, which enables you to write something like the following as well! (Spoiler: it plays 'Never Gonna Give You Up' by Rick Astley at half the volume then prints to stdout.)
rickrollHalfVolume :: Channel -> DiscordHandler ()
rickrollHalfVolume c@(ChannelVoice {}) = do
runVoice $ do
join (channelGuild c) (channelId c)
let halfAmplitude = awaitForever $ \current ->
yield $ round $ fromIntegral current * 0.5
res <- createYoutubeResource "rickroll" $ HaskellTransformation $ packInt16C .| halfAmplitude .| unpackInt16C
play res UnknownCodec
liftIO $ print "finished playing!"
Scroll down for a more in-depth features list.
libsodium
: We depend onsaltine
for encryption and decryption of audio packets. This is a NaCl binding and thus requires libsodium to be installed on your system. See their README for installation information.- An alternative is provided via a compile flag, which is to use
crypton
as a backend instead, which requires no native dependencies. The security of this library has not been vetted however, so use with caution.
- An alternative is provided via a compile flag, which is to use
libopus
: We require Opus libraries to be installed on your system. Please follow the README of the Haskell Opus package.ffmpeg
: It is heavily recommended to have FFmpeg installed and available in PATH. Without FFmpeg, you will not be able to transcode any non-PCM non-Opus files, bytestrings, or YouTube media.yt-dlp
: It is equally heavily recommended to have yt-dlp installed and available in PATH. Without yt-dlp, you will not be able to usecreateYoutubeResource
.ffprobe
: It is optional to have FFprobe installed and available in PATH. Without FFprobe, you will not be able to useProbeCodec
to check if a given file, bytestream, or YouTube video can avoid transcoding via FFmpeg if it's already PCM or Opus-encoded.
What is supported:
- Can join/leave Discord voice channels.
- Can join multiple of them simultaneously (one per sever) and stream different content to each.
- Can join many voice channels (across many servers) and simulcast the same content, radio/subscriber-style.
- Can play arbitrary PCM/Opus audio from a file or byte stream
- Can play arbitrary audio using FFmpeg to transcode
- Can intelligently skip transcoding based on source format using ffprobe
- Can play arbitrary internet audio using yt-dlp, including live streams
- Can transform audio arbitrarily using either FFmpeg flags or Conduits that operate on bytestreams
- As it streams content, the library should use constant memory (unverified)
Where possible, specific details like method of encryption, protocol handshakes, packet encoding etc have been abstracted away. As a result, this library is able to offer a high-level productive API interface similar to discord.js and discord.py libraries.
What is not supported:
- Decrypting audio packets sent from Discord (other people's voices), and decoding them to PCM. This isn't particularly well-documented by Discord and will thus likely never be supported by this library.
This library is available on Hackage, at https://hackage.haskell.org/package/discord-haskell-voice.
To use it in your Cabal-based project, add discord-haskell-voice
as a
dependency in your .cabal
file:
# --- myproject.cabal <truncated>
build-depends:
base >=4.7 && <5
, discord-haskell ==1.17.1
, discord-haskell-voice ==3.0.0
To use it in your Stack-based project, add discord-haskell-voice
in both your
package.yaml
and stack.yaml
files (since this library is not available in
Stackage for the same reason discord-haskell
is not on Stackage):
# --- stack.yaml <truncated>
extra-deps:
- discord-haskell-1.17.1
- discord-haskell-voice-3.0.0
# --- package.yaml <truncated>
dependencies:
- base >= 4.7 && < 5
- discord-haskell == 1.17.1
- discord-haskell-voice == 3.0.0
See the Haddock documentation on the Hackage page, at https://hackage.haskell.org/package/discord-haskell-voice/docs/Discord-Voice.html.
See examples/BasicMusicBot.hs
for a bot that uses many advanced features of
the library, including dynamically adjusting the stream audio using a TVar
(and allowing users to change the TVar using a /volume
command).