private async Task PlayAsync(VoiceNextConnection connection, AudioInfo audioInfo) { if (audioInfo.CommandContext.Command.Module.GetInstance(audioInfo.CommandContext.Services) is SkiCommandModule skiCommandModule) { skiCommandModule.LogMessage(audioInfo.CommandContext, $"Playing: {audioInfo.FullPath}"); try { ProcessStartInfo processStartInfo = new ProcessStartInfo("ffmpeg", $@"-loglevel panic -i ""{audioInfo.FullPath}"" -ac 2 -f s16le -ar 48000 pipe:1") { RedirectStandardOutput = true, UseShellExecute = false }; Process ffmpeg = Process.Start(processStartInfo); Stream audioStream = ffmpeg.StandardOutput.BaseStream; VoiceTransmitStream transmitStream = connection.GetTransmitStream(); await audioStream.CopyToAsync(transmitStream, Program.CancellationTokenSource.Token); await transmitStream.FlushAsync(Program.CancellationTokenSource.Token); await connection.WaitForPlaybackFinishAsync(); } catch (System.Exception e) { skiCommandModule.LogMessage(audioInfo.CommandContext, "Failed to play", e); } } }
public async Task Play() { // check whether VNext is enabled var vnext = ctx.Client.GetVoiceNext(); if (vnext == null) { // not enabled await ctx.RespondAsync("VNext is not enabled or configured."); return; } // check whether we aren't already connected vnc = vnext.GetConnection(ctx.Guild); if (vnc == null) { // already connected await ctx.RespondAsync("Not connected in this guild."); return; } // play if (vnc.IsPlaying) await ctx.RespondAsync($"Added to Queue: `{NextQueueSong.Name}` | Requested by: {UserExtension.GetUsername(ctx.Message.Author)}"); else { Exception exc = null; await vnc.SendSpeakingAsync(true); try { filename = qs.Peek().URL; //Set song filename transmitStream = vnc.GetTransmitStream(); //Get Voice transmission stream // check if music input is url and if it is not check if file exists if (!WolfBot.Tools.Network.StringNetworkTools.IsURL(filename)) { if (!File.Exists(filename)) { // file does not exist await ctx.RespondAsync($"File `{filename}` does not exist."); //Remove the invalid file from the queue qs.Dequeue(); } } else { //If the song is not skipped play it if (!qs.Peek().isSkipped) { //await ctx.Message.RespondAsync($"Now Playing `{qs.Peek().Name}` | Requested by: {UserExtension.GetUsername(ctx.Message.Author)}"); playingSong = qs.Peek(); //Add playing song //Show song info try { new SongEmbedBuilder(this); } catch { await ctx.RespondAsync("`Resource not found`"); } //Play the damm song :) PlayInternal(filename); } else { await ctx.Message.RespondAsync($"Song: `{qs.Peek().Name}` | Requested by: {UserExtension.GetUsername(ctx.Message.Author)} is skipped"); } } } catch (System.InvalidOperationException ext) { if (ext.Message == "Queue empty") { //Playback is probably over } } catch (Exception ex) { exc = ex; } finally { await vnc.SendSpeakingAsync(false); await MusicPlayBackFinished(vnc, "next-song"); } if (exc != null) await ctx.RespondAsync($"An exception occured during playback: `{exc.GetType()}: {exc.Message}`"); } }
public async Task Play(CommandContext ctx, [RemainingText, Description("Full path to the file to play.")] string filename) { // check whether VNext is enabled var vnext = ctx.Client.GetVoiceNext(); if (vnext == null) { // not enabled await ctx.RespondAsync("Voice is not enabled or configured."); return; } // check whether we aren't already connected var vnc = vnext.GetConnection(ctx.Guild); if (vnc == null) { // already connected await ctx.RespondAsync("I'm not connected to any channel."); return; } // check if file exists if (!File.Exists(filename)) { // file does not exist await ctx.RespondAsync($"File `{filename}` does not exist."); return; } // wait for current playback to finish while (vnc.IsPlaying) { await vnc.WaitForPlaybackFinishAsync(); } // play Exception exc = null; await ctx.Message.RespondAsync($"Playing `{filename}`"); await vnc.SendSpeakingAsync(true); try { // borrowed from // https://github.com/RogueException/Discord.Net/blob/5ade1e387bb8ea808a9d858328e2d3db23fe0663/docs/guides/voice/samples/audio_create_ffmpeg.cs var ffmpeg_inf = new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-i \"{filename}\" -ac 2 -f s16le -ar 48000 pipe:1", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; var ffmpeg = Process.Start(ffmpeg_inf); var ffout = ffmpeg.StandardOutput.BaseStream; VoiceTransmitStream vStream = vnc.GetTransmitStream(20); // let's buffer ffmpeg output using (var ms = new MemoryStream()) { await ffout.CopyToAsync(ms); ms.Position = 0; var buff = new byte[3840]; // buffer to hold the PCM data var br = 0; while ((br = ms.Read(buff, 0, buff.Length)) > 0) { if (br < buff.Length) // it's possible we got less than expected, let's null the remaining part of the buffer { for (var i = br; i < buff.Length; i++) { buff[i] = 0; } } //await vnc.SendAsync(buff, 20); // we're sending 20ms of data await vStream.WriteAsync(buff); } } } catch (Exception ex) { exc = ex; } finally { await vnc.SendSpeakingAsync(false); } while (vnc.IsPlaying) { await vnc.WaitForPlaybackFinishAsync(); vnc.Disconnect(); } if (exc != null) { await ctx.RespondAsync($"An exception occured during playback: `{exc.GetType()}: {exc.Message}`"); } }