add couple of stuff

This commit is contained in:
José Henrique Ivanchechen 2023-02-02 12:50:33 -03:00
parent ae9c3cfa35
commit 5146f47c30
4 changed files with 115 additions and 52 deletions

View File

@ -75,3 +75,24 @@ jobs:
- name: Image digest - name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }} run: echo ${{ steps.docker_build.outputs.digest }}
deploy:
name: Update running container
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Recreate container
uses: appleboy/ssh-action@v0.1.7
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
port: ${{ secrets.DEPLOY_PORT }}
script: |
cd docker/kasbot
docker-compose rm
docker-compose pull
docker-compose up -d

View File

@ -50,7 +50,16 @@ namespace TextCommandFramework.Modules
var user = Context.User; var user = Context.User;
if (user.IsBot) return; if (user.IsBot) return;
await PlayerService.Stop(Context); await PlayerService.Stop(Context.Guild.Id);
}
[Command("leave", RunMode = RunMode.Async)]
public async Task LeaveAsync()
{
var user = Context.User;
if (user.IsBot) return;
await PlayerService.Stop(Context.Guild.Id);
} }
[Command("guild_only")] [Command("guild_only")]

View File

@ -28,6 +28,8 @@ namespace TextCommandFramework
var client = services.GetRequiredService<DiscordSocketClient>(); var client = services.GetRequiredService<DiscordSocketClient>();
client.Log += LogAsync; client.Log += LogAsync;
client.LoggedIn += () => Client_LoggedIn(client);
client.Ready += () => Client_Ready(client);
services.GetRequiredService<CommandService>().Log += LogAsync; services.GetRequiredService<CommandService>().Log += LogAsync;
await client.LoginAsync(TokenType.Bot, token); await client.LoginAsync(TokenType.Bot, token);
@ -39,6 +41,34 @@ namespace TextCommandFramework
} }
} }
private async Task Client_Ready(DiscordSocketClient client)
{
var announceLoginGuild = ulong.Parse(Environment.GetEnvironmentVariable("ANNOUNCE_LOGIN_GUILD") ?? "0");
var announceLoginChannel = ulong.Parse(Environment.GetEnvironmentVariable("ANNOUNCE_LOGIN_CHANNEL") ?? "0");
if (announceLoginGuild == 0 || announceLoginChannel == 0)
{
return;
}
var channel = client.GetGuild(announceLoginGuild).GetTextChannel(announceLoginChannel);
if (channel == null)
{
Console.WriteLine("Announce channel not found.");
return;
}
await channel.SendMessageAsync("@everyone LIVE!");
}
private Task Client_LoggedIn(DiscordSocketClient client)
{
Console.WriteLine("Successfully logged in!");
return Task.CompletedTask;
}
private Task LogAsync(LogMessage log) private Task LogAsync(LogMessage log)
{ {
Console.WriteLine(log.ToString()); Console.WriteLine(log.ToString());

View File

@ -10,77 +10,84 @@ namespace Kasbot.Services
{ {
public class PlayerService public class PlayerService
{ {
public Dictionary<SocketGuild, Media> Clients { get; set; } public Dictionary<ulong, Media> Clients { get; set; }
public PlayerService() public PlayerService()
{ {
Clients = new Dictionary<SocketGuild, Media>(); Clients = new Dictionary<ulong, Media>();
} }
private async Task<string> DownloadAudioFromYoutube(string youtubeUrl) private async Task<MemoryStream> DownloadAudioFromYoutube(string youtubeUrl)
{ {
var memoryStream = new MemoryStream();
var youtube = new YoutubeClient(); var youtube = new YoutubeClient();
var videoId = await youtube.Search.GetVideosAsync(youtubeUrl).FirstOrDefaultAsync(); var videoId = await youtube.Search.GetVideosAsync(youtubeUrl).FirstOrDefaultAsync();
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);
var fileName = $"{videoId.Id}.mp3"; streamVideo.Position = 0;
streamVideo.CopyTo(memoryStream);
memoryStream.Position = 0;
using (var fileStream = new FileStream(fileName, FileMode.Create)) return memoryStream;
{
await streamVideo.CopyToAsync(fileStream);
}
return fileName;
} }
public async Task Play(SocketCommandContext Context, string arguments) public async Task Play(SocketCommandContext Context, string arguments)
{ {
IVoiceChannel channel = (Context.User as IVoiceState).VoiceChannel; IVoiceChannel channel = (Context.User as IVoiceState).VoiceChannel;
string filename; var mp3Stream = await DownloadAudioFromYoutube(arguments);
var ffmpeg = CreateStream();
try
{
filename = await DownloadAudioFromYoutube(arguments);
}
catch (Exception ex)
{
throw new Exception("Error while downloading video from YouTube!");
}
var audioClient = await channel.ConnectAsync(); var audioClient = await channel.ConnectAsync();
audioClient.ClientDisconnected += AudioClient_ClientDisconnected;
using (var ffmpeg = CreateStream(filename)) var media = new Media()
using (var output = ffmpeg.StandardOutput.BaseStream)
using (var discord = audioClient.CreatePCMStream(AudioApplication.Mixed))
{ {
try AudioClient = audioClient,
Message = Context.Message,
Name = ""
};
Clients.Add(Context.Guild.Id, media);
Task stdin = new Task(() =>
{
using (var input = mp3Stream)
{ {
var media = new Media() input.CopyTo(ffmpeg.StandardInput.BaseStream);
{
AudioClient = audioClient,
AudioOutStream = discord,
FileName = filename,
Message = Context.Message,
Name = ""
};
Clients.Add(Context.Guild, media);
await output.CopyToAsync(discord);
} }
finally });
Task stdout = new Task(() =>
{
using (var output = ffmpeg.StandardOutput.BaseStream)
using (var discord = audioClient.CreatePCMStream(AudioApplication.Music))
{ {
await discord.FlushAsync(); output.CopyTo(discord);
File.Delete(filename); discord.Flush();
} }
} });
stdin.Start();
stdout.Start();
Task.WaitAll(stdin, stdout);
ffmpeg.WaitForExit();
} }
private Process CreateStream(string filename) private async Task AudioClient_ClientDisconnected(ulong arg)
{
await Stop(arg);
}
private Process CreateStream()
{ {
var process = Process.Start(new ProcessStartInfo var process = Process.Start(new ProcessStartInfo
{ {
FileName = "ffmpeg", FileName = "ffmpeg",
Arguments = $"-hide_banner -loglevel panic -i {filename} -ac 2 -f s16le -ar 48000 pipe:1", Arguments = $"-hide_banner -loglevel panic -i pipe:0 -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false, UseShellExecute = false,
RedirectStandardInput = true, RedirectStandardInput = true,
RedirectStandardOutput = true RedirectStandardOutput = true
@ -88,36 +95,32 @@ namespace Kasbot.Services
if (process == null || process.HasExited) if (process == null || process.HasExited)
{ {
throw new Exception("Sorry, ffmpeg killed himself! Bah."); throw new Exception("Sorry, ffmpeg killed himself in a tragic accident!");
} }
return process; return process;
} }
public async Task Stop(SocketCommandContext Context) public async Task Stop(ulong guildId)
{ {
if (!Clients.ContainsKey(Context.Guild)) if (!Clients.ContainsKey(guildId))
return; return;
var media = Clients[Context.Guild]; var media = Clients[guildId];
Clients.Remove(Context.Guild);
File.Delete(media.FileName);
await Context.Message.DeleteAsync();
await media.Message.DeleteAsync(); await media.Message.DeleteAsync();
await media.AudioOutStream.DisposeAsync();
await media.AudioOutStream.ClearAsync(new CancellationToken());
await media.AudioClient.StopAsync(); await media.AudioClient.StopAsync();
}
Clients.Remove(guildId);
}
} }
public class Media public class Media
{ {
public string Name { get; set; } public string Name { get; set; }
public int Length { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public IAudioClient AudioClient { get; set; } public IAudioClient AudioClient { get; set; }
public AudioOutStream AudioOutStream { get; set; }
public SocketUserMessage Message { get; set; } public SocketUserMessage Message { get; set; }
} }
} }