From 812fc0bf41fb10e656f18393b9108ccfa37c40e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Henrique=20Ivanchechen?= Date: Thu, 2 Feb 2023 19:21:38 -0300 Subject: [PATCH] things --- .github/workflows/master.yml | 2 - Services/CommandHandlingService.cs | 2 +- Services/PlayerService.cs | 135 ++++++++++++++++++++++++----- 3 files changed, 115 insertions(+), 24 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index cdc8b9c..9db4aeb 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -82,8 +82,6 @@ jobs: needs: build_arm64 steps: - - uses: actions/checkout@v2 - - name: Recreate container uses: appleboy/ssh-action@v0.1.7 with: diff --git a/Services/CommandHandlingService.cs b/Services/CommandHandlingService.cs index 5709c27..65fe94c 100644 --- a/Services/CommandHandlingService.cs +++ b/Services/CommandHandlingService.cs @@ -37,7 +37,7 @@ namespace TextCommandFramework.Services return; var argPos = 0; - var prefix = "!"; + var prefix = "-"; //Check if the message sent has the specified prefix if (!message.HasStringPrefix(prefix, ref argPos)) return; diff --git a/Services/PlayerService.cs b/Services/PlayerService.cs index a5ba045..43e1b75 100644 --- a/Services/PlayerService.cs +++ b/Services/PlayerService.cs @@ -1,6 +1,7 @@ using Discord; using Discord.Audio; using Discord.Commands; +using Discord.Rest; using Discord.WebSocket; using System.Diagnostics; using YoutubeExplode; @@ -10,19 +11,19 @@ namespace Kasbot.Services { public class PlayerService { - public Dictionary Clients { get; set; } + public Dictionary Clients { get; set; } public PlayerService() { - Clients = new Dictionary(); + Clients = new Dictionary(); } - private async Task DownloadAudioFromYoutube(string youtubeUrl) + private async Task DownloadAudioFromYoutube(Media media) { var memoryStream = new MemoryStream(); var youtube = new YoutubeClient(); - var videoId = await youtube.Search.GetVideosAsync(youtubeUrl).FirstOrDefaultAsync(); + var videoId = await youtube.Search.GetVideosAsync(media.Search).FirstOrDefaultAsync(); var streamInfoSet = await youtube.Videos.Streams.GetManifestAsync(videoId.Id); var streamInfo = streamInfoSet.GetAudioOnlyStreams().GetWithHighestBitrate(); var streamVideo = await youtube.Videos.Streams.GetAsync(streamInfo); @@ -31,31 +32,99 @@ namespace Kasbot.Services streamVideo.CopyTo(memoryStream); memoryStream.Position = 0; + media.Name = videoId.Title; + media.Length = videoId.Duration.GetValueOrDefault(); + return memoryStream; } + private Connection CreateConnection(IAudioClient audioClient, ulong guildId) + { + var conn = new Connection() + { + AudioClient = audioClient, + }; + + if (Clients.ContainsKey(guildId)) + Clients.Remove(guildId); + + Clients.Add(guildId, conn); + + return conn; + } + public async Task Play(SocketCommandContext Context, string arguments) { - IVoiceChannel channel = (Context.User as IVoiceState).VoiceChannel; - - var mp3Stream = await DownloadAudioFromYoutube(arguments); - var ffmpeg = CreateStream(); - - var audioClient = await channel.ConnectAsync(); - audioClient.ClientDisconnected += AudioClient_ClientDisconnected; var media = new Media() { - AudioClient = audioClient, Message = Context.Message, + Search = arguments, Name = "" }; - Clients.Add(Context.Guild.Id, media); + + if (Clients.TryGetValue(Context.Guild.Id, out var conn)) + { + conn.Queue.Enqueue(media); + Console.WriteLine("conn.Queue.Count " + conn.Queue.Count); + if (conn.Queue.Count == 1) + { + await PlayNext(Context.Guild.Id); + } + + return; + } + + IVoiceChannel channel = (Context.User as IVoiceState).VoiceChannel; + + var audioClient = await channel.ConnectAsync(); + audioClient.ClientDisconnected += (id) => AudioClient_ClientDisconnected(Context.Guild.Id); + audioClient.Disconnected += (ex) => AudioClient_ClientDisconnected(Context.Guild.Id); + + conn = CreateConnection(audioClient, Context.Guild.Id); + + conn.Queue.Enqueue(media); + Console.WriteLine("conn.Queue.Count " + conn.Queue.Count); + if (conn.Queue.Count == 1) + { + await PlayNext(Context.Guild.Id); + } + } + + private async Task PlayNext(ulong guildId) + { + if (!Clients.ContainsKey(guildId) || Clients[guildId].Queue.Count == 0) + { + return; + } + + var nextMedia = Clients[guildId].Queue.FirstOrDefault(); + + if (nextMedia == null) + { + await Stop(guildId); + return; + } + + var mp3Stream = await DownloadAudioFromYoutube(nextMedia); + var audioClient = Clients[guildId].AudioClient; + var ffmpeg = CreateStream(); + + nextMedia.PlayMessage = await nextMedia.Message.Channel.SendMessageAsync($"⏯ Playing: {nextMedia.Name} **({nextMedia.Length.Minutes.ToString("00")}:{nextMedia.Length.Seconds:00})**"); Task stdin = new Task(() => { using (var input = mp3Stream) { - input.CopyTo(ffmpeg.StandardInput.BaseStream); + try + { + input.CopyTo(ffmpeg.StandardInput.BaseStream); + ffmpeg.StandardInput.Close(); + } + finally + { + input.Flush(); + input.Dispose(); + } } }); @@ -64,8 +133,15 @@ namespace Kasbot.Services using (var output = ffmpeg.StandardOutput.BaseStream) using (var discord = audioClient.CreatePCMStream(AudioApplication.Music)) { - output.CopyTo(discord); - discord.Flush(); + try + { + output.CopyTo(discord); + } + finally + { + discord.Flush(); + output.Close(); + } } }); @@ -74,7 +150,14 @@ namespace Kasbot.Services Task.WaitAll(stdin, stdout); - ffmpeg.WaitForExit(); + ffmpeg.Close(); + + await nextMedia.Message.DeleteAsync(); + await nextMedia.PlayMessage.DeleteAsync(); + + Clients[guildId].Queue.Dequeue(); + + await PlayNext(guildId); } private async Task AudioClient_ClientDisconnected(ulong arg) @@ -108,19 +191,29 @@ namespace Kasbot.Services var media = Clients[guildId]; - await media.Message.DeleteAsync(); + foreach (var v in media.Queue) + { + await v.Message.DeleteAsync(); + await v.PlayMessage.DeleteAsync(); + } await media.AudioClient.StopAsync(); Clients.Remove(guildId); } } + public class Connection + { + public IAudioClient AudioClient { get; set; } + public Queue Queue { get; set; } = new Queue(); + } + public class Media { + public string Search { get; set; } public string Name { get; set; } - public int Length { get; set; } - public string FileName { get; set; } - public IAudioClient AudioClient { get; set; } + public TimeSpan Length { get; set; } public SocketUserMessage Message { get; set; } + public RestUserMessage PlayMessage { get; set; } } }