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.IO;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
@ -63,23 +64,32 @@ namespace Geekbot.net.Commands
}
}
// [Command("play")]
// public async Task play(IVoiceChannel channel = null)
// {
// 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;
// }
//
// }
// catch (Exception e)
// {
// _errorHandler.HandleCommandException(e, Context);
// }
// }
[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 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,17 +1,28 @@
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.Net;
namespace Geekbot.net.Lib
{
public class AudioUtils : IAudioUtils
{
private string _tempFolderPath;
private Dictionary<ulong, IAudioClient> _audioClients;
public AudioUtils()
{
_audioClients = new Dictionary<ulong, IAudioClient>();
_tempFolderPath = Path.GetFullPath("./temp/");
if (!Directory.Exists(_tempFolderPath))
{
Directory.CreateDirectory(_tempFolderPath);
}
}
public IAudioClient GetAudioClient(ulong guildId)
{
return _audioClients[guildId];
@ -21,11 +32,62 @@ namespace Geekbot.net.Lib
{
_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
{
IAudioClient GetAudioClient(ulong guildId);
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
* Redis
* Discord.net
* ffmpeg
## Running