diff --git a/BUILDS/net5.0/MusicCommands.dll b/BUILDS/net5.0/MusicCommands.dll index 5bd0425..58fc01a 100644 Binary files a/BUILDS/net5.0/MusicCommands.dll and b/BUILDS/net5.0/MusicCommands.dll differ diff --git a/BUILDS/net5.0/ref/MusicCommands.dll b/BUILDS/net5.0/ref/MusicCommands.dll index bde4210..becb33c 100644 Binary files a/BUILDS/net5.0/ref/MusicCommands.dll and b/BUILDS/net5.0/ref/MusicCommands.dll differ diff --git a/DiscordBot/Discord/Commands/Help.cs b/DiscordBot/Discord/Commands/Help.cs index 09cfc06..24388db 100644 --- a/DiscordBot/Discord/Commands/Help.cs +++ b/DiscordBot/Discord/Commands/Help.cs @@ -52,7 +52,7 @@ namespace PluginManager.Commands DMCommands += cmd.Command + " "; if (cmd.requireAdmin) adminCommands += cmd.Command + " "; - else normalCommands += cmd.Command + " "; + else if (cmd.canUseServer) normalCommands += cmd.Command + " "; } embedBuilder.AddField("Admin Commands", adminCommands); diff --git a/MusicCommands/Data.cs b/MusicCommands/Data.cs index 0d81d53..f2cc1de 100644 --- a/MusicCommands/Data.cs +++ b/MusicCommands/Data.cs @@ -1,11 +1,15 @@ using Discord; using Discord.Audio; +using MusicCommands; + namespace CMD_Utils.Music { internal static class Data { internal static IAudioClient audioClient = null; internal static IVoiceChannel voiceChannel = null; + + internal static MusicPlayer CurrentlyRunning = null; } } diff --git a/MusicCommands/Leave.cs b/MusicCommands/Leave.cs index ecff457..1b8d221 100644 --- a/MusicCommands/Leave.cs +++ b/MusicCommands/Leave.cs @@ -29,6 +29,8 @@ namespace CMD_Utils.Music { if (Data.audioClient is not null && Data.voiceChannel is not null) { + Data.CurrentlyRunning.Stop(); + Data.CurrentlyRunning = null; await Data.audioClient.StopAsync(); await Data.voiceChannel.DisconnectAsync(); } diff --git a/MusicCommands/LinkMusic.cs b/MusicCommands/LinkMusic.cs new file mode 100644 index 0000000..8247ac8 --- /dev/null +++ b/MusicCommands/LinkMusic.cs @@ -0,0 +1,26 @@ +using Discord.Net; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace MusicCommands +{ + public class LinkMusic + { + private string URL; + public LinkMusic(string URL) + { + this.URL = URL; + } + public async Task GetMusicStreamAsync() + { + WebClient client = new WebClient(); + return await client.OpenReadTaskAsync(this.URL); + } + } +} diff --git a/MusicCommands/MusicPlayer.cs b/MusicCommands/MusicPlayer.cs new file mode 100644 index 0000000..293feac --- /dev/null +++ b/MusicCommands/MusicPlayer.cs @@ -0,0 +1,57 @@ +using CMD_Utils.Music; + +using PluginManager.Others; + +using System; +using System.IO; +using System.Threading.Tasks; + +namespace MusicCommands +{ + class MusicPlayer + { + public Stream inputStream { get; private set; } // from FFMPEG + public Stream outputStream { get; private set; } // to Voice Channel + public MusicPlayer(Stream input, Stream output) + { + inputStream = input; + outputStream = output; + } + + public bool Paused { get; set; } + private bool _stop { get; set; } + public void Stop() + { + _stop = true; + } + + public async Task StartSendAudio() + { + Paused = false; + _stop = false; + while (!_stop) + { + if (Paused) continue; + int bsize = 512; + byte[] buffer = new byte[bsize]; + var bcount = await inputStream.ReadAsync(buffer, 0, bsize); + if (bcount <= 0) + { + Stop(); + Data.CurrentlyRunning = null; + break; + } + try + { + await outputStream.WriteAsync(buffer, 0, bcount); + } + catch (Exception ex) + { + await outputStream.FlushAsync(); + Functions.WriteLogFile(ex.ToString()); + } + + } + } + } +} diff --git a/MusicCommands/Pause.cs b/MusicCommands/Pause.cs index 16d9872..457b8b8 100644 --- a/MusicCommands/Pause.cs +++ b/MusicCommands/Pause.cs @@ -3,12 +3,6 @@ using Discord.WebSocket; using PluginManager.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - namespace CMD_Utils.Music { class Pause : DBCommand @@ -25,9 +19,9 @@ namespace CMD_Utils.Music public bool requireAdmin => false; - public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) { - // to be implemented + Data.CurrentlyRunning.Paused = true; } } } diff --git a/MusicCommands/Play.cs b/MusicCommands/Play.cs index c70e2b0..eb666c6 100644 --- a/MusicCommands/Play.cs +++ b/MusicCommands/Play.cs @@ -3,6 +3,8 @@ using Discord.Audio; using Discord.Commands; using Discord.WebSocket; +using MusicCommands; + using PluginManager.Interfaces; using PluginManager.Others; @@ -37,22 +39,20 @@ namespace CMD_Utils.Music return; } - // Get the audio channel Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel; if (Data.voiceChannel == 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. Data.audioClient = await Data.voiceChannel.ConnectAsync(); - - // Create FFmpeg using the previous example using (var ffmpeg = CreateStream(path)) using (var output = ffmpeg.StandardOutput.BaseStream) using (var discord = Data.audioClient.CreatePCMStream(AudioApplication.Mixed)) { - try { await output.CopyToAsync(discord); } - finally { await discord.FlushAsync(); } + if (Data.CurrentlyRunning != null) + Data.CurrentlyRunning.Stop(); + Data.CurrentlyRunning = new MusicPlayer(output, discord); + await Data.CurrentlyRunning.StartSendAudio(); } } diff --git a/MusicCommands/Unpause.cs b/MusicCommands/Unpause.cs new file mode 100644 index 0000000..e585dee --- /dev/null +++ b/MusicCommands/Unpause.cs @@ -0,0 +1,35 @@ +using CMD_Utils.Music; + +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Interfaces; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MusicCommands +{ + class Unpause : DBCommand + { + public string Command => "unpause"; + + public string Description => "Unpause the music"; + + public string Usage => "unpause"; + + public bool canUseDM => false; + + public bool canUseServer => true; + + public bool requireAdmin => false; + + public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + Data.CurrentlyRunning.Paused = false; + } + } +} diff --git a/MusicCommands/lplay.cs b/MusicCommands/lplay.cs new file mode 100644 index 0000000..43e33f3 --- /dev/null +++ b/MusicCommands/lplay.cs @@ -0,0 +1,53 @@ +using CMD_Utils.Music; +using Discord.Audio; +using Discord.Commands; +using Discord.WebSocket; +using Discord; + +using PluginManager.Interfaces; +using PluginManager.Others; + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MusicCommands +{ + class lplay : DBCommand + { + public string Command => "lplay"; + + public string Description => "Play music from a link"; + + public string Usage => "lplay [name]"; + + public bool canUseDM => false; + + public bool canUseServer => false; + + public bool requireAdmin => false; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + + + Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel; + if (Data.voiceChannel == null) { await context.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; } + + Data.audioClient = await Data.voiceChannel.ConnectAsync(); + + using (var discord = Data.audioClient.CreatePCMStream(AudioApplication.Mixed)) + { + if (Data.CurrentlyRunning != null) + Data.CurrentlyRunning.Stop(); + LinkMusic music = new LinkMusic(Functions.GetArguments(message)[0]); + Data.CurrentlyRunning = new MusicPlayer(await music.GetMusicStreamAsync(), discord); + await Data.CurrentlyRunning.StartSendAudio(); + } + } + + } +}