a couple of stuff + skip

This commit is contained in:
José Henrique Ivanchechen 2023-02-02 22:14:17 -03:00
parent 812fc0bf41
commit 5d910a62a1
4 changed files with 86 additions and 15 deletions

View File

@ -85,10 +85,10 @@ jobs:
- name: Recreate container - name: Recreate container
uses: appleboy/ssh-action@v0.1.7 uses: appleboy/ssh-action@v0.1.7
with: with:
host: ${{ secrets.DEPLOY_HOST }} host: ${{ secrets.HOST }}
username: ${{ secrets.DEPLOY_USER }} username: ${{ secrets.USERNAME }}
key: ${{ secrets.DEPLOY_KEY }} key: ${{ secrets.KEY }}
port: ${{ secrets.DEPLOY_PORT }} port: ${{ secrets.PORT }}
script: | script: |
cd docker/kasbot cd docker/kasbot
docker-compose down docker-compose down

View File

@ -53,6 +53,15 @@ namespace TextCommandFramework.Modules
await PlayerService.Stop(Context.Guild.Id); await PlayerService.Stop(Context.Guild.Id);
} }
[Command("skip", RunMode = RunMode.Async)]
public async Task SkipAsync()
{
var user = Context.User;
if (user.IsBot) return;
await PlayerService.Skip(Context.Guild.Id);
}
[Command("leave", RunMode = RunMode.Async)] [Command("leave", RunMode = RunMode.Async)]
public async Task LeaveAsync() public async Task LeaveAsync()
{ {

View File

@ -14,6 +14,8 @@ namespace TextCommandFramework.Services
private readonly DiscordSocketClient _discord; private readonly DiscordSocketClient _discord;
private readonly IServiceProvider _services; private readonly IServiceProvider _services;
private readonly string CommandPrefix = "!";
public CommandHandlingService(IServiceProvider services) public CommandHandlingService(IServiceProvider services)
{ {
_commands = services.GetRequiredService<CommandService>(); _commands = services.GetRequiredService<CommandService>();
@ -22,6 +24,8 @@ namespace TextCommandFramework.Services
_commands.CommandExecuted += CommandExecutedAsync; _commands.CommandExecuted += CommandExecutedAsync;
_discord.MessageReceived += MessageReceivedAsync; _discord.MessageReceived += MessageReceivedAsync;
CommandPrefix = Environment.GetEnvironmentVariable("COMMAND_PREFIX") ?? "!";
} }
public async Task InitializeAsync() public async Task InitializeAsync()
@ -37,10 +41,9 @@ namespace TextCommandFramework.Services
return; return;
var argPos = 0; var argPos = 0;
var prefix = "-";
//Check if the message sent has the specified prefix //Check if the message sent has the specified prefix
if (!message.HasStringPrefix(prefix, ref argPos)) return; if (!message.HasStringPrefix(CommandPrefix, ref argPos)) return;
var context = new SocketCommandContext(_discord, message); var context = new SocketCommandContext(_discord, message);
await _commands.ExecuteAsync(context, argPos, _services); await _commands.ExecuteAsync(context, argPos, _services);
@ -54,7 +57,11 @@ namespace TextCommandFramework.Services
if (result.IsSuccess) if (result.IsSuccess)
return; return;
await context.Channel.SendMessageAsync($"error: {result}"); var message = await context.Channel.SendMessageAsync($"error: {result}");
await Task.Delay(5_000);
await message.DeleteAsync();
} }
} }
} }

View File

