This commit is contained in:
José Henrique Ivanchechen 2023-02-02 19:21:38 -03:00
parent 52c858cffb
commit 812fc0bf41
3 changed files with 115 additions and 24 deletions

View File

@ -82,8 +82,6 @@ jobs:
needs: build_arm64 needs: build_arm64
steps: steps:
- uses: actions/checkout@v2
- name: Recreate container - name: Recreate container
uses: appleboy/ssh-action@v0.1.7 uses: appleboy/ssh-action@v0.1.7
with: with:

View File

@ -37,7 +37,7 @@ namespace TextCommandFramework.Services
return; return;
var argPos = 0; var argPos = 0;
var prefix = "!"; 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(prefix, ref argPos)) return;

View File

@ -1,6 +1,7 @@
using Discord; using Discord;
using Discord.Audio; using Discord.Audio;
using Discord.Commands; using Discord.Commands;
using Discord.Rest;
using Discord.WebSocket; using Discord.WebSocket;
using System.Diagnostics; using System.Diagnostics;
using YoutubeExplode; using YoutubeExplode;
@ -10,19 +11,19 @@ namespace Kasbot.Services
{ {
public class PlayerService public class PlayerService
{ {
public Dictionary<ulong, Media> Clients { get; set; } public Dictionary<ulong, Connection> Clients { get; set; }
public PlayerService() public PlayerService()
{ {
Clients = new Dictionary<ulong, Media>(); Clients = new Dictionary<ulong, Connection>();
} }
private async Task<MemoryStream> DownloadAudioFromYoutube(string youtubeUrl) 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(youtubeUrl).FirstOrDefaultAsync(); var videoId = await youtube.Search.GetVideosAsync(media.Search).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);
@ -31,31 +32,99 @@ namespace Kasbot.Services
streamVideo.CopyTo(memoryStream); streamVideo.CopyTo(memoryStream);
memoryStream.Position = 0; memoryStream.Position = 0;
media.Name = videoId.Title;
media.Length = videoId.Duration.GetValueOrDefault();
return memoryStream; 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) 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() var media = new Media()
{ {
AudioClient = audioClient,
Message = Context.Message, Message = Context.Message,
Search = arguments,
Name = "" 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(() => Task stdin = new Task(() =>
{ {
using (var input = mp3Stream) 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 output = ffmpeg.StandardOutput.BaseStream)
using (var discord = audioClient.CreatePCMStream(AudioApplication.Music)) using (var discord = audioClient.CreatePCMStream(AudioApplication.Music))
{ {
output.CopyTo(discord); try
discord.Flush(); {
output.CopyTo(discord);
}
finally
{
discord.Flush();
output.Close();
}
} }
}); });
@ -74,7 +150,14 @@ namespace Kasbot.Services
Task.WaitAll(stdin, stdout); 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) private async Task AudioClient_ClientDisconnected(ulong arg)
@ -108,19 +191,29 @@ namespace Kasbot.Services
var media = Clients[guildId]; 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(); await media.AudioClient.StopAsync();
Clients.Remove(guildId); Clients.Remove(guildId);
} }
} }
public class Connection
{
public IAudioClient AudioClient { get; set; }
public Queue<Media> Queue { get; set; } = new Queue<Media>();
}
public class Media public class Media
{ {
public string Search { get; set; }
public string Name { get; set; } public string Name { get; set; }
public int Length { get; set; } public TimeSpan Length { get; set; }
public string FileName { get; set; }
public IAudioClient AudioClient { get; set; }
public SocketUserMessage Message { get; set; } public SocketUserMessage Message { get; set; }
public RestUserMessage PlayMessage { get; set; }
} }
} }