diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 894fc26..254990f 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -39,7 +39,7 @@ jobs: - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} - + build_arm64: name: Build and Push Docker Image (arm64) runs-on: ubuntu-latest @@ -75,7 +75,7 @@ jobs: - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} - + deploy: name: Update running container runs-on: ubuntu-latest @@ -95,4 +95,3 @@ jobs: docker-compose rm docker-compose pull docker-compose up -d - \ No newline at end of file diff --git a/Program.cs b/Program.cs index 43385c4..bf2abc0 100644 --- a/Program.cs +++ b/Program.cs @@ -11,6 +11,7 @@ namespace TextCommandFramework class Program { private static string TOKEN = Environment.GetEnvironmentVariable("TOKEN"); + private static int SHARDS = int.Parse(Environment.GetEnvironmentVariable("SHARDS")); static void Main(string[] args) { @@ -18,8 +19,16 @@ namespace TextCommandFramework { throw new Exception("Discord Bot Token was not found."); } + if (SHARDS == 0) + { + Console.WriteLine("Shards amount not found, defaulting to 1."); + SHARDS = 1; + } - new Program().MainAsync().GetAwaiter().GetResult(); + new Program() + .MainAsync() + .GetAwaiter() + .GetResult(); } public async Task MainAsync() @@ -84,7 +93,7 @@ namespace TextCommandFramework .AddSingleton(new DiscordSocketConfig { GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent, - TotalShards = 3 + TotalShards = SHARDS }) .AddSingleton() .AddSingleton() diff --git a/Services/Internal/AudioService.cs b/Services/Internal/AudioService.cs index d2f3b42..f0dd7a2 100644 --- a/Services/Internal/AudioService.cs +++ b/Services/Internal/AudioService.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using Discord.Audio; +using System.Diagnostics; namespace Kasbot.Services.Internal { @@ -6,7 +7,57 @@ namespace Kasbot.Services.Internal { public AudioService() { } - public Process CreateStream() + public void StartAudioTask(Stream inputStream, IAudioClient outputAudioClient, Action onStartAudio, Action onFinish) + { + var ffmpeg = CreateFFmpeg(); + + Task stdin = new Task(() => + { + using (var output = inputStream) + { + try + { + output.CopyTo(ffmpeg.StandardInput.BaseStream); + ffmpeg.StandardInput.Close(); + } + catch { } + finally + { + output.Flush(); + } + } + }); + + Task stdout = new Task(() => + { + using (var output = ffmpeg.StandardOutput.BaseStream) + using (var discord = outputAudioClient.CreatePCMStream(AudioApplication.Music)) + { + try + { + onStartAudio.Invoke(ffmpeg.StandardOutput.BaseStream); + output.CopyTo(discord); + } + catch { } + finally + { + discord.Flush(); + } + } + }); + + stdin.Start(); + stdout.Start(); + + stdin.ContinueWith(onFinish); + stdout.ContinueWith(onFinish); + + Task.WaitAll(stdin, stdout); + + ffmpeg.Close(); + } + + private Process CreateFFmpeg() { var process = Process.Start(new ProcessStartInfo { diff --git a/Services/Internal/YoutubeService.cs b/Services/Internal/YoutubeService.cs index c0eb3af..9c91b61 100644 --- a/Services/Internal/YoutubeService.cs +++ b/Services/Internal/YoutubeService.cs @@ -22,12 +22,14 @@ namespace Kasbot.Services.Internal var playlistInfo = await youtube.Playlists.GetAsync(search); await youtube.Playlists.GetVideosAsync(search).ForEachAsync(videoId => { - var media = new Media(); - - media.Name = videoId.Title; - media.Length = videoId.Duration ?? new TimeSpan(0); - media.VideoId = videoId.Id; - media.Message = message; + var media = new Media + { + Name = videoId.Title, + Length = videoId.Duration ?? new TimeSpan(0), + VideoId = videoId.Id, + Message = message, + Flags = new Flags() + }; collection.Medias.Add(media); }); diff --git a/Services/PlayerService.cs b/Services/PlayerService.cs index 0a57206..b8b6d6e 100644 --- a/Services/PlayerService.cs +++ b/Services/PlayerService.cs @@ -143,7 +143,6 @@ namespace Kasbot.Services } var audioClient = Clients[guildId].AudioClient; - var ffmpeg = AudioService.CreateStream(); if (!nextMedia.Flags.Silent) { @@ -156,62 +155,17 @@ namespace Kasbot.Services await nextMedia.QueueMessage.TryDeleteAsync(); } - Task stdin = new Task(() => - { - using (var input = mp3Stream) + AudioService.StartAudioTask(mp3Stream, audioClient, + (outAudioStream) => { - try - { - input.CopyTo(ffmpeg.StandardInput.BaseStream); - ffmpeg.StandardInput.Close(); - } - catch { } - finally - { - input.Flush(); - } - } - }); - - Task stdout = new Task(() => - { - using (var output = ffmpeg.StandardOutput.BaseStream) - using (var discord = audioClient.CreatePCMStream(AudioApplication.Music)) + Clients[guildId].CurrentAudioStream = outAudioStream; + }, async (ac) => { - try + if (ac.Exception != null) { - Clients[guildId].CurrentAudioStream = output; - output.CopyTo(discord); + await nextMedia.Channel.SendTemporaryMessageAsync("Error in stream: " + ac.Exception.ToString()); } - catch { } - finally - { - discord.Flush(); - } - } - }); - - stdin.Start(); - stdout.Start(); - - await stdin.ContinueWith(async ac => - { - if (ac.Exception != null) - { - await nextMedia.Channel.SendTemporaryMessageAsync("Error in input stream: " + ac.Exception.ToString()); - } - }); - await stdout.ContinueWith(async ac => - { - if (ac.Exception != null) - { - await nextMedia.Channel.SendTemporaryMessageAsync("Error while playing: " + ac.Exception.ToString()); - } - }); - - Task.WaitAll(stdin, stdout); - - ffmpeg.Close(); + }); await nextMedia.PlayMessage.TryDeleteAsync(); diff --git a/docker-compose.yml b/docker-compose.yml index fb13786..2e35b49 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,4 +6,5 @@ services: environment: - TOKEN= - COMMAND_PREFIX=! + - SHARDS=3 restart: unless-stopped \ No newline at end of file