public async Task RunCommand(CommandContext ctx, VoiceNextConnection connection) { DiscordChannel channel = ctx.Member.VoiceState.Channel; if (channel == null) { Console.WriteLine("Not connected in this guild."); } await ctx.RespondAsync("Bye Bye"); connection.Disconnect(); }
public async Task ResumePlayback(CommandContext ctx) { VoiceNextConnection vnc = await GetVNextConnection(ctx); if (vnc == null) { return; } if (!vnc.IsPlaying) { await vnc.ResumeAsync(); } }
public async Task PausePlayback(CommandContext ctx) { VoiceNextConnection vnc = await GetVNextConnection(ctx); if (vnc == null) { return; } if (vnc.IsPlaying) { vnc.Pause(); } }
public static async Task SendVoiceData(byte[] bytes, int size, VoiceNextConnection vnc) { if (MusicBot.UsersInChannel != DUtils.GetAmountInVoice(vnc.Channel) && Config.StopPlayingWithNewPlayer) { MusicBot.UsersInChannel = DUtils.GetAmountInVoice(vnc.Channel); MusicBot.StopPlayingJoined = true; } if (MusicBot.StopPlayingJoined) { return; } await vnc.SendAsync(bytes, size, 16); }
private async Task VoiceReceiveHandler(VoiceNextConnection connection, VoiceReceiveEventArgs args) { var fileName = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var ffmpeg = Process.Start(new ProcessStartInfo { FileName = "ffmpeg", Arguments = $@"-ac 1 -f s16le -ar 48000 -i pipe:0 -ac 2 -ar 44100 Output/{fileName}.wav", RedirectStandardInput = true }); await ffmpeg.StandardInput.BaseStream.WriteAsync(args.PcmData); ffmpeg.Dispose(); }
private async Task OnVoiceReceived(VoiceNextConnection vnc, VoiceReceiveEventArgs e) { if (!this._ssrcFilemap.ContainsKey(e.SSRC)) { this._ssrcFilemap[e.SSRC] = File.Create($"{e.SSRC} ({e.AudioFormat.ChannelCount}).pcm"); } var fs = this._ssrcFilemap[e.SSRC]; // e.Client.DebugLogger.LogMessage(LogLevel.Debug, "VNEXT RX", $"{e.User?.Username ?? "Unknown user"} sent voice data. {e.AudioFormat.ChannelCount}", DateTime.Now); var buff = e.PcmData.ToArray(); await fs.WriteAsync(buff, 0, buff.Length).ConfigureAwait(false); // await fs.FlushAsync().ConfigureAwait(false); }
public ProcessExt(ProcessStartInfo psi, VoiceNextConnection vnc) { try { proc = new Process(); proc.StartInfo = psi; _vnc = vnc; bool started = proc.Start(); ffout = proc.StandardOutput.BaseStream; } catch (Exception e) { Console.Write(e); } }
public async Task Remover(CommandContext ctx, VoiceNextConnection vnc) { if (Fila.Count == 0) { await vnc.SendSpeakingAsync(false); vnc?.Disconnect(); StatusDaFila = EnumeradorDeStatusDaFila.Parada; } else { var proximaExecucao = Fila.Dequeue(); await AoExecutarMusica?.Invoke(proximaExecucao); } }
public async Task StartListen(CommandContext ctx) { await JoinIfNotConnected(ctx); VoiceNextExtension voiceNextClient = ctx.Client.GetVoiceNext(); VoiceNextConnection voiceNextCon = voiceNextClient.GetConnection(ctx.Guild); if (voiceNextClient.IsIncomingEnabled) { this.ssrcMap = new ConcurrentDictionary <uint, ulong>(); this.ssrcFilemap = new ConcurrentDictionary <uint, FileStream>(); voiceNextCon.VoiceReceived += this.OnVoiceReceived; voiceNextCon.UserSpeaking += this.OnUserSpeaking; } }
public async Task StopListen(CommandContext ctx) { if (await IsClientConnected(ctx)) { VoiceNextExtension voiceNextClient = ctx.Client.GetVoiceNext(); VoiceNextConnection voiceNextCon = ctx.Client.GetVoiceNext().GetConnection(ctx.Guild); if (voiceNextClient.IsIncomingEnabled) { this.ssrcMap = new ConcurrentDictionary <uint, ulong>(); this.ssrcFilemap = new ConcurrentDictionary <uint, FileStream>(); voiceNextCon.VoiceReceived += null; voiceNextCon.UserSpeaking += null; } } }
private Task OnUserSpeaking(VoiceNextConnection vnc, UserSpeakingEventArgs e) { if (this._ssrcMap.ContainsKey(e.SSRC)) { return(Task.CompletedTask); } if (e.User == null) { return(Task.CompletedTask); } this._ssrcMap[e.SSRC] = e.User.Id; return(Task.CompletedTask); }
public async Task PlayFileAsync(CommandContext ctx, [RemainingText, Description("Full path to the file to play.")] string filename) { VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); if (vnext == null) { throw new CommandFailedException("VNext is not enabled or configured."); } VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (vnc == null) { await this.ConnectAsync(ctx); vnc = vnext.GetConnection(ctx.Guild); } if (!File.Exists(filename)) { throw new CommandFailedException($"File {Formatter.InlineCode(filename)} does not exist."); } var si = new SongInfo() { Title = filename, Provider = "Server file system", Query = ctx.Client.CurrentUser.AvatarUrl, Queuer = ctx.User.Mention, Uri = filename }; if (MusicPlayers.ContainsKey(ctx.Guild.Id)) { MusicPlayers[ctx.Guild.Id].Enqueue(si); await ctx.RespondAsync("Added to queue:", embed : si.ToDiscordEmbed(this.ModuleColor)); } else { if (!MusicPlayers.TryAdd(ctx.Guild.Id, new MusicPlayer(ctx.Client, ctx.Channel, vnc))) { throw new ConcurrentOperationException("Failed to initialize music player!"); } MusicPlayers[ctx.Guild.Id].Enqueue(si); await MusicPlayers[ctx.Guild.Id].StartAsync(); } }
/// <summary> /// Called whenever music music playback is stopped /// </summary> async Task MusicPlayBackFinished(VoiceNextConnection vnc, string command) { while (vnc.IsPlaying) ; //Do nothing while we are playing, dequeue when we stop //Remove already played song from the queue and play the next one if (qs.Count > 0) { PrevPlayingSong = playingSong; //Set previous playing song qs.Dequeue(); //Remove last played element from queue this.isSongPlaying = false; await Play(); } else if (command != "next-song") //If playback ist stopped manualy { this.isSongPlaying = false; } }
public static async Task Say(VoiceNextConnection vnc, string say) { await vnc.SendSpeakingAsync(true); // send a speaking indicator using (MemoryStream stream = new MemoryStream()) { var info = new SpeechAudioFormatInfo(48000, AudioBitsPerSample.Sixteen, AudioChannel.Stereo); using (SpeechSynthesizer synth = new SpeechSynthesizer()) { //synth.SetOutputToAudioStream(stream, info); synth.SetOutputToAudioStream(stream, info); //var t = synth.GetInstalledVoices(); //synth.SelectVoice(t.First().VoiceInfo.Name); synth.Speak(say); synth.SetOutputToNull(); } //await vnc.SendAsync(stream.ToArray(), 20, info.BitsPerSample); stream.Seek(0, SeekOrigin.Begin); Console.WriteLine("Format: {0}", info.EncodingFormat); Console.WriteLine("BitRate: {0}", info.BitsPerSample); Console.WriteLine("Block Alignment: {0}", info.BlockAlign); Console.WriteLine("Samples per second: {0}", info.SamplesPerSecond); var buff = new byte[3840]; var br = 0; while ((br = stream.Read(buff, 0, buff.Length)) > 0) { if (br < buff.Length) // not a full sample, mute the rest { for (var i = br; i < buff.Length; i++) { buff[i] = 0; } } await vnc.SendAsync(buff, 20, info.BitsPerSample); } } await vnc.SendSpeakingAsync(false); // we're not speaking anymore }
public void Start(VoiceNextConnection voiceStream) { try { _capture.StartRecording(); _localOutput?.Play(); _playing = true; Task.Run(async() => await SendToStream(voiceStream)); } catch (Exception e) { _log.Error(e, $"An error occured in the stream task: {e.Message}"); Stop(); } }
public async Task Join(CommandContext ctx, DiscordChannel chn = null) { // check whether VNext is enabled VoiceNextClient vnext = ctx.Client.GetVoiceNextClient(); if (vnext == null) { // not enabled await ctx.RespondAsync("VNext is not enabled or configured."); return; } // check whether we aren't already connected VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (vnc != null) { // already connected await ctx.RespondAsync("Already connected in this guild."); return; } // get member's voice state var vstat = ctx.Member?.VoiceState; if (vstat?.Channel == null && chn == null) { // they did not specify a channel and are not in one await ctx.RespondAsync("You are not in a voice channel."); return; } // channel not specified, use user's if (chn == null) { chn = vstat.Channel; } // connect vnc = await vnext.ConnectAsync(chn); await ctx.RespondAsync($"Connected to `{chn.Name}`"); }
public async Task <bool> TryJoinVoiceChannel(DiscordGuild guild, DiscordMember commandAuthor, DiscordMessage commandMessage) { VoiceNextConnection vnc = _voiceNextExtension.GetConnection(guild); DiscordChannel chn = commandAuthor?.VoiceState?.Channel; if (chn == null) { await commandMessage.RespondAsync("You need to be in a voice channel!"); return(false); } if (guild.AfkChannel != null && guild.AfkChannel.Id == chn.Id) { await commandMessage.RespondAsync("You are in the AFK channel!"); return(false); } if (vnc != null) { if (vnc.TargetChannel.Id == chn.Id) { await commandMessage.RespondAsync("I am already in that channel!"); } else { await commandMessage.RespondAsync("I am already in a channel for this guild!"); } return(false); } await chn.ConnectAsync(); DiscordMember bot = await guild.GetMemberAsync(_botCoreModule.DiscordClient.CurrentUser.Id); if (!bot.VoiceState.IsServerDeafened) { await bot.ModifyAsync(member => member.Deafened = true); } return(true); }
private async Task VoiceReceiveHandler(VoiceNextConnection connection, VoiceReceiveEventArgs args) { var guild = connection.TargetChannel.Guild; var user = args.User; if (guild == null || user == null) { return; } var configuration = await DataBase.GetServerConfiguration(guild.Id); UserChokeData userData = await stash[guild.Id].GetOrCreateUserData(user.Id); if (ProcessSoundData(configuration, userData, args.PcmData.ToArray())) { var member = await guild.GetMemberAsync(user.Id); await member.SetMuteAsync(true, $"Being louder than {string.Format("{0:0.##}", configuration.MaxLoudness)}% for {configuration.Interval} ms."); userData.Count = 0; userData.Time = DateTime.Now; userData.SessionChokes++; userData.LastMute = DateTime.Now; await DataBase.SetUserChokes(user.Id, ++userData.Chokes); if (configuration.MuteTime != -1) { var timer = new Timer() { AutoReset = false, Interval = configuration.MuteTime }; timer.Elapsed += async(s, e) => { await member.SetMuteAsync(false, $"{configuration.MuteTime} ms expired."); timer.Dispose(); }; timer.Start(); } } }
private async void AudioPlayingThread() { while (true) { try { PlayQueueElement elementToPlay = playQueue.Take(); Program.Client.DebugLogger.Info($"Took [{elementToPlay.Filepath}] off the queue"); // Connect if not already VoiceNextExtension voiceNextClient = Program.Client.GetVoiceNext(); VoiceNextConnection voiceNextCon = voiceNextClient.GetConnection(elementToPlay.GuildToJoin); if (voiceNextCon == null) { Program.Client.DebugLogger.Info($"Not currently connected"); Task <VoiceNextConnection> voiceNextConTask = voiceNextClient.ConnectAsync(elementToPlay.ChannelToJoin); voiceNextConTask.Wait(new TimeSpan(0, 0, 3)); if (voiceNextConTask.IsCompletedSuccessfully) { voiceNextCon = voiceNextConTask.Result; Program.Client.DebugLogger.Info($"Joined: {voiceNextCon.Channel}"); } else { Program.Client.DebugLogger.Error($"Could not join: {elementToPlay.ChannelToJoin.Name}"); continue; } } await PlayAudio(voiceNextCon, elementToPlay.Filepath); if (playQueue.Count == 0) { voiceNextCon.Disconnect(); Program.Client.DebugLogger.Info($"Leaving: {voiceNextCon.Channel}"); } } catch (Exception ex) { Program.Client.DebugLogger.Critical($"Exception was caught in the Audio Thread: {ex}"); } } }
public Task DisconnectAsync(CommandContext ctx) { VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); if (vnext is null) throw new CommandFailedException("VNext is not enabled or configured."); VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (vnc is null) throw new CommandFailedException("Not connected in this guild."); if (MusicPlayers.TryGetValue(ctx.Guild.Id, out MusicPlayer player)) { player.Stop(); MusicPlayers.TryRemove(ctx.Guild.Id, out _); } // TODO check await Task.Delay(500); vnc.Disconnect(); return this.InformAsync(ctx, StaticDiscordEmoji.Headphones, "Disconnected.", important: false); }
public async Task VolumeAsync(CommandContext ctx, [Description("volume in percents: from 0 to 250 inclusive.")] int vol) { VoiceNextConnection vnc = await GetVNextConnection(ctx); if (vnc == null) { return; } if (vol < 0 || vol > 250) { await ctx.RespondAsync(":x: Volume needs to be between 0 and 250% inclusive."); return; } VoiceTransmitSink transmitStream = vnc.GetTransmitSink(); transmitStream.VolumeModifier = vol * 0.01; await ctx.RespondAsync($"Volume set to {vol}%"); }
private async Task <VoiceNextConnection> GetVNextConnection(CommandContext ctx) { if (ctx.Channel.IsPrivate) { await ctx.RespondAsync(":x: This command is only for server use."); return(null); } VoiceNextConnection vnc = null; if (_vnext != null) { vnc = _vnext.GetConnection(ctx.Guild); } if (vnc == null) { await ctx.Message.RespondAsync(":x: Voice is not connected in this guild."); } return(vnc); }
public static async Task Play(DUser duser, bool Next = false) { MusicBot.StopPlayingJoined = false; VoiceNextClient vnext = duser.VNClient; if (vnext == null) { await DiscordUtils.SendBotMessage("VNext is not enabled or configured.", duser); } else { VoiceNextConnection vnc = duser.VNCon; if (vnc == null) { await DiscordUtils.SendBotMessage(Messages.AudioNotconnectedToServer, duser); await CommandFunctions.MusicJoinCh(duser); await Task.Delay(200); await MusicBot.Play(duser, false); } else if (Next) { MusicBot.ThreadID.Abort(); await Task.Delay(1000); MusicBot.ThreadID = new Thread((ThreadStart)(() => MusicBot.StartPlay(duser, false))); MusicBot.ThreadID.Start(); } else if (MusicBot.CurrentPlaying(duser)) { await DiscordUtils.SendBotMessage(Messages.AudioMusicAlreadyPlaying, duser); } else { MusicBot.ThreadID = new Thread((ThreadStart)(() => MusicBot.StartPlay(duser, false))); MusicBot.ThreadID.Start(); } } }
public async Task PlayAudio(CommandContext ctx, VoiceNextConnection VoiceConnection, string filePath) { if (!File.Exists(filePath)) { throw new FileNotFoundException("This file could not be found", filePath); } if (VoiceConnection.IsPlaying) { await VoiceConnection.WaitForPlaybackFinishAsync(); } Exception exc = null; await VoiceConnection.SendSpeakingAsync(true); try { var psi = new ProcessStartInfo { FileName = "ffmpeg", Arguments = $@"-i ""{filePath}"" -ac 2 -f s16le -ar 48000 pipe:1", RedirectStandardOutput = true, UseShellExecute = false }; var ffmpeg = Process.Start(psi); var ffout = ffmpeg.StandardOutput.BaseStream; ffout.CopyTo(VoiceConnection.GetTransmitStream()); } catch (Exception ex) { exc = ex; } finally { await VoiceConnection.SendSpeakingAsync(false); } if (exc != null) { await ctx.RespondAsync($"An exception occurred during playback: `{exc.GetType()}: {exc.Message}`"); } }
public async Task JoinVocal(CommandContext commandContext, DiscordChannel channel = null) { VoiceNextClient voiceNext = commandContext.Client.GetVoiceNextClient(); if (voiceNext == null) { await commandContext.RespondAsync("voiceNext == null;"); return; } VoiceNextConnection voiceConnection = voiceNext.GetConnection(commandContext.Guild); if (voiceConnection != null) { await commandContext.RespondAsync("already connected"); return; } else { await commandContext.RespondAsync("bug bug bug"); } DiscordVoiceState voiceState = commandContext.Member.VoiceState; if (voiceState.Channel == null && channel == null) { await commandContext.RespondAsync("you're not in a voice channel"); return; } if (channel == null) { channel = voiceState.Channel; } await commandContext.RespondAsync($"Connected to {channel.Name}"); voiceConnection = await voiceNext.ConnectAsync(channel); }
public async Task Leave(CommandContext ctx) { VoiceNextConnection vnc = ctx.GetVoiceNext().GetConnection(ctx.Guild); if (vnc == null) { await ctx.Message.RespondAsync("I'm not in a voice channel!"); } else if (ctx.Member.VoiceState.Channel == null) { await ctx.Message.RespondAsync("You are not in a voice channel!"); } else if (vnc.TargetChannel.Id != ctx.Member.VoiceState.Channel.Id) { await ctx.Message.RespondAsync("I am not in your channel!"); } else if (vnc != null) { vnc.Disconnect(); } }
public async Task PlayAsync() { if (Connection == null) { return; } if (AudioInfos.TryDequeue(out AudioInfo audioInfo)) { await PlayAsync(Connection, audioInfo); if (AudioInfos.Count == 0 && Connection != null) { Connection.Disconnect(); Connection = null; } else { await PlayAsync(); } } }
public async Task ConnectAsync(CommandContext ctx, [Description("Channel.")] DiscordChannel channel = null) { VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); if (vnext is null) throw new CommandFailedException("VNext is not enabled or configured."); VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (!(vnc is null)) throw new CommandFailedException("Already connected in this guild."); DiscordVoiceState vstat = ctx.Member?.VoiceState; if ((vstat is null || vstat.Channel is null) && channel is null) throw new CommandFailedException("You are not in a voice channel."); if (channel is null) channel = vstat.Channel; vnc = await vnext.ConnectAsync(channel); await this.InformAsync(ctx, StaticDiscordEmoji.Headphones, $"Connected to {Formatter.Bold(channel.Name)}.", important: false); }
public async Task Join(CommandContext ctx) { VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (vnc != null) { throw new OutputException("Already connected in this guild."); } DiscordChannel chn = ctx.Member?.VoiceState?.Channel; if (chn == null) { throw new OutputException("You need to be in a voice channel."); } vnc = await vnext.ConnectAsync(chn); await ctx.RespondAsync($"Connected to channel {vnc.Channel.Name} successfully."); }
public async Task Join(CommandContext ctx) { DiscordMessage tmp = await ctx.RespondAsync("JN: GVNC"); VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); await tmp.DeleteAsync(); tmp = await ctx.RespondAsync("JN: GGLD"); VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); await tmp.DeleteAsync(); tmp = await ctx.RespondAsync("JN: CVNC"); if (vnc != null) { throw new InvalidOperationException("Already connected in this guild."); } await tmp.DeleteAsync(); tmp = await ctx.RespondAsync("JN: CCHN"); DiscordChannel chn = ctx.Member?.VoiceState?.Channel; if (chn == null) { throw new InvalidOperationException("You need to be in a voice channel."); } await tmp.DeleteAsync(); tmp = await ctx.RespondAsync("JN: CTXC"); vnc = await vnext.ConnectAsync(chn); await tmp.DeleteAsync(); await ctx.RespondAsync("👌Connected"); }