Groundwork for playing youtube videos to voice

This commit is contained in:
runebaas 2018-01-11 00:16:04 +01:00
parent a52982cbcd
commit 1ee627a915
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
3 changed files with 93 additions and 20 deletions

View file

@ -1,4 +1,5 @@
using System; using System;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
@ -63,23 +64,32 @@ namespace Geekbot.net.Commands
} }
} }
// [Command("play")] [Command("ytplay")]
// public async Task play(IVoiceChannel channel = null) public async Task ytplay(string url)
// { {
// try try
// { {
// var audioClient = _audioUtils.GetAudioClient(Context.Guild.Id); if (!url.Contains("youtube"))
// if (audioClient == null) {
// { await ReplyAsync("I can only play youtube videos");
// await Context.Channel.SendMessageAsync("I'm not in a voice channel at the moment"); return;
// return; }
// } var audioClient = _audioUtils.GetAudioClient(Context.Guild.Id);
// if (audioClient == null)
// } {
// catch (Exception e) await ReplyAsync("I'm not in a voice channel at the moment");
// { return;
// _errorHandler.HandleCommandException(e, Context); }
// } var ffmpeg = _audioUtils.CreateStreamFromYoutube(url, Context.Guild.Id);
// } var output = ffmpeg.StandardOutput.BaseStream;
var discord = audioClient.CreatePCMStream(Discord.Audio.AudioApplication.Mixed);
await output.CopyToAsync(discord);
await discord.FlushAsync();
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
}
}
} }
} }

View file

@ -1,15 +1,26 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using Discord.Audio; using Discord.Audio;
using Discord.Net;
namespace Geekbot.net.Lib namespace Geekbot.net.Lib
{ {
public class AudioUtils : IAudioUtils public class AudioUtils : IAudioUtils
{ {
private string _tempFolderPath;
private Dictionary<ulong, IAudioClient> _audioClients; private Dictionary<ulong, IAudioClient> _audioClients;
public AudioUtils() public AudioUtils()
{ {
_audioClients = new Dictionary<ulong, IAudioClient>(); _audioClients = new Dictionary<ulong, IAudioClient>();
_tempFolderPath = Path.GetFullPath("./temp/");
if (!Directory.Exists(_tempFolderPath))
{
Directory.CreateDirectory(_tempFolderPath);
}
} }
public IAudioClient GetAudioClient(ulong guildId) public IAudioClient GetAudioClient(ulong guildId)
@ -21,11 +32,62 @@ namespace Geekbot.net.Lib
{ {
_audioClients[guildId] = 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}.mp3");
}
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 System.Exception("Could not get Youtube Media URL");
}
return output;
}
private void DownloadMediaUrl(string url, ulong guildId)
{
var ffmpeg = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-re -i \"${url}\" -c:a mp3 -b:a 256k {_tempFolderPath}\\{guildId}.mp3",
UseShellExecute = false,
RedirectStandardOutput = true,
};
Process.Start(ffmpeg).WaitForExit();
return;
}
} }
public interface IAudioUtils public interface IAudioUtils
{ {
IAudioClient GetAudioClient(ulong guildId); IAudioClient GetAudioClient(ulong guildId);
void StoreAudioClient(ulong guildId, IAudioClient client); void StoreAudioClient(ulong guildId, IAudioClient client);
Process CreateStreamFromFile(string path);
Process CreateStreamFromYoutube(string url, ulong guildId);
} }
} }

View file

@ -11,6 +11,7 @@ You can invite Geekbot to your server with [this link](https://discordapp.com/oa
* DotNet Core 2 * DotNet Core 2
* Redis * Redis
* Discord.net * Discord.net
* ffmpeg
## Running ## Running