@ -5,6 +5,8 @@ using Discord.Rest;
using Discord.WebSocket; using Discord.WebSocket;
using System.Diagnostics; using System.Diagnostics;
using YoutubeExplode; using YoutubeExplode;
using YoutubeExplode.Search;
using YoutubeExplode.Videos;
using YoutubeExplode.Videos.Streams; using YoutubeExplode.Videos.Streams;
namespace Kasbot.Services namespace Kasbot.Services
@ -18,12 +20,23 @@ namespace Kasbot.Services
Clients = new Dictionary<ulong, Connection>(); Clients = new Dictionary<ulong, Connection>();
} }
private async Task<MemoryStream> DownloadAudioFromYoutube(Media media) private async Task<MemoryStream?> DownloadAudioFromYoutube(Media media)
{ {
var memoryStream = new MemoryStream(); var memoryStream = new MemoryStream();
var youtube = new YoutubeClient(); var youtube = new YoutubeClient();
var videoId = await youtube.Search.GetVideosAsync(media.Search).FirstOrDefaultAsync(); IVideo? videoId = null;
if (media.Search.StartsWith("http://") || media.Search.StartsWith("https://"))
videoId = await youtube.Videos.GetAsync(media.Search);
else
videoId = await youtube.Search.GetVideosAsync(media.Search).FirstOrDefaultAsync();
if (videoId == null)
{
return null;
}
var streamInfoSet = await youtube.Videos.Streams.GetManifestAsync(videoId.Id); var streamInfoSet = await youtube.Videos.Streams.GetManifestAsync(videoId.Id);
var streamInfo = streamInfoSet.GetAudioOnlyStreams().GetWithHighestBitrate(); var streamInfo = streamInfoSet.GetAudioOnlyStreams().GetWithHighestBitrate();
var streamVideo = await youtube.Videos.Streams.GetAsync(streamInfo); var streamVideo = await youtube.Videos.Streams.GetAsync(streamInfo);
@ -65,7 +78,6 @@ namespace Kasbot.Services
if (Clients.TryGetValue(Context.Guild.Id, out var conn)) if (Clients.TryGetValue(Context.Guild.Id, out var conn))
{ {
conn.Queue.Enqueue(media); conn.Queue.Enqueue(media);
Console.WriteLine("conn.Queue.Count " + conn.Queue.Count);
if (conn.Queue.Count == 1) if (conn.Queue.Count == 1)
{ {
await PlayNext(Context.Guild.Id); await PlayNext(Context.Guild.Id);
@ -83,7 +95,6 @@ namespace Kasbot.Services
conn = CreateConnection(audioClient, Context.Guild.Id); conn = CreateConnection(audioClient, Context.Guild.Id);
conn.Queue.Enqueue(media); conn.Queue.Enqueue(media);
Console.WriteLine("conn.Queue.Count " + conn.Queue.Count);
if (conn.Queue.Count == 1) if (conn.Queue.Count == 1)
{ {
await PlayNext(Context.Guild.Id); await PlayNext(Context.Guild.Id);
@ -101,15 +112,24 @@ namespace Kasbot.Services
if (nextMedia == null) if (nextMedia == null)
{ {
Clients[guildId].Queue.Dequeue();
await Stop(guildId); await Stop(guildId);
return; return;
} }
var mp3Stream = await DownloadAudioFromYoutube(nextMedia); var mp3Stream = await DownloadAudioFromYoutube(nextMedia);
if (mp3Stream == null)
{
await Stop(guildId);
return;
}
var audioClient = Clients[guildId].AudioClient; var audioClient = Clients[guildId].AudioClient;
var ffmpeg = CreateStream(); var ffmpeg = CreateStream();
nextMedia.PlayMessage = await nextMedia.Message.Channel.SendMessageAsync($"⏯ Playing: {nextMedia.Name} **({nextMedia.Length.Minutes.ToString("00")}:{nextMedia.Length.Seconds:00})**"); var message = $"⏯ Playing: {nextMedia.Name} **({nextMedia.Length.TotalMinutes:00}:{nextMedia.Length.Seconds:00})**";
nextMedia.PlayMessage = await nextMedia.Message.Channel.SendMessageAsync(message);
Task stdin = new Task(() => Task stdin = new Task(() =>
{ {
@ -120,6 +140,7 @@ namespace Kasbot.Services
input.CopyTo(ffmpeg.StandardInput.BaseStream); input.CopyTo(ffmpeg.StandardInput.BaseStream);
ffmpeg.StandardInput.Close(); ffmpeg.StandardInput.Close();
} }
catch { }
finally finally
{ {
input.Flush(); input.Flush();
@ -135,8 +156,10 @@ namespace Kasbot.Services
{ {
try try
{ {
Clients[guildId].CurrentAudioStream = output;
output.CopyTo(discord); output.CopyTo(discord);
} }
catch { }
finally finally
{ {
discord.Flush(); discord.Flush();
@ -184,6 +207,21 @@ namespace Kasbot.Services
return process; return process;
} }
public Task Skip(ulong guildId)
{
if (!Clients.ContainsKey(guildId))
return Task.CompletedTask;
var media = Clients[guildId];
if (media.CurrentAudioStream == null)
return Task.CompletedTask;
media.CurrentAudioStream.Close();
return Task.CompletedTask;
}
public async Task Stop(ulong guildId) public async Task Stop(ulong guildId)
{ {
if (!Clients.ContainsKey(guildId)) if (!Clients.ContainsKey(guildId))
@ -193,18 +231,35 @@ namespace Kasbot.Services
foreach (var v in media.Queue) foreach (var v in media.Queue)
{ {
await v.Message.DeleteAsync(); await RemoveMediaMessages(v);
await v.PlayMessage.DeleteAsync();
} }
await media.AudioClient.StopAsync();
if (media.AudioClient != null)
await media.AudioClient.StopAsync();
Clients.Remove(guildId); Clients.Remove(guildId);
} }
private async Task RemoveMediaMessages(Media media)
{
try
{
if (media.Message != null)
await media.Message.DeleteAsync();
}
catch { }
try
{
if (media.PlayMessage != null)
await media.PlayMessage.DeleteAsync();
} catch { }
}
} }
public class Connection public class Connection
{ {
public IAudioClient AudioClient { get; set; } public IAudioClient AudioClient { get; set; }
public Stream? CurrentAudioStream { get; set; }
public Queue<Media> Queue { get; set; } = new Queue<Media>(); public Queue<Media> Queue { get; set; } = new Queue<Media>();
} }