Skip to content

Voice Support

So you want to start playing some 🎵tunes🎶 in voice channels? Well let's get that going for you.

First you're going to want to get the voice dependencies installed:

1
pip install discord.py-interactions[voice]

Then you'll need to download FFmpeg and place it in your project directory or PATH.

Now you've got those; let's make a simple play command to get you started.

First you're going to want to get the voice dependencies installed:

1
pip install discord.py-interactions[voice]

Then you'll need to install the following packages: libnacl, libffi, and FFmpeg

For debian based distros:

1
sudo apt install ffmpeg libffi-dev libnacl-dev
For arch based distros:
1
sudo pacman -S ffmpeg libffi libnacl
For fedora based distros:
1
sudo dnf install ffmpeg libffi-devel libsodium-devel

If you get an error about "Could not find opus library," your distro may not have libopus installed. You'll need to find documentation for your distro on how to install it.

Now you've got those; let's make a simple play command to get you started.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import interactions
from interactions.api.voice.audio import AudioVolume


@interactions.slash_command("play", "play a song!")
@interactions.slash_option("song", "The song to play", 3, True)
async def play(self, ctx: interactions.SlashContext, song: str):
    if not ctx.voice_state:
        # if we haven't already joined a voice channel
        # join the authors vc
        await ctx.author.voice.channel.connect()

    # Get the audio using YTDL
    audio = await AudioVolume(song)
    await ctx.send(f"Now Playing: **{song}**")
    # Play the audio
    await ctx.voice_state.play(audio)

Now just join a voice channel, and type run the "play" slash command with a song of your choice.

Congratulations! You've got a music-bot.

But what about local music?

If you want to play your own files, you can do that too! Create an AudioVolume object and away you go.

Note

If your audio is already encoded, use the standard Audio object instead. You'll lose volume manipulation, however.

1
2
3
4
5
6
7
8
import interactions
from interactions.api.voice.audio import AudioVolume


@interactions.slash_command("play", "play a song!")
async def play_file(ctx: interactions.SlashContext):
    audio = AudioVolume("some_file.wav")
    await ctx.voice_state.play(audio)

Check out Active Voice State for a list of available methods and attributes.

Voice Recording

So you've got a bot that can play music, but what about recording? Well, you're in luck! We've got you covered.

Let's start with a simple example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import asyncio
import interactions

@interactions.slash_command("record", "record some audio")
async def record(ctx: interactions.SlashContext):
    voice_state = await ctx.author.voice.channel.connect()

    # Start recording
    await voice_state.start_recording()
    await asyncio.sleep(10)
    await voice_state.stop_recording()
    await ctx.send(files=[interactions.File(file, file_name="user_id.mp3") for user_id, file in voice_state.recorder.output.items()])
This code will connect to the author's voice channel, start recording, wait 10 seconds, stop recording, and send a file for each user that was recorded.

But what if you didn't want to use mp3 files? Well, you can change that too! Just pass the encoding you want to use to start_recording.

1
await voice_state.start_recording(encoding="wav")

For a list of available encodings, check out Recorder's documentation

Are you going to be recording for a long time? You are going to want to write the files to disk instead of keeping them in memory. You can do that too!

1
await voice_state.start_recording(output_dir="folder_name")
This will write the files to the folder folder_name in the current working directory, please note that the library will not create the folder for you, nor will it delete the files when you're done.