summaryrefslogtreecommitdiff
path: root/DiscoBot
diff options
context:
space:
mode:
Diffstat (limited to 'DiscoBot')
-rw-r--r--DiscoBot/Audio.cs27
-rw-r--r--DiscoBot/AudioService.cs88
-rw-r--r--DiscoBot/Commands.cs90
-rw-r--r--DiscoBot/DSA.cs3
-rw-r--r--DiscoBot/DiscoBot.csproj2
-rw-r--r--DiscoBot/Program.cs9
6 files changed, 208 insertions, 11 deletions
diff --git a/DiscoBot/Audio.cs b/DiscoBot/Audio.cs
new file mode 100644
index 0000000..68c860c
--- /dev/null
+++ b/DiscoBot/Audio.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DiscoBot
+{
+ using System.Diagnostics;
+
+ class Audio
+ {
+ 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);
+ }
+ }
+
+
+}
diff --git a/DiscoBot/AudioService.cs b/DiscoBot/AudioService.cs
new file mode 100644
index 0000000..bb4d21e
--- /dev/null
+++ b/DiscoBot/AudioService.cs
@@ -0,0 +1,88 @@
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.IO;
+using System.Threading.Tasks;
+using Discord;
+using Discord.Audio;
+
+namespace DiscoBot
+{
+ public class AudioService
+ {
+ private readonly ConcurrentDictionary<ulong, IAudioClient> ConnectedChannels =
+ new ConcurrentDictionary<ulong, IAudioClient>();
+
+ public async Task JoinAudio(IGuild guild, IVoiceChannel target)
+ {
+ IAudioClient client;
+ if (ConnectedChannels.TryGetValue(guild.Id, out client))
+ {
+ return;
+ }
+
+ if (target.Guild.Id != guild.Id)
+ {
+ return;
+ }
+
+ var audioClient = await target.ConnectAsync();
+
+ if (ConnectedChannels.TryAdd(guild.Id, audioClient))
+ {
+ // If you add a method to log happenings from this service,
+ // you can uncomment these commented lines to make use of that.
+ //await Log(LogSeverity.Info, $"Connected to voice on {guild.Name}.");
+ }
+ }
+
+ public async Task LeaveAudio(IGuild guild)
+ {
+ IAudioClient client;
+ if (ConnectedChannels.TryRemove(guild.Id, out client))
+ {
+ await client.StopAsync();
+ //await Log(LogSeverity.Info, $"Disconnected from voice on {guild.Name}.");
+ }
+ }
+
+ public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path)
+ {
+ // Your task: Get a full path to the file if the value of 'path' is only a filename.
+ if (!File.Exists(path))
+ {
+ await channel.SendMessageAsync("File does not exist.");
+ return;
+ }
+
+ IAudioClient client;
+ if (ConnectedChannels.TryGetValue(guild.Id, out client))
+ {
+ //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}");
+ using (var ffmpeg = Process.Start(path))
+ using (var stream = client.CreatePCMStream(AudioApplication.Music))
+ {
+ try
+ {
+ await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream);
+ }
+ finally
+ {
+ await stream.FlushAsync();
+ }
+ }
+ }
+ }
+
+ private Process CreateStream(string path)
+ {
+ return Process.Start(
+ new ProcessStartInfo
+ {
+ FileName = "ffmpeg.exe",
+ Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1",
+ UseShellExecute = false,
+ RedirectStandardOutput = true
+ });
+ }
+ }
+}
diff --git a/DiscoBot/Commands.cs b/DiscoBot/Commands.cs
index 55ad530..6ba2b8a 100644
--- a/DiscoBot/Commands.cs
+++ b/DiscoBot/Commands.cs
@@ -11,9 +11,12 @@ using Discord.WebSocket;
namespace DiscoBot
{
using System.ComponentModel;
+ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
+ using Discord.Audio;
+
public class Info : ModuleBase
{
[Command("say"), Summary("Echos a message.")]
@@ -123,24 +126,57 @@ namespace DiscoBot
public class Voice : ModuleBase
{
- [Command("join")]
+ public static IAudioClient client { get; set; }
+ [Command("join", RunMode = RunMode.Async)]
public async Task JoinChannel(IVoiceChannel channel = null)
{
+ var msg = this.Context.Message;
// Get the audio channel
- channel = channel ?? (this.Context.User as IGuildUser)?.VoiceChannel;
- if (channel == null)
- {
- await this.Context.Channel.SendMessageAsync(
- "User must be in a voice channel, or a voice channel must be passed as an argument.");
- return;
- }
+ 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; }
// For the next step with transmitting audio, you would want to pass this Audio Client in to a service.
var audioClient = await channel.ConnectAsync();
-
+ client = audioClient;
+ }
+
+ [Command("leave", RunMode = RunMode.Async)]
+ public async Task LeaveChannel(IVoiceChannel channel = null)
+ {
+ // For the next step with transmitting audio, you would want to pass this Audio Client in to a service.
+ client.StopAsync();
+ }
+
+ [Command("play")]
+ public async Task PlayAudio(string path)
+ {
+ SendAsync(client, path);
+ }
+
+ private Process CreateStream(string path)
+ {
+ var ffmpeg = new ProcessStartInfo
+ {
+ FileName = "ffmpeg",
+ Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 -ab 620000 pipe:1",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ };
+ return Process.Start(ffmpeg);
+ }
+
+ 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(AudioApplication.Music);
+ await output.CopyToAsync(discord);
+ await discord.FlushAsync();
}
}
+
[Group("gmtr")]
public class Sample : ModuleBase
{
@@ -364,6 +400,42 @@ namespace DiscoBot
}
}
+ /*public class AudioModule : ModuleBase<ICommandContext>
+ {
+ // Scroll down further for the AudioService.
+ // Like, way down
+ private readonly AudioService _service;
+
+ // Remember to add an instance of the AudioService
+ // to your IServiceCollection when you initialize your bot
+ public AudioModule(AudioService service)
+ {
+ _service = service;
+ }
+
+ // You *MUST* mark these commands with 'RunMode.Async'
+ // otherwise the bot will not respond until the Task times out.
+ [Command("join", RunMode = RunMode.Async)]
+ public async Task JoinCmd()
+ {
+ await _service.JoinAudio(Context.Guild, (Context.User as IVoiceState).VoiceChannel);
+ }
+
+ // Remember to add preconditions to your commands,
+ // this is merely the minimal amount necessary.
+ // Adding more commands of your own is also encouraged.
+ [Command("leave", RunMode = RunMode.Async)]
+ public async Task LeaveCmd()
+ {
+ await _service.LeaveAudio(Context.Guild);
+ }
+
+ [Command("play", RunMode = RunMode.Async)]
+ public async Task PlayCmd([Remainder] string song)
+ {
+ await _service.SendAudioAsync(Context.Guild, Context.Channel, song);
+ }
+ }*/
public enum Commands
{
diff --git a/DiscoBot/DSA.cs b/DiscoBot/DSA.cs
index 60b25ce..af02023 100644
--- a/DiscoBot/DSA.cs
+++ b/DiscoBot/DSA.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+ using System.Threading.Tasks;
using Discord.Commands;
@@ -14,7 +15,7 @@
public static List<Talent> Talente { get; set; } = new List<Talent>();
- public static void Startup()
+ public static async Task Startup()
{
relation.Add("The Doctor", "Numeri Illuminus");//Relation
relation.Add("Tardis", "Morla");//"Numeri Illuminus");
diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj
index 91ce25e..d0fc986 100644
--- a/DiscoBot/DiscoBot.csproj
+++ b/DiscoBot/DiscoBot.csproj
@@ -140,6 +140,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Audio.cs" />
+ <Compile Include="AudioService.cs" />
<Compile Include="Character.cs" />
<Compile Include="CommandExtension.cs" />
<Compile Include="Commands.cs" />
diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs
index b90ed54..7ae8244 100644
--- a/DiscoBot/Program.cs
+++ b/DiscoBot/Program.cs
@@ -24,7 +24,7 @@ namespace DiscoBot
public async Task Start()
{
- DSA.Startup();
+ var loading = DSA.Startup();
client = new DiscordSocketClient();
commands = new CommandService();
@@ -32,12 +32,14 @@ namespace DiscoBot
services = new ServiceCollection()
.BuildServiceProvider();
+ AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
await InstallCommands();
await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();
+ await loading;
await Task.Delay(-1);
}
@@ -66,6 +68,11 @@ namespace DiscoBot
if (!result.IsSuccess)
await context.Channel.SendMessageAsync(result.ErrorReason);
}
+ static void OnProcessExit(object sender, EventArgs e)
+ {
+ Console.WriteLine("I'm out of here");
+ Voice.client.StopAsync();
+ }
}
}