add couple of stuff
This commit is contained in:
parent
ae9c3cfa35
commit
5146f47c30
21
.github/workflows/master.yml
vendored
21
.github/workflows/master.yml
vendored
@ -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
|
||||||
|
|
@ -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")]
|
||||||
|
30
Program.cs
30
Program.cs
@ -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());
|
||||||
|
@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user