Browse Source

Add voice guide

tags/1.0-rc
Christopher F 8 years ago
parent
commit
6a0f41a4dc
7 changed files with 121 additions and 21 deletions
  1. +1
    -1
      docs/api/.manifest
  2. +4
    -4
      docs/guides/commands.md
  3. +3
    -1
      docs/guides/intro.md
  4. +11
    -0
      docs/guides/samples/audio_create_ffmpeg.cs
  5. +9
    -0
      docs/guides/samples/audio_ffmpeg.cs
  6. +3
    -8
      docs/guides/samples/joining_audio.cs
  7. +90
    -7
      docs/guides/voice.md

+ 1
- 1
docs/api/.manifest
File diff suppressed because it is too large
View File


+ 4
- 4
docs/guides/commands.md View File

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



+ 3
- 1
docs/guides/intro.md View File

@@ -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
- 0
docs/guides/samples/audio_create_ffmpeg.cs View 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
- 0
docs/guides/samples/audio_ffmpeg.cs View 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();
}

+ 3
- 8
docs/guides/samples/joining_audio.cs View File

@@ -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();
}

+ 90
- 7
docs/guides/voice.md View File

@@ -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 [Sodium] and [Opus] from
source, or install them from your package manager.

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/).
[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)]

Loading…
Cancel
Save