|
|
@@ -5,9 +5,9 @@ title: Sending Voice |
|
|
|
|
|
|
|
**Information on this page is subject to change!** |
|
|
|
|
|
|
|
>[!WARNING] |
|
|
|
>This article is out of date, and has not been rewritten yet. |
|
|
|
Information is not guaranteed to be accurate. |
|
|
|
> [!WARNING] |
|
|
|
> This article is out of date, and has not been rewritten yet. |
|
|
|
> Information is not guaranteed to be accurate. |
|
|
|
|
|
|
|
## Installing |
|
|
|
|
|
|
@@ -18,13 +18,13 @@ when developing on .NET Core, this is where you execute `dotnet run` |
|
|
|
from; typically the same directory as your csproj). |
|
|
|
|
|
|
|
For Windows Users, precompiled binaries are available for your |
|
|
|
convienence [here](https://discord.foxbot.me/binaries/). |
|
|
|
convienence [here](https://github.com/discord-net/Discord.Net/tree/dev/voice-natives). |
|
|
|
|
|
|
|
For Linux Users, you will need to compile [Sodium] and [Opus] from |
|
|
|
source, or install them from your package manager. |
|
|
|
|
|
|
|
[Sodium]: https://download.libsodium.org/libsodium/releases/ |
|
|
|
[Opus]: http://downloads.xiph.org/releases/opus/ |
|
|
|
[sodium]: https://download.libsodium.org/libsodium/releases/ |
|
|
|
[opus]: http://downloads.xiph.org/releases/opus/ |
|
|
|
|
|
|
|
## Joining a Channel |
|
|
|
|
|
|
@@ -36,13 +36,13 @@ To join a channel, simply await [ConnectAsync] on any instance of an |
|
|
|
|
|
|
|
[!code-csharp[Joining a Channel](samples/joining_audio.cs)] |
|
|
|
|
|
|
|
>[!WARNING] |
|
|
|
>Commands which mutate voice states, such as those where you join/leave |
|
|
|
>an audio channel, or send audio, should use [RunMode.Async]. RunMode.Async |
|
|
|
>is necessary to prevent a feedback loop which will deadlock clients |
|
|
|
>in their default configuration. If you know that you're running your |
|
|
|
>commands in a different task than the gateway task, RunMode.Async is |
|
|
|
>not required. |
|
|
|
> [!WARNING] |
|
|
|
> Commands which mutate voice states, such as those where you join/leave |
|
|
|
> an audio channel, or send audio, should use [RunMode.Async]. RunMode.Async |
|
|
|
> is necessary to prevent a feedback loop which will deadlock clients |
|
|
|
> in their default configuration. If you know that you're running your |
|
|
|
> commands in a different task than the gateway task, RunMode.Async is |
|
|
|
> not required. |
|
|
|
|
|
|
|
The client will sustain a connection to this channel until it is |
|
|
|
kicked, disconnected from Discord, or told to disconnect. |
|
|
@@ -52,9 +52,9 @@ basis; only one audio connection may be open by the bot in a single |
|
|
|
guild. To switch channels within a guild, invoke [ConnectAsync] on |
|
|
|
another voice channel in the guild. |
|
|
|
|
|
|
|
[IAudioClient]: xref:Discord.Audio.IAudioClient |
|
|
|
[ConnectAsync]: xref:Discord.IAudioChannel.ConnectAsync* |
|
|
|
[RunMode.Async]: xref:Discord.Commands.RunMode |
|
|
|
[iaudioclient]: xref:Discord.Audio.IAudioClient |
|
|
|
[connectasync]: xref:Discord.IAudioChannel.ConnectAsync* |
|
|
|
[runmode.async]: xref:Discord.Commands.RunMode |
|
|
|
|
|
|
|
## Transmitting Audio |
|
|
|
|
|
|
@@ -68,17 +68,17 @@ and placed somewhere in your PATH (or alongside the bot, in the same |
|
|
|
location as libsodium and opus). Windows binaries are available on |
|
|
|
[FFmpeg's download page]. |
|
|
|
|
|
|
|
[FFmpeg]: https://ffmpeg.org/ |
|
|
|
[FFmpeg's download page]: https://ffmpeg.org/download.html |
|
|
|
[ffmpeg]: https://ffmpeg.org/ |
|
|
|
[ffmpeg's download page]: https://ffmpeg.org/download.html |
|
|
|
|
|
|
|
First, you will need to create a Process that starts FFmpeg. An |
|
|
|
example of how to do this is included below, though it is important |
|
|
|
that you return PCM at 48000hz. |
|
|
|
|
|
|
|
>[!NOTE] |
|
|
|
>As of the time of this writing, Discord.Audio struggles significantly |
|
|
|
>with processing audio that is already opus-encoded; you will need to |
|
|
|
>use the PCM write streams. |
|
|
|
> [!NOTE] |
|
|
|
> As of the time of this writing, Discord.Audio struggles significantly |
|
|
|
> with processing audio that is already opus-encoded; you will need to |
|
|
|
> use the PCM write streams. |
|
|
|
|
|
|
|
[!code-csharp[Creating FFmpeg](samples/audio_create_ffmpeg.cs)] |
|
|
|
|
|
|
@@ -93,15 +93,15 @@ simplicity, I recommend using 1920. |
|
|
|
Channels should be left at `2`, unless you specified a different value |
|
|
|
for `-ac 2` when creating FFmpeg. |
|
|
|
|
|
|
|
[AudioOutStream]: xref:Discord.Audio.AudioOutStream |
|
|
|
[IAudioClient.CreatePCMStream]: xref:Discord.Audio.IAudioClient#Discord_Audio_IAudioClient_CreateDirectPCMStream_Discord_Audio_AudioApplication_System_Nullable_System_Int32__System_Int32_ |
|
|
|
[audiooutstream]: xref:Discord.Audio.AudioOutStream |
|
|
|
[iaudioclient.createpcmstream]: xref:Discord.Audio.IAudioClient#Discord_Audio_IAudioClient_CreateDirectPCMStream_Discord_Audio_AudioApplication_System_Nullable_System_Int32__System_Int32_ |
|
|
|
|
|
|
|
Finally, audio will need to be piped from FFmpeg's stdout into your |
|
|
|
AudioOutStream. This step can be as complex as you'd like it to be, but |
|
|
|
for the majority of cases, you can just use [Stream.CopyToAsync], as |
|
|
|
shown below. |
|
|
|
|
|
|
|
[Stream.CopyToAsync]: https://msdn.microsoft.com/en-us/library/hh159084(v=vs.110).aspx |
|
|
|
[stream.copytoasync]: https://msdn.microsoft.com/en-us/library/hh159084(v=vs.110).aspx |
|
|
|
|
|
|
|
If you are implementing a queue for sending songs, it's likely that |
|
|
|
you will want to wait for audio to stop playing before continuing on |
|
|
|