diff options
author | TrueDoctor <d-kobert@web.de> | 2018-04-11 14:19:57 +0200 |
---|---|---|
committer | TrueDoctor <d-kobert@web.de> | 2018-04-11 14:19:57 +0200 |
commit | 351067a5203307fc0c1a14ae2be84eae71246af9 (patch) | |
tree | a17b63d94b41c87215a03fd2a19edab9f4d53c30 /DiscoBot | |
parent | aa236f67bf1829e2a7c6e9a5f82d109b39147b11 (diff) |
Added possibillity for service based soundplaying
Diffstat (limited to 'DiscoBot')
-rw-r--r-- | DiscoBot/Audio/AudioModule.cs | 72 | ||||
-rw-r--r-- | DiscoBot/Audio/AudioService.cs | 101 | ||||
-rw-r--r-- | DiscoBot/Auxiliary/Soundeffects.cs | 9 | ||||
-rw-r--r-- | DiscoBot/Characters/Character.cs | 10 | ||||
-rw-r--r-- | DiscoBot/Commands/Voice.cs | 24 | ||||
-rw-r--r-- | DiscoBot/DSA.cs | 3 | ||||
-rw-r--r-- | DiscoBot/DiscoBot.csproj | 2 | ||||
-rw-r--r-- | DiscoBot/Program.cs | 3 |
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; |