start music player
This commit is contained in:
parent
2fe479a94b
commit
f8409f328e
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 "";
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace dotbot
|
|||
.AddSingleton<PollService>()
|
||||
.AddSingleton<HangmanService>()
|
||||
.AddSingleton<TicTacToeService>()
|
||||
.AddSingleton<AudioService>()
|
||||
.AddSingleton<Random>()
|
||||
.AddSingleton(_config);
|
||||
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue