Add voice guide
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -61,7 +61,7 @@ By now, your module should look like this:
|
||||
|
||||
[IoC]: https://msdn.microsoft.com/en-us/library/ff921087.aspx
|
||||
[Dependency Injection]: https://msdn.microsoft.com/en-us/library/ff921152.aspx
|
||||
[ModuleBase]: xref:Discord.Commands.ModuleBase-1
|
||||
[ModuleBase]: xref:Discord.Commands.ModuleBase`1
|
||||
|
||||
### Adding Commands
|
||||
|
||||
@@ -125,8 +125,8 @@ will not need to cast them.
|
||||
To reply to messages, you may also invoke [ReplyAsync], instead of
|
||||
accessing the channel through the [Context] and sending a message.
|
||||
|
||||
[Context]: xref:Discord.Commands.ModuleBase-1#Discord_Commands_ModuleBase_1_Context
|
||||
[SocketCommandContext]: Discord.Commands.SocketCommandContext
|
||||
[Context]: xref:Discord.Commands.ModuleBase`1#Discord_Commands_ModuleBase_1_Context
|
||||
[SocketCommandContext]: xref:Discord.Commands.SocketCommandContext
|
||||
|
||||
>![WARNING]
|
||||
>Contexts should **NOT** be mixed! You cannot have one module that
|
||||
@@ -149,7 +149,7 @@ Invoke [CommandService.AddModulesAsync] to discover modules and
|
||||
install them.
|
||||
|
||||
[DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute
|
||||
[CommandService.AddModulesAsync]: xref:Discord_Commands_CommandService#AddModulesAsync_System_Reflection_Assembly_
|
||||
[CommandService.AddModulesAsync]: xref:Discord_Commands_CommandService#Discord_Commands_CommandService_AddModulesAsync_Assembly_
|
||||
|
||||
#### Loading Modules Manually
|
||||
|
||||
|
||||
@@ -45,4 +45,6 @@ For more information, go to [MSDN's Async-Await section.](https://msdn.microsoft
|
||||
|
||||
>[!NOTE]
|
||||
>In previous versions of Discord.Net, you had to hook into the `Ready` and `GuildAvailable` events to determine when your client was ready for use.
|
||||
>In 1.0, the [ConnectAsync](xref:Discord.DiscordSocketClient#ConnectAsync) method will automatically wait for the Ready event, and for all guilds to stream. To avoid this, pass `false` into `ConnectAsync`.
|
||||
>In 1.0, the [ConnectAsync] method will automatically wait for the Ready event, and for all guilds to stream. To avoid this, pass `false` into `ConnectAsync`.
|
||||
|
||||
[ConnectAsync]: xref:Discord.WebSocket.DiscordSocketClient#Discord_WebSocket_DiscordSocketClient_ConnectAsync_System_Boolean_
|
||||
11
docs/guides/samples/audio_create_ffmpeg.cs
Normal file
11
docs/guides/samples/audio_create_ffmpeg.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
private Process CreateStream(string path)
|
||||
{
|
||||
var ffmpeg = new ProcessStartInfo
|
||||
{
|
||||
FileName = "ffmpeg",
|
||||
Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
};
|
||||
return Process.Start(ffmpeg);
|
||||
}
|
||||
9
docs/guides/samples/audio_ffmpeg.cs
Normal file
9
docs/guides/samples/audio_ffmpeg.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
private async Task SendAsync(IAudioClient client, string path)
|
||||
{
|
||||
// Create FFmpeg using the previous example
|
||||
var ffmpeg = CreateStream(path);
|
||||
var output = ffmpeg.StandardOutput.BaseStream;
|
||||
var discord = client.CreatePCMStream(1920);
|
||||
await output.CopyToAsync(discord);
|
||||
await discord.FlushAsync();
|
||||
}
|
||||
@@ -1,15 +1,10 @@
|
||||
// Create an IAudioClient, and store it for later use
|
||||
private IAudioClient _audio;
|
||||
|
||||
// Create a Join command, that will join the parameter or the user's current voice channel
|
||||
[Command("join")]
|
||||
public async Task JoinChannel(IUserMessage msg,
|
||||
IVoiceChannel channel = null)
|
||||
public async Task JoinChannel(IVoiceChannel channel = null)
|
||||
{
|
||||
// Get the audio channel
|
||||
channel = channel ?? (msg.Author as IGuildUser)?.VoiceChannel;
|
||||
if (channel == null) { await msg.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; }
|
||||
|
||||
// Get the IAudioClient by calling the JoinAsync method
|
||||
_audio = await channel.JoinAsync();
|
||||
// For the next step with transmitting audio, you would want to pass this Audio Client in to a service.
|
||||
var audioClient = await channel.ConnectAsync();
|
||||
}
|
||||
@@ -7,22 +7,105 @@
|
||||
|
||||
## Installation
|
||||
|
||||
To use Audio, you must first configure your `DiscordSocketClient` with Audio support.
|
||||
To use Audio, you must first configure your [DiscordSocketClient]
|
||||
with Audio support.
|
||||
|
||||
In your @Discord.DiscordSocketConfig, set `AudioMode` to the appropriate @Discord.Audio.AudioMode for your bot. For most bots, you will only need to use `AudioMode.Outgoing`.
|
||||
In your [DiscordSocketConfig], set `AudioMode` to the appropriate
|
||||
[AudioMode] for your bot. For most bots, you will only need to use
|
||||
`AudioMode.Outgoing`.
|
||||
|
||||
[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient
|
||||
[DiscordSocketConfig]: xref:Discord.WebSocket.DiscordSocketConfig
|
||||
[AudioMode]: xref:Discord.Audio.AudioMode
|
||||
|
||||
### Dependencies
|
||||
|
||||
Audio requires two native libraries, `libsodium` and `opus`. Both of these libraries must be placed in the runtime directory of your bot (for .NET 4.6, the directory where your exe is located; for .NET core, directory where your project.json is located)
|
||||
Audio requires two native libraries, `libsodium` and `opus`.
|
||||
Both of these libraries must be placed in the runtime directory of your
|
||||
bot. (When developing on .NET Framework, this would be `bin/debug`,
|
||||
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/)
|
||||
For Windows Users, precompiled binaries are available for your
|
||||
convienence [here](https://discord.foxbot.me/binaries/)
|
||||
|
||||
For Linux Users, you will need to compile from source. [Sodium Source Code](https://download.libsodium.org/libsodium/releases/), [Opus Source Code](http://downloads.xiph.org/releases/opus/).
|
||||
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/
|
||||
|
||||
## Joining a Channel
|
||||
|
||||
Joining Voice Channels is relatively straight-forward, and is a requirement for sending or receiving audio. This will also allow us to create an @Discord.Audio.IAudioClient, which will be used later to send or receive audio.
|
||||
Joining a channel is the first step to sending audio, and will return
|
||||
an [IAudioClient] to send data with.
|
||||
|
||||
To join a channel, simply await [ConnectAsync] on any instance of an
|
||||
@Discord.IVoiceChannel.
|
||||
|
||||
[!code-csharp[Joining a Channel](samples/joining_audio.cs)]
|
||||
|
||||
The client will sustain a connection to this channel until it is kicked, disconnected from Discord, or told to disconnect.
|
||||
The client will sustain a connection to this channel until it is
|
||||
kicked, disconnected from Discord, or told to disconnect.
|
||||
|
||||
It should be noted that voice connections are created on a per-guild
|
||||
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.IVoiceChannel#Discord_IVoiceChannel_ConnectAsync
|
||||
|
||||
## Transmitting Audio
|
||||
|
||||
### With FFmpeg
|
||||
|
||||
[FFmpeg] is an open source, highly versatile AV-muxing tool. This is
|
||||
the recommended method of transmitting audio.
|
||||
|
||||
Before you begin, you will need to have a version of FFmpeg downloaded
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
[!code-csharp[Creating FFmpeg](samples/audio_create_ffmpeg.cs)]
|
||||
|
||||
Next, to transmit audio from FFmpeg to Discord, you will need to
|
||||
pull an [AudioOutStream] from your [IAudioClient]. Since we're using
|
||||
PCM audio, use [IAudioClient.CreatePCMStream].
|
||||
|
||||
The sample rate argument doesn't particularly matter, so long as it is
|
||||
a valid rate (120, 240, 480, 960, 1920, or 2880). For the sake of
|
||||
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_CreatePCMStream_System_Int32_System_Int32_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
|
||||
|
||||
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
|
||||
to the next song. You can await `AudioOutStream.FlushAsync` to wait for
|
||||
the audio client's internal buffer to clear out.
|
||||
|
||||
[!code-csharp[Sending Audio](samples/audio_ffmpeg.cs)]
|
||||
Reference in New Issue
Block a user