Add audio stuff back

This commit is contained in:
runebaas 2018-05-04 00:54:01 +02:00
parent 0828130ae8
commit 8599c815d7
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
4 changed files with 217 additions and 0 deletions

View file

@ -0,0 +1,103 @@
using System;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Geekbot.net.Lib.Audio;
using Geekbot.net.Lib.ErrorHandling;
namespace Geekbot.net.Commands.Audio
{
public class Voice : ModuleBase
{
private readonly IAudioUtils _audioUtils;
private readonly IErrorHandler _errorHandler;
public Voice(IErrorHandler errorHandler, IAudioUtils audioUtils)
{
_errorHandler = errorHandler;
_audioUtils = audioUtils;
}
[Command("join")]
public async Task JoinChannel()
{
try
{
// Get the audio channel
var channel = (Context.User as IGuildUser)?.VoiceChannel;
if (channel == null)
{
await Context.Channel.SendMessageAsync(
"User must be in a voice channel, or a voice channel must be passed as an argument.");
return;
}
// For the next step with transmitting audio, you would want to pass this Audio Client in to a service.
var audioClient = await channel.ConnectAsync();
_audioUtils.StoreAudioClient(Context.Guild.Id, audioClient);
await ReplyAsync($"Connected to {channel.Name}");
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
}
}
[Command("disconnect")]
public async Task DisconnectChannel()
{
try
{
var audioClient = _audioUtils.GetAudioClient(Context.Guild.Id);
if (audioClient == null)
{
await Context.Channel.SendMessageAsync("I'm not in a voice channel at the moment");
return;
}
await audioClient.StopAsync();
await ReplyAsync("Disconnected from channel!");
_audioUtils.Cleanup(Context.Guild.Id);
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
_audioUtils.Cleanup(Context.Guild.Id);
}
}
[Command("ytplay")]
public async Task ytplay(string url)
{
try
{
if (!url.Contains("youtube"))
{
await ReplyAsync("I can only play youtube videos");
return;
}
var audioClient = _audioUtils.GetAudioClient(Context.Guild.Id);
if (audioClient == null)
{
await ReplyAsync("I'm not in a voice channel at the moment");
return;
}
var message = await Context.Channel.SendMessageAsync("Just a second, i'm still a bit slow at this");
var ffmpeg = _audioUtils.CreateStreamFromYoutube(url, Context.Guild.Id);
var output = ffmpeg.StandardOutput.BaseStream;
await message.ModifyAsync(msg => msg.Content = "**Playing!** Please note that this feature is experimental");
var discord = audioClient.CreatePCMStream(Discord.Audio.AudioApplication.Mixed);
await output.CopyToAsync(discord);
await discord.FlushAsync();
_audioUtils.Cleanup(Context.Guild.Id);
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
_audioUtils.Cleanup(Context.Guild.Id);
}
}
}
}

View file

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using Discord.Audio;
namespace Geekbot.net.Lib.Audio
{
public class AudioUtils : IAudioUtils
{
private string _tempFolderPath;
private Dictionary<ulong, IAudioClient> _audioClients;
public AudioUtils()
{
_audioClients = new Dictionary<ulong, IAudioClient>();
_tempFolderPath = Path.GetFullPath("./tmp/");
if (Directory.Exists(_tempFolderPath))
{
Directory.Delete(_tempFolderPath, true);
}
Directory.CreateDirectory(_tempFolderPath);
}
public IAudioClient GetAudioClient(ulong guildId)
{
return _audioClients[guildId];
}
public void StoreAudioClient(ulong guildId, IAudioClient client)
{
_audioClients[guildId] = client;
}
public Process CreateStreamFromFile(string path)
{
var ffmpeg = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false,
RedirectStandardOutput = true,
};
return Process.Start(ffmpeg);
}
public Process CreateStreamFromYoutube(string url, ulong guildId)
{
var ytdlMediaUrl = GetYoutubeMediaUrl(url);
DownloadMediaUrl(ytdlMediaUrl, guildId);
return CreateStreamFromFile($"{_tempFolderPath}{guildId}");
}
public void Cleanup(ulong guildId)
{
File.Delete($"{_tempFolderPath}{guildId}");
}
private string GetYoutubeMediaUrl(string url)
{
var ytdl = new ProcessStartInfo()
{
FileName = "youtube-dl",
Arguments = $"-f bestaudio -g {url}",
UseShellExecute = false,
RedirectStandardOutput = true
};
var output = Process.Start(ytdl).StandardOutput.ReadToEnd();
if (string.IsNullOrWhiteSpace(output))
{
throw new Exception("Could not get Youtube Media URL");
}
return output;
}
private void DownloadMediaUrl(string url, ulong guildId)
{
using (var web = new WebClient())
{
web.DownloadFile(url, $"{_tempFolderPath}{guildId}");
}
// var ffmpeg = new ProcessStartInfo
// {
// FileName = "ffmpeg",
// Arguments = $"-i \"{_tempFolderPath}{guildId}\" -c:a mp3 -b:a 256k {_tempFolderPath}{guildId}.mp3",
// UseShellExecute = false,
// RedirectStandardOutput = true,
// };
// Process.Start(ffmpeg).WaitForExit();
// File.Delete($"{_tempFolderPath}{guildId}");
return;
}
}
}

View file

@ -0,0 +1,15 @@
using System.Diagnostics;
using Discord.Audio;
namespace Geekbot.net.Lib.Audio
{
public interface IAudioUtils
{
IAudioClient GetAudioClient(ulong guildId);
void StoreAudioClient(ulong guildId, IAudioClient client);
Process CreateStreamFromFile(string path);
Process CreateStreamFromYoutube(string url, ulong guildId);
void Cleanup(ulong guildId);
}
}

View file

@ -8,6 +8,7 @@ using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using Geekbot.net.Lib; using Geekbot.net.Lib;
using Geekbot.net.Lib.Audio;
using Geekbot.net.Lib.Clients; using Geekbot.net.Lib.Clients;
using Geekbot.net.Lib.Converters; using Geekbot.net.Lib.Converters;
using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.ErrorHandling;
@ -113,6 +114,7 @@ namespace Geekbot.net
var emojiConverter = new EmojiConverter(); var emojiConverter = new EmojiConverter();
var mtgManaConverter = new MtgManaConverter(); var mtgManaConverter = new MtgManaConverter();
var wikipediaClient = new WikipediaClient(); var wikipediaClient = new WikipediaClient();
var audioUtils = new AudioUtils();
_services.AddSingleton(_redis); _services.AddSingleton(_redis);
_services.AddSingleton(logger); _services.AddSingleton(logger);
@ -124,6 +126,7 @@ namespace Geekbot.net
_services.AddSingleton<IMalClient>(malClient); _services.AddSingleton<IMalClient>(malClient);
_services.AddSingleton<IMtgManaConverter>(mtgManaConverter); _services.AddSingleton<IMtgManaConverter>(mtgManaConverter);
_services.AddSingleton<IWikipediaClient>(wikipediaClient); _services.AddSingleton<IWikipediaClient>(wikipediaClient);
_services.AddSingleton<IAudioUtils>(audioUtils);
logger.Information("Geekbot", "Connecting to Discord"); logger.Information("Geekbot", "Connecting to Discord");