public async Task StopAudioInput() { StopMicConnectWatcher(); if (_FrameOutputNode == null) { return; } if (_AudioOutStream == null) { return; } _FrameOutputNode.Stop(); await _AudioOutStream.FlushAsync(); using (var release = await _OutputStreamLock.LockAsync()) { _AudioGraph.QuantumStarted -= AudioGraph_QuantumStarted; if (_AudioOutStream != null) { _AudioOutStream.Dispose(); _AudioOutStream = null; } } }
public VoiceConnection(IVoiceChannel voiceChannel, IAudioClient audioClient) { VoiceChannel = voiceChannel; AudioClient = audioClient; CancelToken = null; AudioStream = AudioClient.CreatePCMStream(AudioApplication.Mixed, voiceChannel.Bitrate); }
public async Task StartQueue(EduardoContext context) { queueCts = new CancellationTokenSource(); List <SongInfo> guildQueue = GetGuildQueue(context.Guild.Id); if (guildQueue.Count == 0) { await context.Channel.SendMessageAsync($"There are no songs in the queue! Use `{Constants.CMD_PREFIX}queue add <song>` to add items to the queue"); return; } await JoinAudio(context); if (_connectedChannels.TryGetValue(context.Guild.Id, out IAudioClient client)) { using AudioOutStream stream = client.CreatePCMStream(AudioApplication.Music, bufferMillis: 1); while (guildQueue.Count > 0 && !queueCts.IsCancellationRequested) { await SendAudioAsync(context, guildQueue.First(), stream); } } await LeaveAudio(context.Guild); }
private async Task SendAudioAsync(EduardoContext context, SongInfo song, AudioOutStream discordStream) { audioCts = new CancellationTokenSource(); await ShowCurrentSong(context); await Logger.Log($"Starting playback of {song.Name} in {context.Guild.Name}", LogSeverity.Debug); SongBuffer songBuffer = null; try { songBuffer = new SongBuffer(song.StreamUrl); songBuffer.StartBuffering(audioCts.Token); RestUserMessage message = await context.Channel.SendMessageAsync("Video is buffering, please wait a moment..."); await songBuffer.PrebufferingCompleted.Task; await message.DeleteAsync(); //await Task.WhenAny(Task.Delay(10000), songBuffer.PrebufferingCompleted.Task); if (audioCts.IsCancellationRequested) { return; } int bytesSent = 0; while (true) { byte[] buffer = songBuffer.Read(FrameBytes).ToArray(); if (buffer.Length == 0) { break; } AdjustVolume(buffer, volume); await discordStream.WriteAsync(buffer, 0, buffer.Length, audioCts.Token); bytesSent += buffer.Length; song.CurrentTime = TimeSpan.FromSeconds(bytesSent / (float)FrameBytes / (1000 / Milliseconds)); await(pauseTaskSource?.Task ?? Task.CompletedTask); } } catch (Exception ex) when(!(ex is OperationCanceledException cancelledException) || cancelledException.CancellationToken.IsCancellationRequested) { } finally { await discordStream.FlushAsync(); songBuffer?.Dispose(); } }
public async Task PlayAsync(Uri input) { using (await playSync.EnterAsync()) { end = false; using (IWaveSource source = CodecFactory.Instance.GetCodec(input).ChangeSampleRate(Discord.Audio.Streams.OpusEncodeStream.SampleRate)) { int size = source.WaveFormat.BytesPerSecond / 50; byte[] buffer = new byte[size]; int read; using (AudioOutStream output = AudioClient.CreatePCMStream(AudioApplication.Music)) { while (!end && (read = source.Read(buffer, 0, size)) > 0) { if (read < size) { for (int i = read; i < size; ++i) { buffer[i] = 0; } } output.Write(buffer, 0, size); } output.Flush(); } end = true; awaiter?.TrySetResult(source.Length <= source.Position); } } }
private async Task UpdateSends(System.Threading.CancellationToken newListener) { foreach (var kvpSpeaker in ConnectedChannels) { IAudioClient speaker = kvpSpeaker.Value; await speaker.SetSpeakingAsync(true); AudioOutStream speak = speaker.CreateDirectOpusStream(); Console.WriteLine("Speaker"); foreach (var kvpListener in ConnectedChannels.Where(c => !speaker.Equals(c))) { Console.WriteLine("Listener"); IAudioClient listener = kvpListener.Value; await kvpListener.Value.CreateOpusStream().CopyToAsync(speaker.CreateOpusStream()); var users = (await(listener as IVoiceChannel).GetUsersAsync().FlattenAsync()).Where(u => !u.IsBot); foreach (var user in users) { await ListenUserAsync(user).CopyToAsync(speak); } } await speak.WriteAsync(new byte[3840], newListener); await speaker.SetSpeakingAsync(false); } }
public async Task <bool> StreamToVoiceAsync(string fileName) { this._ffmpeg = CreateStream($"{Startup.AppConfig.RootDirectory}user-intros/{fileName}"); this._ffmpegStream = this._ffmpeg.StandardOutput.BaseStream; IAudioClient client = await this.ConnectAsync(this._destinationChannel.Id); if (client == null) { Logger.Warning($"Failed to connect to voice channel [{this._destinationChannel.Name}] in [{this.Guild.Name}]"); Dispose(); return(false); } this._outputStream = client.CreatePCMStream(AudioApplication.Mixed); try { await this._ffmpegStream.CopyToAsync(this._outputStream); } finally { await this._outputStream.FlushAsync(); await DisconnectAsync(); Dispose(); } return(true); }
private void speak(string text) { var delay = (1) * text.Split().Length; while (DateTime.Now - whenSpeakRan < TimeSpan.FromSeconds(delay)) { Thread.Sleep(125); } SpeechSynthesizer tts = new SpeechSynthesizer(); tts.SelectVoice(( string )cmbTTS.SelectedItem); tts.Volume = sliderTTSVol.Value * 5; tts.Rate = sliderTTSSpeed.Value - 10; MemoryStream ms = new MemoryStream(); tts.SetOutputToAudioStream(ms, formatInfo); if (voiceStream == null) { voiceStream = audioClient.CreatePCMStream(AudioApplication.Voice, 128 * 1024); } tts.SpeakAsync(text); tts.SpeakCompleted += (a, b) => { ms.Seek(0, SeekOrigin.Begin); ms.CopyTo(voiceStream); voiceStream.Flush(); }; whenSpeakRan = DateTime.Now; }
private async Task SendAsync() { if (audioClient == null) { await Context.Channel.SendMessageAsync("Please make the bot join a channel first"); } else { i = 0; while (i != Queue.Count) { try { // Create FFmpeg using the previous example var ffmpeg = CreateStream(Queue[i]); output = ffmpeg.StandardOutput.BaseStream; discord = audioClient.CreatePCMStream(AudioApplication.Mixed); await Context.Channel.SendMessageAsync($"Now playing {Queue[i].Replace(@"music\", "").Replace(".flac", "")} in {Context.Channel.Name} "); await(Context.Client as DiscordSocketClient).SetGameAsync(Queue[i].Replace(@"music\", "").Replace(".flac", "")); await output.CopyToAsync(discord); await discord.FlushAsync(); }catch { i++; await Task.Delay(2000); continue; } i++; } Queue.Clear(); } }
public static void Initialize(IAudioClient client, ISocketMessageChannel channel) { AudioService.client = client; AudioService.channel = channel; stream = client.CreatePCMStream(AudioApplication.Mixed); }
private async Task SendAudioAsync(IGuild guild, string filePath) { if (_isPlaying) { return; } if (_connectedChannels.TryGetValue(guild.Id, out IAudioClient audioClient)) { _audioOutStream = _audioOutStream ?? audioClient.CreatePCMStream(AudioApplication.Voice); using (var mp3 = new Mp3FileReader(filePath)) using (var pcmStream = WaveFormatConversionStream.CreatePcmStream(mp3)) { try { _isPlaying = true; await pcmStream.CopyToAsync(_audioOutStream); } finally { await _audioOutStream.FlushAsync(); await pcmStream.FlushAsync(); _isPlaying = false; } } } }
public async Task SendAudioAsync(SocketGuild guild, ISocketMessageChannel channel, string path) { string filePath = $"Data/Music/{path}.mp3"; if (!File.Exists(filePath)) { await channel.SendMessageAsync("File does not exist."); return; } if (_audioClients.TryGetValue(guild.Id, out IAudioClient client)) { using (Stream output = CreateStream(filePath).StandardOutput.BaseStream) using (AudioOutStream stream = client.CreatePCMStream(AudioApplication.Music)) { try { await output.CopyToAsync(stream); } catch (Exception e) { _logger.LogError(e, "Stopped audio stream"); } finally { await stream.FlushAsync(); } } } }
public async Task PlaySong(int seconds, string path, AudioOutStream aclient) { musicproc = Process.Start(new ProcessStartInfo { FileName = "ffmpeg.exe", Arguments = " -loglevel quiet" + " -ss " + seconds + $" -i " + " \"" + Program.config.musicPath + path.Trim() + "\" " + //strip.wma "-f s16le -ar 48000 -ac 2 pipe:1", UseShellExecute = false, CreateNoWindow = false, RedirectStandardOutput = true, RedirectStandardError = false }); try { while (true) { if (musicproc.HasExited) { break; } await musicproc.StandardOutput.BaseStream.CopyToAsync(aclient); } } catch (Exception e) { Logger.Error("Playing song", e); } await aclient.FlushAsync(); }
public static void SpeakFile(string path, int vol = 100) { lock (speaklock) { if (IsConnectedToChannel()) { if (voiceStream == null) { voiceStream = audioClient.CreatePCMStream(AudioApplication.Voice, 128 * 1024); } try { Process sound = CreateStream(path, vol); Stream output = sound.StandardOutput.BaseStream; output.CopyTo(voiceStream); voiceStream.Flush(); sound.Close(); } catch (Exception e) { Log($"Sound Stream Error: {e}"); } } } }
public async Task StartAudioInput(IAudioClient audioClient) { StartMicConnectWatcher(); if (_AudioOutStream != null) { _AudioOutStream.Dispose(); _AudioOutStream = null; } if (InputDeviceState != InputDeviceState.Avairable) { if (!await ResetAudioInput()) { return; } } _AudioOutStream = audioClient.CreatePCMStream(AudioApplication.Voice, 1920, 100); _FrameOutputNode.Stop(); _AudioGraph.QuantumStarted += AudioGraph_QuantumStarted; _FrameOutputNode.Start(); _AudioGraph.Start(); }
public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path) { //await Logger.LogAsync(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; } try { IAudioClient client; if (ConnectedChannels.TryGetValue(guild.Id, out client)) { //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}"); Process process = CreateStream(path); AudioOutStream stream = client.CreatePCMStream(AudioApplication.Music); process.Start(); Stream output = process.StandardOutput.BaseStream; await output.CopyToAsync(stream); await stream.FlushAsync(); } } catch (Exception ex) { Logger.Log(ex.ToString()); } }
private async Task PlaySnippet(TriviaItem item) { _questions.RemoveAt(0); _currentItem = item; if (_streamCanceller != null) { _streamCanceller.Dispose(); } _streamCanceller = new CancellationTokenSource(); _streamProcess = CreateStream("Resources/Music/" + item.filepath); _outputStream = _streamProcess.StandardOutput.BaseStream; if (_discordStream == null) { _discordStream = _audioConnection.CreatePCMStream(AudioApplication.Music); } try { Task killTask = Task.Run(() => _streamProcess.WaitForExit(30000), _streamCanceller.Token); await Task.WhenAny(killTask, _outputStream.CopyToAsync(_discordStream, _streamCanceller.Token)); await EndSnippet(); } catch (Exception e) { Console.WriteLine(e.ToString()); } }
private async Task WriteStreamToVoiceChannel(AudioClient audioClient, AudioOutStream discord, MemoryStream memoryStream) { try { await discord.WriteAsync(memoryStream.ToArray(), 0, (int)memoryStream.Length); } finally { await memoryStream.DisposeAsync(); await discord.FlushAsync(); await discord.DisposeAsync(); // Clear current stream audioClient.CurrentStream = null; // Play next AudioOnlyStreamInfo nextSong = audioClient.GetNextSong(); if (nextSong != null) { this.StartStream(youtube, audioClient, nextSong, null); } } }
private async void StartStream(YoutubeClient youtube, AudioClient audioClient, AudioOnlyStreamInfo streamInfo, IMessage?message) { Stream ytStream = await youtube.Videos.Streams.GetAsync(streamInfo); // Convert yt stream MemoryStream memoryStream = new MemoryStream(); await Cli.Wrap("ffmpeg") .WithArguments(" -hide_banner -loglevel panic -i pipe:0 -ac 2 -f s16le -ar 48000 pipe:1") .WithStandardInputPipe(PipeSource.FromStream(ytStream)) .WithStandardOutputPipe(PipeTarget.ToStream(memoryStream)) .ExecuteAsync(); // Clear stream before beginning if (audioClient.CurrentStream != null) { audioClient.CurrentStream.Dispose(); audioClient.CurrentStream = null; } AudioOutStream discord = audioClient.Client.CreatePCMStream(AudioApplication.Mixed); audioClient.CurrentStream = discord; // Delete calling command if (message != null) { await message.DeleteAsync(); } // Start playing music await this.WriteStreamToVoiceChannel(audioClient, discord, memoryStream); }
public static async void LeaveChannel() { voiceStream?.Close(); voiceStream = null; await audioClient.StopAsync(); await voiceChannel.DisconnectAsync(); }
private Task BufferClip(string clip) { return(Task.Factory.StartNew(() => { try { var OutFormat = new WaveFormat(48000, 16, 2); // Create a new Output Format, using the spec that Discord will accept, and with the number of channels that our client supports. using (var MP3Reader = new Mp3FileReader(clip)) // Create a new Disposable MP3FileReader, to read audio from the filePath parameter using (var resampler = new MediaFoundationResampler(MP3Reader, OutFormat)) // Create a Disposable Resampler, which will convert the read MP3 data to PCM, using our Output Format { resampler.ResamplerQuality = 60; // Set the quality of the resampler to 60, the highest quality int blockSize = OutFormat.AverageBytesPerSecond / 50; // Establish the size of our AudioBuffer byte[] buffer = new byte[blockSize]; int byteCount; if (m_outStream == null) { m_outStream = m_audioClient.CreatePCMStream(AudioApplication.Mixed, bufferMillis: 10); } int writes = 0; while ((byteCount = resampler.Read(buffer, 0, blockSize)) > 0) // Read audio into our buffer, and keep a loop open while data is present { if (m_clipCancellationSource.Token.IsCancellationRequested) { m_clipCancellationSource = new CancellationTokenSource(); return; } if (byteCount < blockSize) { // Incomplete Frame for (int i = byteCount; i < blockSize; i++) { buffer[i] = 0; } } lock (m_playbackMutex) { if (m_outStream != null) { m_outStream.Write(buffer, 0, blockSize); // Send the buffer to Discord } } writes++; } } } catch { //this is ok for the moment as currently it may assert if the channel changes m_outStream = null; } //} while (dequeued); }, m_clipCancellationSource.Token)); }
private async Task RandomQueue(IVoiceChannel channel = null) { Queue.Clear(); try { // Get the audio channel channel = channel ?? (Context.Message.Author as IGuildUser)?.VoiceChannel; if (channel == 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. audioClient = await channel.ConnectAsync(); } catch (Exception e) { await Context.Channel.SendMessageAsync(e.Message); } List <int> RandomIndex = new List <int>(); DirectoryInfo d = new DirectoryInfo(@"music\");//Assuming Test is your Folder FileInfo[] Files = d.GetFiles("*.flac"); foreach (FileInfo file in Files) { Queue.Add(file.Name); } foreach (int j in UniqueRandom(0, Queue.Count - 1)) { RandomIndex.Add(j); } i = 0; while (i != Queue.Count) { try { // Create FFmpeg using the previous example var ffmpeg = CreateStream(@"music\\" + Queue[RandomIndex[i]]); output = ffmpeg.StandardOutput.BaseStream; discord = audioClient.CreatePCMStream(AudioApplication.Mixed); await Context.Channel.SendMessageAsync($"Now playing {Queue[RandomIndex[i]].Replace(@"music\", "").Replace(".flac", "")} in {Context.Channel.Name} "); await(Context.Client as DiscordSocketClient).SetGameAsync(Queue[RandomIndex[i]].Replace(@"music\", "").Replace(".flac", "")); await output.CopyToAsync(discord); await discord.FlushAsync(); } catch { i++; await Task.Delay(2000); continue; } i++; } Queue.Clear(); }
public CurrentAudioInformation(ConcurrentQueue <string> queue, IAudioClient client, AudioOutStream currentStream, CancellationTokenSource cancelTokenSource, string playing, SocketVoiceChannel channel) { this.queue = queue; this.client = client; this.currentStream = currentStream; this.cancelTokenSource = cancelTokenSource; this.playing = playing; voiceChannel = channel; }
internal static async Task <AudioOutStream> GetStream() { if (Client != null && Out == null) { Out = Client.CreateDirectPCMStream(AudioApplication.Music, 2880, 2); } return(Out); }
public void PlayFile(string filePath) { var OutFormat = new WaveFormat(48000, 16, 1); // Create a new Output Format, using the spec that Discord will accept, and with the number of channels that our Client supports. AudioOutStream currentStream = AudioClient.CreatePCMStream(AudioApplication.Mixed); using (var MP3Reader = new Mp3FileReader(filePath)) // Create a new Disposable MP3FileReader, to read audio from the filePath parameter using (var resampler = new MediaFoundationResampler(MP3Reader, OutFormat)) // Create a Disposable Resampler, which will convert the read MP3 data to PCM, using our Output Format { resampler.ResamplerQuality = 60; // Set the quality of the resampler to 60, the highest quality int blockSize = OutFormat.AverageBytesPerSecond / 50; // Establish the size of our AudioBuffer byte[] buffer = new byte[blockSize]; byte[] silence = new byte[blockSize]; int byteCount = resampler.Read(buffer, 0, blockSize); while (byteCount > 0) // Read audio into our buffer, and keep a loop open while data is present { if (RequestStop) { RequestStop = false; FinishedSong(); return; } if (byteCount < blockSize) { // Incomplete Frame for (int i = byteCount; i < blockSize; i++) { buffer[i] = 0; } } for (int i = 0; i < buffer.Length; i += 2) { short sample = (short)(buffer[i] | (buffer[i + 1] << 8)); short result = (short)(sample * Volume); buffer[i] = (byte)(result & 0xFF); buffer[i + 1] = (byte)(result >> 8); } try { currentStream.WriteAsync(Paused ? silence : buffer, 0, blockSize).GetAwaiter(); //Send buffer to Discord } catch (Exception e) { Console.WriteLine(e.Message); AudioClient = null; CurrentState = AudioState.Stopped; break; } if (!Paused) { byteCount = resampler.Read(buffer, 0, blockSize); } } FinishedSong(); } }
public static async void LeaveChannel() { voiceStream?.Close(); voiceStream = null; if (IsConnectedToChannel()) { await audioClient.StopAsync(); } await bot.SetGameAsync("with Discord"); }
public static async Task SendUrlAsync(IAudioClient client, string url) { using (Process ffmpeg = YTStream(url)) { output = ffmpeg.StandardOutput.BaseStream; discord = client.CreatePCMStream(AudioApplication.Mixed); try { await output.CopyToAsync(discord); } finally { await discord.FlushAsync(); } } }
/// <summary> /// Play a music /// </summary> public async Task PlayAsync() { // If the playlist is empty, the current song is not finished yet or the song that need to be played is still downloading if (Playlist.Count == 0 || (_process != null && !_process.HasExited) || Playlist[0].Downloading) { return; } if (Playlist.Count == 1) // There is only one music remaining in the playlist so we add a custom suggestion based on the last one { _ = Task.Run(AddAutosuggestionAsync); } await _textChan.SendMessageAsync(embed : Playlist[0].Embed); if (!File.Exists("ffmpeg.exe")) { throw new FileNotFoundException("ffmpeg.exe was not found near the bot executable."); } _process = Process.Start(new ProcessStartInfo { FileName = "ffmpeg.exe", // -af volume=0.2 reduce the volume of the song since by default it's really loud Arguments = $"-hide_banner -loglevel panic -i \"{Playlist[0].Path}\" -af volume=0.2 -ac 2 -f s16le -ar 48000 pipe:1", UseShellExecute = false, RedirectStandardOutput = true, }); using (Stream output = _process.StandardOutput.BaseStream) using (AudioOutStream discord = _audioClient.CreatePCMStream(AudioApplication.Music)) { try { await output.CopyToAsync(discord); } catch (OperationCanceledException) // If we stopped the music midway (stop/skip command) { // If force the GC to do his job so we can safely delete the music file GC.Collect(); GC.WaitForPendingFinalizers(); File.Delete(Playlist[0].Path); } await discord.FlushAsync(); } File.Delete(Playlist[0].Path); Playlist.RemoveAt(0); if (Playlist.Count == 0) { await StopAsync(); StaticObjects.Radios.Remove(_guildId); } else { await PlayAsync(); // If there are others songs in the playlist, we play the next one } }
public async void Dispose() { await AudioClient.StopAsync(); FFMPEGProcess = null; DiscordOutStream = null; Videos = null; RadioTimer = null; CurrentSong = ""; MessageClient = null; AudioClient = null; }
private void CreateRecordStream() { if (this.stream == null) { // TRANSLATORS: Log message. In AudioManager. Logger.Log(T._("- create stream ...")); this.stream = this.audioClient.CreatePCMStream(AudioApplication.Voice, this.bitrate); } // TRANSLATORS: Log message. In AudioManager. Logger.Log(T._("- start recording ...")); this.input.StartRecording(); }