public async Task PlayTrack(CommandContext ctx, Track track) { VoiceNextConnection vnc = _voiceNextExtension.GetConnection(ctx.Guild); bool isConnected = vnc != null; if (vnc != null && vnc.IsPlaying) { await ctx.Message.RespondAsync("I am already playing something!"); return; } if (isConnected) { DiscordChannel chn = ctx.Member.VoiceState?.Channel; if (chn == null) { await ctx.Message.RespondAsync("You need to be in a voice channel!"); return; } else if (ctx.Guild.AfkChannel != null && ctx.Guild.AfkChannel.Id == chn.Id) { await ctx.Message.RespondAsync("You are in the AFK channel!"); return; } else if (vnc.TargetChannel.Id != chn.Id) { await ctx.Message.RespondAsync("I am not in your channel!"); return; } } if (isConnected || await TryJoinVoiceChannel(ctx)) { if (!isConnected) { vnc = _voiceNextExtension.GetConnection(ctx.Guild); } ProcessStartInfo psi = new ProcessStartInfo { FileName = _config.FfmpegLocation, Arguments = $@"-i ""{Path.Combine(_config.AudioFolderLocation, track.GetFileName())}"" -ac 2 -f s16le -ar 48000 pipe:1", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; Process ffmpeg = Process.Start(psi); Stream ffout = ffmpeg.StandardOutput.BaseStream; VoiceTransmitSink txStream = vnc.GetTransmitSink(); await ffout.CopyToAsync(txStream); await txStream.FlushAsync(); } }
public async Task SendToStream(VoiceNextConnection voiceStream) { try { var sink = voiceStream.GetTransmitSink(_soundSettings.SampleSize); var bytesPerSample = _remoteBuffer.BytesPerSample(sink.SampleDuration); streamBuffer = new byte[bytesPerSample]; await Task.Delay(_soundSettings.BufferDurationMs); while (_playing) { if (_remoteBuffer.BufferedBytes >= bytesPerSample) { _remoteBuffer.Read(streamBuffer, 0, bytesPerSample); await sink.WriteAsync(streamBuffer, 0, bytesPerSample); } } } catch (Exception e) { _log.Error(e, $"An error occured during transmission to stream: {e.Message}"); Stop(); } }
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}%"); }
public async Task Play(CommandContext ctx, [Description("full path to the file to play."), RemainingText] string filename) { VoiceNextConnection vnc = await GetVNextConnection(ctx); if (vnc == null) { return; } if (filename == null) { await ctx.RespondAsync("No file specified."); return; } if (!File.Exists(filename)) { await ctx.RespondAsync($"File `{filename}` does not exist."); return; } while (vnc.IsPlaying) { await ctx.Message.RespondAsync("Waiting for audio to end."); await vnc.WaitForPlaybackFinishAsync(); } await ctx.Message.RespondAsync($"Playing `{filename}`"); await vnc.SendSpeakingAsync(); try { /* borrowed from * https://github.com/RogueException/Discord.Net/blob/5ade1e387bb8ea808a9d858328e2d3db23fe0663/docs/guides/voice/samples/audio_create_ffmpeg.cs */ var ffmpegInf = new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-i \"{filename}\" -ac 2 -f s16le -ar 48000 pipe:1", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; Process ffmpeg = Process.Start(ffmpegInf); if (ffmpeg != null) { Stream ffout = ffmpeg.StandardOutput.BaseStream; VoiceTransmitSink transmit = vnc.GetTransmitSink(); await ffout.CopyToAsync(transmit); await transmit.FlushAsync(); await vnc.WaitForPlaybackFinishAsync(); ffout.Close(); } } catch (Exception ex) { await ctx.RespondAsync($"An exception occured during playback: `{ex.GetType()}: {ex.Message}`"); } }
public async Task Play(CommandContext ctx, [RemainingText, Description("Full path to the file to play.")] string path) { string filename = Path.Combine(Directory.GetCurrentDirectory(), "Audios", path); VoiceNextExtension vnext = ctx.Client.GetVoiceNext(); if (vnext == null) { await ctx.RespondAsync("VNext is not enabled or configured."); return; } VoiceNextConnection vnc = vnext.GetConnection(ctx.Guild); if (vnc == null) { await ctx.RespondAsync("Not connected in this guild."); return; } if (!File.Exists(filename)) { await ctx.RespondAsync($"File `{path}` does not exist."); return; } while (vnc.IsPlaying) { await vnc.WaitForPlaybackFinishAsync(); } Exception exc = null; await ctx.Message.RespondAsync($"Playing `{path}`"); try { await vnc.SendSpeakingAsync(); Stream ffout = new FfmpegUtils().GetffmpegStream(filename); VoiceTransmitSink txStream = vnc.GetTransmitSink(); await ffout.CopyToAsync(txStream); await txStream.FlushAsync(); await vnc.WaitForPlaybackFinishAsync(); } catch (Exception ex) { exc = ex; } finally { await vnc.SendSpeakingAsync(false); await ctx.Message.RespondAsync($"Finished playing `{path}`"); } if (exc != null) { await ctx.RespondAsync($"An exception occured during playback: `{exc.GetType()}: {exc.Message}`"); } }