start music player

This commit is contained in:
Ben Harris 2018-01-11 01:36:30 -05:00
parent 2fe479a94b
commit f8409f328e
6 changed files with 129 additions and 2 deletions

40
Commands/Music.cs Normal file
View File

@ -0,0 +1,40 @@
//////////////////////////////////////////////////////////////////////
// https://gist.github.com/Joe4evr/773d3ce6cc10dbea6924d59bbfa3c62a //
//////////////////////////////////////////////////////////////////////
using Discord;
using Discord.Commands;
using System.Threading.Tasks;
public class Music : ModuleBase<ICommandContext>
{
private readonly AudioService _service;
public Music(AudioService service)
{
_service = service;
}
// You *MUST* mark these commands with 'RunMode.Async'
// otherwise the bot will not respond until the Task times out.
[Command("join", RunMode = RunMode.Async)]
public async Task JoinCmd()
{
await _service.JoinAudio(Context.Guild, (Context.User as IVoiceState).VoiceChannel);
}
// Remember to add preconditions to your commands,
// this is merely the minimal amount necessary.
// Adding more commands of your own is also encouraged.
[Command("leave", RunMode = RunMode.Async)]
public async Task LeaveCmd()
{
await _service.LeaveAudio(Context.Guild);
}
[Command("play", RunMode = RunMode.Async)]
public async Task PlayCmd([Remainder] string song)
{
await _service.SendAudioAsync(Context.Guild, Context.Channel, song);
}
}

View File

@ -88,7 +88,7 @@ namespace dotbot.Commands
return true;
}
internal async string DoMove(SocketUserMessage msg)
internal async Task<string> DoMove(SocketUserMessage msg)
{
if (!Active || Players[Turn] != msg.Author.Id) return "";

View File

@ -43,6 +43,7 @@ namespace dotbot
.AddSingleton<PollService>()
.AddSingleton<HangmanService>()
.AddSingleton<TicTacToeService>()
.AddSingleton<AudioService>()
.AddSingleton<Random>()
.AddSingleton(_config);

80
Services/AudioService.cs Normal file
View File

@ -0,0 +1,80 @@
//////////////////////////////////////////////////////////////////////
// https://gist.github.com/Joe4evr/773d3ce6cc10dbea6924d59bbfa3c62a //
//////////////////////////////////////////////////////////////////////
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Discord;
using Discord.Audio;
public class AudioService
{
private readonly ConcurrentDictionary<ulong, IAudioClient> ConnectedChannels = new ConcurrentDictionary<ulong, IAudioClient>();
public async Task JoinAudio(IGuild guild, IVoiceChannel target)
{
if (ConnectedChannels.TryGetValue(guild.Id, out IAudioClient client))
{
return;
}
if (target.Guild.Id != guild.Id)
{
return;
}
var audioClient = await target.ConnectAsync();
if (ConnectedChannels.TryAdd(guild.Id, audioClient))
{
// If you add a method to log happenings from this service,
// you can uncomment these commented lines to make use of that.
//await Log(LogSeverity.Info, $"Connected to voice on {guild.Name}.");
}
}
public async Task LeaveAudio(IGuild guild)
{
if (ConnectedChannels.TryRemove(guild.Id, out IAudioClient client))
{
await client.StopAsync();
//await Log(LogSeverity.Info, $"Disconnected from voice on {guild.Name}.");
}
}
public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path)
{
// Your task: Get a full path to the file if the value of 'path' is only a filename.
if (!File.Exists(path))
{
await channel.SendMessageAsync("File does not exist.");
return;
}
if (ConnectedChannels.TryGetValue(guild.Id, out IAudioClient client))
{
//await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}");
using (var output = CreateStream(path).StandardOutput.BaseStream)
using (var stream = client.CreatePCMStream(AudioApplication.Music))
{
try { await output.CopyToAsync(stream); }
finally { await stream.FlushAsync(); }
}
}
}
private Process CreateStream(string path)
{
return Process.Start(new ProcessStartInfo
{
FileName = "ytdl-bin/ffmpeg.exe",
Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false,
RedirectStandardOutput = true
});
}
}

View File

@ -26,7 +26,7 @@ namespace dotbot.Services
if (_activeGames.ContainsKey(id))
{
var game = _activeGames[id];
await context.Channel.SendMessageAsync($"{game.DoMove(msg)}\n\n{game}");
await context.Channel.SendMessageAsync($"{game.DoMove(msg).Result}\n\n{game}");
}
}

View File

@ -19,6 +19,12 @@
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="ytdl-bin\ffmpeg.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="ytdl-bin\youtube-dl.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="_config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>