summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrueDoctor <d-kobert@web.de>2018-04-11 14:19:57 +0200
committerTrueDoctor <d-kobert@web.de>2018-04-11 14:19:57 +0200
commit351067a5203307fc0c1a14ae2be84eae71246af9 (patch)
treea17b63d94b41c87215a03fd2a19edab9f4d53c30
parentaa236f67bf1829e2a7c6e9a5f82d109b39147b11 (diff)
Added possibillity for service based soundplaying
-rw-r--r--DiscoBot/Audio/AudioModule.cs72
-rw-r--r--DiscoBot/Audio/AudioService.cs101
-rw-r--r--DiscoBot/Auxiliary/Soundeffects.cs9
-rw-r--r--DiscoBot/Characters/Character.cs10
-rw-r--r--DiscoBot/Commands/Voice.cs24
-rw-r--r--DiscoBot/DSA.cs3
-rw-r--r--DiscoBot/DiscoBot.csproj2
-rw-r--r--DiscoBot/Program.cs3
8 files changed, 207 insertions, 17 deletions
diff --git a/DiscoBot/Audio/AudioModule.cs b/DiscoBot/Audio/AudioModule.cs
new file mode 100644
index 0000000..0c3814f
--- /dev/null
+++ b/DiscoBot/Audio/AudioModule.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Threading.Tasks;
+
+using DiscoBot;
+using DiscoBot.Audio;
+using DiscoBot.Auxiliary;
+using DiscoBot.Commands;
+
+using Discord;
+using Discord.Commands;
+
+public class AudioModule : ModuleBase
+{
+ // 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;
+ Dsa.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)
+ {
+ if (Dsa.GeneralContext == null)
+ {
+ Dsa.GeneralContext = this.Context;
+ }
+
+ var sounds = Enum.GetValues(typeof(Sound));
+ var soundList = new List<Sound>();
+ foreach (var sound in sounds)
+ {
+ soundList.Add((Sound)sound);
+ }
+
+ var sc = new SpellCorrect();
+
+ var tSound = soundList.OrderBy(x => sc.Compare(song, x.ToString())).First();
+
+ if (sc.Compare(song, tSound.ToString()) > SpellCorrect.ErrorThreshold)
+ {
+ await _service.SendAudioAsync(Context.Guild, Context.Channel, song);
+ }
+
+ await SoundEffects.Play(tSound);
+ }
+} \ No newline at end of file
diff --git a/DiscoBot/Audio/AudioService.cs b/DiscoBot/Audio/AudioService.cs
new file mode 100644
index 0000000..25beed0
--- /dev/null
+++ b/DiscoBot/Audio/AudioService.cs
@@ -0,0 +1,101 @@
+namespace DiscoBot.Audio
+{
+ using System.Collections.Concurrent;
+ using System.Diagnostics;
+ using System.IO;
+ using System.Threading.Tasks;
+
+ using Discord;
+ using Discord.Audio;
+
+ public class AudioService
+ {
+ private readonly ConcurrentDictionary<ulong, IAudioClient> connectedChannels = new ConcurrentDictionary<ulong, IAudioClient>();
+
+ public async Task JoinAudio(IGuild guild, IVoiceChannel target)
+ {
+ IAudioClient client;
+ if (this.connectedChannels.TryGetValue(guild.Id, out client))
+ {
+ return;
+ }
+
+ if (target.Guild.Id != guild.Id)
+ {
+ return;
+ }
+
+ var audioClient = await target.ConnectAsync();
+
+ if (this.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 (this.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) && false)
+ {
+ await channel.SendMessageAsync("File does not exist.");
+ return;
+ }
+ IAudioClient client;
+ if (this.connectedChannels.TryGetValue(guild.Id, out client))
+ {
+ //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}");
+ using (var ffmpeg = this.CreateStream(path))
+ using (var stream = client.CreatePCMStream(AudioApplication.Music))
+ {
+ try { await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream); }
+ finally { await stream.FlushAsync(); }
+ }
+ }
+ }
+
+ public async Task SendAudioAsync(string path, int Volume)
+ {
+ // Your task: Get a full path to the file if the value of 'path' is only a filename.
+ if (!File.Exists(path) && false)
+ {
+ //await channel.SendMessageAsync("File does not exist.");
+ return;
+ }
+
+ if (this.connectedChannels.TryGetValue(Dsa.GeneralContext.Guild.Id, out var client))
+ {
+ //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}");
+ using (var ffmpeg = this.CreateStream(path))
+ using (var stream = client.CreatePCMStream(AudioApplication.Voice))
+ {
+ 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/Auxiliary/Soundeffects.cs b/DiscoBot/Auxiliary/Soundeffects.cs
index 3c67fac..c959156 100644
--- a/DiscoBot/Auxiliary/Soundeffects.cs
+++ b/DiscoBot/Auxiliary/Soundeffects.cs
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
namespace DiscoBot.Auxiliary
{
+ using System.Runtime.CompilerServices;
+ using System.Threading;
+
using DiscoBot.Commands;
public enum Sound
@@ -53,11 +56,11 @@ namespace DiscoBot.Auxiliary
if (url != string.Empty)
{
- Task.Run(() => Voice.SendAsync(url, vol));
- return;
+ // await Dsa.Service.SendAudioAsync(url, vol);
+ await Voice.SendAsync(url, vol);
}
- await Dsa.GeneralContext.Channel.SendMessageAsync("Ton Existiert nicht");
+ throw new Exception("Ton Existiert nicht");
}
}
}
diff --git a/DiscoBot/Characters/Character.cs b/DiscoBot/Characters/Character.cs
index 2915622..6884eaf 100644
--- a/DiscoBot/Characters/Character.cs
+++ b/DiscoBot/Characters/Character.cs
@@ -76,7 +76,7 @@
if (sc.Compare(talent, tTalent.Name) > SpellCorrect.ErrorThreshold)
{
- SoundEffects.Play(Sound.Wrong);
+ SoundEffects.Play(Sound.Wrong).Wait();
return $"{this.Name} kann nicht {talent}...";
}
@@ -139,7 +139,7 @@
if(tap < 0)
{
- SoundEffects.Play(Sound.Wrong);
+ SoundEffects.Play(Sound.Wrong).Wait();
}
output.AppendFormat(" tap: {0,2}", tap);
@@ -174,7 +174,7 @@
var attack = this.Kampftalente.OrderBy(x => sc.Compare(talent, x.Name)).First();
if (sc.Compare(talent, attack.Name) > SpellCorrect.ErrorThreshold)
{
- SoundEffects.Play(Sound.Wrong);
+ SoundEffects.Play(Sound.Wrong).Wait();
return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen...";
}
@@ -198,7 +198,7 @@
if (sc.Compare(talent, attack.Name) > SpellCorrect.ErrorThreshold)
{
- SoundEffects.Play(Sound.Wrong);
+ SoundEffects.Play(Sound.Wrong).Wait();
return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen...";
}
@@ -222,7 +222,7 @@
var attack = this.Talente.OrderBy(x => sc.Compare(talent, x.Name)).First();
if (sc.Compare(talent, attack.Name) > SpellCorrect.ErrorThreshold)
{
- SoundEffects.Play(Sound.Wrong);
+ SoundEffects.Play(Sound.Wrong).Wait();
return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen...";
}
diff --git a/DiscoBot/Commands/Voice.cs b/DiscoBot/Commands/Voice.cs
index 7ffb029..9e94a30 100644
--- a/DiscoBot/Commands/Voice.cs
+++ b/DiscoBot/Commands/Voice.cs
@@ -2,11 +2,14 @@
{
using System;
using System.Collections.Generic;
+ using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Media;
+ using System.Threading;
using System.Threading.Tasks;
+ using DiscoBot.Audio;
using DiscoBot.Auxiliary;
using Discord;
@@ -27,12 +30,16 @@
// Create FFmpeg using the previous example
var ffmpeg = CreateStream(path, volume);
var output = ffmpeg.StandardOutput.BaseStream;
-
- var discord = Client.CreatePCMStream(AudioApplication.Music);
- await output.CopyToAsync(discord);
-
- await discord.FlushAsync();
-
+ var barInvoker = new BackgroundWorker();
+ barInvoker.DoWork += delegate
+ {
+ var discord = Client.CreatePCMStream(AudioApplication.Music);
+ output.CopyToAsync(discord);
+
+ discord.FlushAsync();
+ };
+
+ barInvoker.RunWorkerAsync();
}
[Command("join", RunMode = RunMode.Async)]
@@ -59,13 +66,14 @@
{
if (Client != null)
{
- await SoundEffects.Play(Sound.Nooo);
+ var wait = SoundEffects.Play(Sound.Nooo);
await Client.StopAsync();
Client = null;
+ wait.Wait();
}
}
- [Command("play")]
+ [Command("play", RunMode = RunMode.Async)]
public async Task PlayAudioAsync(string path)
{
if (Client == null)
diff --git a/DiscoBot/DSA.cs b/DiscoBot/DSA.cs
index d9cefb2..609fef7 100644
--- a/DiscoBot/DSA.cs
+++ b/DiscoBot/DSA.cs
@@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
+ using DiscoBot.Audio;
using DiscoBot.Auxiliary;
using DiscoBot.Characters;
@@ -13,6 +14,8 @@
{
public static ICommandContext GeneralContext { get; set; }
+ public static AudioService Service { get; set; }
+
public static Dictionary<string, string> Relation { get; set; } = new Dictionary<string, string>(); // dictionary to match the char
public static List<ICharacter> Chars { get; set; } = new List<ICharacter>(); // list of all characters
diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj
index 29f4208..899a485 100644
--- a/DiscoBot/DiscoBot.csproj
+++ b/DiscoBot/DiscoBot.csproj
@@ -140,6 +140,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Audio\AudioModule.cs" />
+ <Compile Include="Audio\AudioService.cs" />
<Compile Include="Auxiliary\Dice.cs" />
<Compile Include="Auxiliary\KampfTalent.cs" />
<Compile Include="Auxiliary\Soundeffects.cs" />
diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs
index 6bf870e..e3ea828 100644
--- a/DiscoBot/Program.cs
+++ b/DiscoBot/Program.cs
@@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace DiscoBot
{
+ using DiscoBot.Audio;
using DiscoBot.Commands;
public class Program
@@ -28,7 +29,7 @@ namespace DiscoBot
string token = Properties.Settings.Default.Token;
- this.services = new ServiceCollection()
+ this.services = new ServiceCollection().AddSingleton(new AudioService())
.BuildServiceProvider();
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;