MyNixOS website logo
Description

Voice support for discord-haskell.

Supplementary library to discord-haskell. See the project README on GitHub for more information. https://github.com/yutotakano/discord-haskell-voice

discord-haskell-voice

hackage version discord-haskell version dependency

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 by Karl.

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
    void $ runVoice $ do
        join (channelGuild c) (channelId c)
        playYouTube "https://www.youtube.com/watch?v=dQw4w9WgXcQ"

The library actively uses and supports conduit, which enables you to write something like the following as well!

rickrollHalfVolume :: Channel -> DiscordHandler ()
rickrollHalfVolume c@(ChannelVoice {}) = do
    void $ runVoice $ do
        join (channelGuild c) (channelId c)
        let halfAmplitude = awaitForever $ \current ->
                yield $ round $ fromIntegral current * 0.5
        playYouTube' "rickroll" $ packInt16C .| halfAmplitude .| unpackInt16C
        liftIO $ print "finished playing!"

Requirements

  • The library uses saltine for encryption and decryption of audio packets. This requires libsodium to be installed on your system. See their README for information.
  • The library requires Opus libraries to be installed on your system. The libopus-dev package available on package repositories should be sufficient on most *nix systems. The opus brew package suffices on Mac. Windows is unexplored yet (WSL works).
  • If you are to use any variants of playFile, playYouTube, you will need FFmpeg installed. To specify a custom executable name, see the -With function variants.
  • If you are to use any variants of playYouTube, you will additionally need youtube-dl installed. This is used to get the stream URL to pass to FFmpeg. To specify a custom executable name (such as yt-dlp), use playYouTubeWith.

Features

What is supported:

  • Can join/leave Discord voice channels. It is possible to join multiple of them simultaneously (one per sever) and stream different contents to each.
  • It is also possible to join many voice channels (across many servers) and play the same content, radio/subscriber-style.
  • You can play arbitrary PCM audio, arbitrary audio (with FFmpeg), and arbitrary internet audio (with youtube-dl).
  • You can transform audio arbitrarily using Conduit.
  • As it streams content, the library /should/ use constant memory (unverified).
  • OPUS encoding and specific implementation details such as handshakes and encryption are done opaquely, and a nice abstraction layer is provided.

What is not supported:

  • Decrypting audio packets sent from Discord (other people's voices), and decoding them to PCM.

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).

Installation

This library is available on Hackage, at https://hackage.haskell.org/package/discord-haskell-voice.

Cabal

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.14.0
    , discord-haskell-voice ==2.3.1

Stack

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.14.0
- discord-haskell-voice-2.3.1
# --- package.yaml <truncated>
dependencies:
- base >= 4.7 && < 5
- discord-haskell == 1.14.0
- discord-haskell-voice == 2.3.1

Documentation

See the Haddock documentation on the Hackage page, at https://hackage.haskell.org/package/discord-haskell-voice/docs/Discord-Voice.html.

Future Plans

  • Use stm-conduit and stm for a safer Chan?
  • Look into SubprocessException seemingly never been thrown (e.g. when SIGINT is signalled to the libarry while FFmpeg is running)
  • Consider, document, and improve the distinction of errors (VoiceError) vs exceptions, and note down why any choices are made.
Metadata

Version

2.3.1

License

Platforms (77)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows