discord-haskell-voice: Voice support for discord-haskell.

[ discord, library, mit, network, program, udp ] [ Propose Tags ] [ Report a vulnerability ]

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


[Skip to Readme]

Flags

Manual Flags

NameDescriptionDefault
use-crypton

Use crypton and crypton-box libraries for encryption instead of saltine, which has a dependency on libsodium. While it may be tempting to use a "pure-Haskell" solution (crypton does have a lot of C though), crypton and crypton-box's security have not been vetted for attacks. Further, Discord themselves use libsodium in their infrastructure, so it's recommended to keep this flag off and use saltine.

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 2.2.0, 2.2.1, 2.2.2, 2.3.0, 2.3.1, 3.0.0
Change log ChangeLog.md
Dependencies aeson (>=1.5 && <1.6 || >=2.0 && <2.3), async (>=2.2.3 && <2.4), base (>=4.7 && <5), binary (>=0.8 && <0.9), BoundedChan (==1.0.3.0), bytestring (>=0.10.12.0 && <0.13), conduit (>=1.3.4.2 && <1.4.0.0), conduit-extra (==1.3.6), discord-haskell (>=1.12.0 && <=1.18.0), discord-haskell-voice, microlens (>=0.4.11.2 && <0.5), microlens-th (>=0.4.3.10 && <0.5), mtl (<2.4), network (>=3.1.1.1 && <3.2), optparse-applicative (>=0.15.1.0 && <0.20), opus (==0.3.0.0), safe-exceptions (>=0.1.7.1 && <0.1.8), saltine (>=0.1.1.1 && <0.3), stm (>=2.5.0.0 && <2.6), stm-containers (<1.4), text (>=1.2.4.1 && <3), time (>=1.9.3 && <1.15), unliftio (>=0.2.18 && <0.3), websockets (>=0.12.7.2 && <0.14), wuss (>=1.1.18 && <2.1.0.0) [details]
License MIT
Copyright Yuto Takano <moa17stock@gmail.com>, discord-haskell-voice Contributors
Author Yuto Takano <moa17stock@gmail.com>
Maintainer Yuto Takano <moa17stock@gmail.com>
Revised Revision 1 made by yutotakano at 2025-07-10T14:27:03Z
Category Network
Home page https://github.com/yutotakano/discord-haskell-voice
Bug tracker https://github.com/yutotakano/discord-haskell-voice/issues
Source repo head: git clone https://github.com/yutotakano/discord-haskell-voice
Uploaded by yutotakano at 2025-03-03T16:59:03Z
Distributions
Executables join-all-on-start, basic-music-bot
Downloads 466 total (4 in the last 30 days)
Rating 2.25 (votes: 2) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user [build log]
All reported builds failed as of 2025-03-03 [all 2 reports]

Readme for discord-haskell-voice-3.0.0

[back to package description]

discord-haskell-voice

hackage version discord-haskell version dependency GitHub Actions Workflow Status

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.

Requirements

  • libsodium: We depend on saltine 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.
  • 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 use createYoutubeResource.
  • ffprobe: It is optional to have FFprobe installed and available in PATH. Without FFprobe, you will not be able to use ProbeCodec to check if a given file, bytestream, or YouTube video can avoid transcoding via FFmpeg if it's already PCM or Opus-encoded.

Features

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.

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.17.1
    , discord-haskell-voice ==3.0.0

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

Documentation

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

Examples

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