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]

Modules

[Last Documentation]

  • Discord
    • Internal
      • Types
        • Discord.Internal.Types.VoiceCommon
        • Discord.Internal.Types.VoiceUDP
        • Discord.Internal.Types.VoiceWebsocket
      • Discord.Internal.Voice
        • Discord.Internal.Voice.CommonUtils
        • Discord.Internal.Voice.UDPLoop
        • Discord.Internal.Voice.WebsocketLoop
    • Discord.Voice
      • Discord.Voice.Conduit

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

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.17.1), 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.19), 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>
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 425 total (12 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
All reported builds failed as of 2025-03-03 [all 1 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).