add couple of stuff
This commit is contained in:
@@ -10,77 +10,84 @@ namespace Kasbot.Services
|
||||
{
|
||||
public class PlayerService
|
||||
{
|
||||
public Dictionary<SocketGuild, Media> Clients { get; set; }
|
||||
public Dictionary<ulong, Media> Clients { get; set; }
|
||||
|
||||
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 videoId = await youtube.Search.GetVideosAsync(youtubeUrl).FirstOrDefaultAsync();
|
||||
var streamInfoSet = await youtube.Videos.Streams.GetManifestAsync(videoId.Id);
|
||||
var streamInfo = streamInfoSet.GetAudioOnlyStreams().GetWithHighestBitrate();
|
||||
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))
|
||||
{
|
||||
await streamVideo.CopyToAsync(fileStream);
|
||||
}
|
||||
return fileName;
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
public async Task Play(SocketCommandContext Context, string arguments)
|
||||
{
|
||||
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();
|
||||
|
||||
using (var ffmpeg = CreateStream(filename))
|
||||
using (var output = ffmpeg.StandardOutput.BaseStream)
|
||||
using (var discord = audioClient.CreatePCMStream(AudioApplication.Mixed))
|
||||
audioClient.ClientDisconnected += AudioClient_ClientDisconnected;
|
||||
var media = new Media()
|
||||
{
|
||||
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()
|
||||
{
|
||||
AudioClient = audioClient,
|
||||
AudioOutStream = discord,
|
||||
FileName = filename,
|
||||
Message = Context.Message,
|
||||
Name = ""
|
||||
};
|
||||
Clients.Add(Context.Guild, media);
|
||||
await output.CopyToAsync(discord);
|
||||
input.CopyTo(ffmpeg.StandardInput.BaseStream);
|
||||
}
|
||||
finally
|
||||
});
|
||||
|
||||
Task stdout = new Task(() =>
|
||||
{
|
||||
using (var output = ffmpeg.StandardOutput.BaseStream)
|
||||
using (var discord = audioClient.CreatePCMStream(AudioApplication.Music))
|
||||
{
|
||||
await discord.FlushAsync();
|
||||
File.Delete(filename);
|
||||
output.CopyTo(discord);
|
||||
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
|
||||
{
|
||||
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,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true
|
||||
@@ -88,36 +95,32 @@ namespace Kasbot.Services
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public async Task Stop(SocketCommandContext Context)
|
||||
public async Task Stop(ulong guildId)
|
||||
{
|
||||
if (!Clients.ContainsKey(Context.Guild))
|
||||
if (!Clients.ContainsKey(guildId))
|
||||
return;
|
||||
|
||||
var media = Clients[Context.Guild];
|
||||
Clients.Remove(Context.Guild);
|
||||
var media = Clients[guildId];
|
||||
|
||||
File.Delete(media.FileName);
|
||||
await Context.Message.DeleteAsync();
|
||||
await media.Message.DeleteAsync();
|
||||
await media.AudioOutStream.DisposeAsync();
|
||||
await media.AudioOutStream.ClearAsync(new CancellationToken());
|
||||
await media.AudioClient.StopAsync();
|
||||
}
|
||||
|
||||
Clients.Remove(guildId);
|
||||
}
|
||||
}
|
||||
|
||||
public class Media
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Length { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public IAudioClient AudioClient { get; set; }
|
||||
public AudioOutStream AudioOutStream { get; set; }
|
||||
public SocketUserMessage Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user