public async Task Say([Remainder]string text = null) { await Stop(); var outFormat = new WaveFormat(48000, 16, 2); using (var ss = new SpeechSynthesizer()) using (var discord = _vClient.CreatePCMStream(AudioApplication.Music)) using (var tstream = new MemoryStream()) { ss.Volume = 100; ss.SelectVoiceByHints(VoiceGender.Female, VoiceAge.Adult, 0, new System.Globalization.CultureInfo("nl-NL")); ss.SetOutputToWaveStream(tstream); ss.Speak(text); tstream.Flush(); tstream.Seek(0, SeekOrigin.Begin); using (var wave = new WaveFileReader(tstream)) using (var resampler = new MediaFoundationResampler(wave, outFormat)) { resampler.ResamplerQuality = 60; int blockSize = outFormat.AverageBytesPerSecond / 50; byte[] buffer = new byte[blockSize]; int byteCount; while ((byteCount = resampler.Read(buffer, 0, blockSize)) > 0) { if (byteCount < blockSize) { for (int i = byteCount; i < blockSize; i++) { buffer[i] = 0; } } discord.Write(buffer, 0, blockSize); } wave.Flush(); } tstream.Flush(); discord.Flush(); } }
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 void initVoiceStreams() { for (int i = 0; i < MAX_VOICE_STREAMS; i++) { voiceStreams.Add(audioClient.CreatePCMStream(AudioApplication.Voice, 128 * 1024)); } }
/// <summary> /// Sends the audio to the output some bytes at a time /// </summary> /// <param name="path">The path to the song (youtube url)</param> /// <returns></returns> private async void SendAudio(System.IO.Stream path) { var output = path; var stream = client.CreatePCMStream(AudioApplication.Music); int bufferSize = 4096; //Play around with this value int bytesSent = 0; byte[] buffer = new byte[bufferSize]; songPlaying = true; isSongPlaying = new TaskCompletionSource <bool>(); while (!exit) { try { if (restart) { //Reset the output and the stream if it needs to be restarted output = CreateLinkStream(CurrentSong.Item1).StandardOutput.BaseStream; stream = client.CreatePCMStream(AudioApplication.Music); bytesSent = 0; restart = false; } //Read from the output up to buffersize into the buffer int read = await output.ReadAsync(buffer, 0, bufferSize); if (read == 0) { exit = true; break; } //Write into the stream to play the music await stream.WriteAsync(buffer, 0, read); //Empty loop for pausing the music while (pause) { ; } bytesSent += read; } catch (TaskCanceledException) { exit = true; } catch { } } //Flush the stream await stream.FlushAsync(); exit = false; isSongPlaying.SetResult(true); }
// private Process CreateStream() // { // return Process.Start(new ProcessStartInfo // { // FileName = "ffmpeg", // Arguments = "-v verbose -report -probesize 2147483647 -i test -ac 2 -ar 48000 -f s16le pipe:1", // UseShellExecute = false, // RedirectStandardOutput = true, // RedirectStandardInput = true, // RedirectStandardError = true, // }); // } private async Task SendAsync(IAudioClient client, Video video) { var a = await GetManifestAsync(video); IStreamInfo info = a.GetAudioOnly().WithHighestBitrate(); await youtube.Videos.Streams.DownloadAsync(info, "test"); //using (var ytVideo = await youtube.Videos.Streams.GetAsync(streamInfo)) using (var ffmpeg = FFmpegUtils.CreateFFmpeg(fFmpegArguments)) using (var output = ffmpeg.StandardOutput.BaseStream) //using (var input = ffmpeg.StandardInput.BaseStream) using (var discord = client.CreatePCMStream(AudioApplication.Mixed)) { try { await output.CopyToAsync(discord); } catch (Exception e) { System.Console.WriteLine(e.ToString()); } finally { await discord.FlushAsync(); } } }
public async Task SendAudioAsync(SocketGuild guild, ISocketMessageChannel channel, string filePath) { // 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 = _audioClient.CreatePCMStream(AudioApplication.Music)) { try { await output.CopyToAsync(stream); } catch (Exception e) { throw new Exception("Stopped audio stream"); } finally { await stream.FlushAsync(); } } }
public async Task deneme() { IVoiceChannel channel = (Context.User as IVoiceState).VoiceChannel; IAudioClient client = await channel.ConnectAsync(); var stream = client.CreatePCMStream(AudioApplication.Music); }
public async Task PlayAudioAsync() { while (Queue.Count != 0) { CurrentlyPlaying = Queue.Dequeue(); //dequeue the latest video try { await DownloadVideo(CurrentlyPlaying); } catch (Exception e) { Console.WriteLine(e.Message); continue; } using (var ffmpeg = CreateStream($"{id}.mp3")) using (var output = ffmpeg.StandardOutput.BaseStream) using (var discord = _audioClient.CreatePCMStream(AudioApplication.Mixed)) { FFmpegId = ffmpeg.Id; try { await output.CopyToAsync(discord); } finally { await discord.FlushAsync(); CurrentlyPlaying = null; } } } await _audioClient.StopAsync(); }
private async Task SpeakAsync(IAudioClient client) { try { using (var reader = new WaveFileReader("Audio/Test123.wav")) { var naudio = WaveFormatConversionStream.CreatePcmStream(reader); //using (var waveOut = new WaveOutEvent()) //{ // waveOut.Init(naudio); // Log.Logger.Debug("Playing sounds..."); // waveOut.Play(); // while (waveOut.PlaybackState == PlaybackState.Playing) // { // Thread.Sleep(1000); // } //} var dstream = client.CreatePCMStream(AudioApplication.Music); await naudio.CopyToAsync(dstream); dstream.Flush(); client.StopAsync().Wait(); } } catch (Exception e) { Log.Logger.Error(e, "Error while sending to discord"); } }
public VoiceConnection(IVoiceChannel voiceChannel, IAudioClient audioClient) { VoiceChannel = voiceChannel; AudioClient = audioClient; CancelToken = null; AudioStream = AudioClient.CreatePCMStream(AudioApplication.Mixed, voiceChannel.Bitrate); }
private async Task Say(IAudioClient connection, string sound, SocketVoiceChannel channel) { try { await connection.SetSpeakingAsync(true); // send a speaking indicator var psi = new ProcessStartInfo { FileName = "ffmpeg", Arguments = $@"-re -i ""audio/{sound}.wav"" -ac 2 -f s16le -ar 48000 pipe:1", RedirectStandardOutput = true, UseShellExecute = false }; var ffmpeg = Process.Start(psi); var output = ffmpeg.StandardOutput.BaseStream; Tuple <IAudioClient, Process> t = new Tuple <IAudioClient, Process>(connection, ffmpeg); _connections[channel.Guild.Id] = t; var discord = connection.CreatePCMStream(AudioApplication.Voice); await output.CopyToAsync(discord); await discord.FlushAsync(); Tuple <IAudioClient, Process> te = new Tuple <IAudioClient, Process>(connection, null); _connections[channel.Guild.Id] = te; await connection.SetSpeakingAsync(false); // we're not speaking anymore } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine($"- {ex.StackTrace}"); } }
public async Task PlayUrlAsync(Uri url, IAudioClient client) { _client = client; _client.SpeakingUpdated += OnSpeakingUpdated; _isPlaying = true; using (var ms = new MemoryStream()) { using (Stream stream = WebRequest.Create(url.ToString()) .GetResponse().GetResponseStream()) { byte[] buffer = new byte[32768]; int read; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, read); } } ms.Position = 0; using (WaveStream blockAlignedStream = new BlockAlignReductionStream( WaveFormatConversionStream.CreatePcmStream( new Mp3FileReader(ms)))) { var audioStream = _client.CreatePCMStream(AudioApplication.Mixed, 98304); await blockAlignedStream.CopyToAsync(audioStream); } } }
private async Task PlayCurrentStream(Stream streamToPlay) { CurrentStream = streamToPlay; // Get ffmepg stream var ffmepgProcess = CreateFFmpegStream(CurrentStream.StreamUrl); var stream = ffmepgProcess.StandardOutput.BaseStream; var discord = audioClient.CreatePCMStream(AudioApplication.Music, Configuration.BaseBitrate); // Start streaming try { await stream.CopyToAsync(discord, 81920, cancelationToken.Token).ConfigureAwait(false); } catch (OperationCanceledException e) { } finally { // Flush buffers / clean await discord.FlushAsync().ConfigureAwait(false); CurrentStream = null; if (!nextStream) { PlayerStopped?.Invoke(this); } else { nextStream = false; } } }
private async Task SendAsync(IAudioClient client, string[] path) { using (var discord = client.CreatePCMStream(AudioApplication.Voice)) { foreach (var item in path) { using (var ffmpeg = GetFfmpeg(item)) using (var output = ffmpeg.StandardOutput.BaseStream) { try { await output.CopyToAsync(discord); } catch (Exception exc) { ffmpeg.Close(); output.Close(); await discord.FlushAsync(); } finally { await discord.FlushAsync(); } } } } }
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(); } }
private async Task PlayMusicAsync(IAudioChannel channel, IMessageChannel outputChannel, string filename, CancellationToken cancellationToken) { IAudioClient audioClient = null; try { audioClient = await channel.ConnectAsync(); using (var ffmpeg = CreateConverterProc(filename)) using (var output = ffmpeg.StandardOutput.BaseStream) using (var discord = audioClient.CreatePCMStream(AudioApplication.Mixed)) { try { await output.CopyToAsync(discord, cancellationToken); } catch (Exception e) { Logger.Error(e); } finally { ffmpeg?.Kill(); await discord.FlushAsync(); await channel.DisconnectAsync(); } } } catch (Exception e) { Logger.Error(e); } finally { audioClient?.Dispose(); } }
public static void Initialize(IAudioClient client, ISocketMessageChannel channel) { AudioService.client = client; AudioService.channel = channel; stream = client.CreatePCMStream(AudioApplication.Mixed); }
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 void PlayMusicAsync() { Process ffmpeg = null; AudioStream pcm = null; while (true) { if (PlayList.Count > 0) { await GetAudioClient(); if (audioClient == null) { Console.WriteLine("[ERROR]"); await Task.Delay(900); } else { ffmpeg = CreateStreamAudio(await PlayList.Peek().Uri()); pcm = audioClient.CreatePCMStream(AudioApplication.Music); try { await ffmpeg.StandardOutput.BaseStream.CopyToAsync(pcm); } finally { await pcm.FlushAsync(); } } PlayList.Dequeue(); } } }
private async Task Say(IAudioClient connection, ZapSound sound) { try { await connection.SetSpeakingAsync(true); // send a speaking indicator var psi = new ProcessStartInfo { FileName = "ffmpeg", Arguments = $@"-i ""{sound.Filename}"" -ac 2 -f s16le -ar 48000 pipe:1", RedirectStandardOutput = true, UseShellExecute = false }; var ffmpeg = Process.Start(psi); var output = ffmpeg.StandardOutput.BaseStream; var discord = connection.CreatePCMStream(AudioApplication.Voice); await output.CopyToAsync(discord); await discord.FlushAsync(); await connection.SetSpeakingAsync(false); // we're not speaking anymore } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine($"- {ex.StackTrace}"); } }
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()); } }
public async Task LaunchStream(string url, IAudioClient client) { playing = true; EmbedBuilder embed = new EmbedBuilder() { Color = new Color(235, 66, 244) }; embed.Description = $"Now playing: {queue[0]}"; await ReplyAsync("", false, embed); queue.RemoveAt(0); var output = CreateStream(url).StandardOutput.BaseStream; var stream = client.CreatePCMStream(AudioApplication.Music, 480); await output.CopyToAsync(stream); await stream.FlushAsync(); if (songList.Count == 0) { playing = false; await client.StopAsync(); } else { songList.Remove(url); await LaunchStream(songList[0], client); } }
/// <summary> /// The player loop /// </summary> /// <returns></returns> private void PlayerLoop() { // Sets the highest priority for the audio thread Thread.CurrentThread.Priority = ThreadPriority.Highest; // Opens the output stream using (var output = m_AudioClient.CreatePCMStream(AudioApplication.Music, OutputFormat.SampleRate)) { // Changed the buffer to 1sec. It adds delay but sounds better on connections with higher ping. int blockSize = OutputFormat.AverageBytesPerSecond; // Establish the size of our AudioBuffer byte[] buffer = new byte[blockSize]; int read; int byteCount; // Run the player while (m_RunPlayerLoop) { // Lock this lock (m_PlayerLock) { // Wait if (m_AudioClient == null || #if USE_FFMPEG m_ProcessFFMpeg == null #else m_CurrentMusicResampler == null #endif // USE_FFMPEG ) { Thread.Sleep(100); }
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); }
public async Task PlayMusic(int ownerid, int startindex = 0, bool forceupdate = false) { Audio[] audio = null; if (forceupdate) { await Context.Channel.SendMessageAsync("Trying to force update playlist..."); await UploadPlaylist(ownerid); } else { await UploadPlaylistSilent(ownerid); } audio = Program._data.RestoreObject <Audio[]>($"{Context.Guild.Id}_{ownerid}.dat"); var channelId = (Context.User as IGuildUser)?.VoiceChannel.Id; var path = $@"{Directory.GetCurrentDirectory()}\servers\{Context.Guild.Id}\music.mp3"; await StopMusic(null, false); await JoinChannel(); var msg = Context.Channel.SendMessageAsync("", false, new EmbedBuilder().Build()); IAudioClient client = Program._data.RestoreObject <IAudioClient>($"{channelId}"); Program._data.StoreObject($"{Context.Guild.Id}.aos", client.CreatePCMStream(AudioApplication.Music)); for (int i = startindex; i < audio.Length; ++i) { if (audio[i].ContentRestricted != null) { await Context.Channel.SendMessageAsync($"{audio[i].Title} is restricted"); continue; } CancellationTokenSource tokenSource = new CancellationTokenSource(); Program._data.StoreObject($"{Context.Guild.Id}.cts", tokenSource); VKMusic.DownloadSongs(audio[i], path).Wait(); try { var vkuser = Program._vkApi.Users.Get(new long[] { ownerid }, VkNet.Enums.Filters.ProfileFields.Photo200).FirstOrDefault(); Task counter = SongCounter(msg.Result, audio[i], vkuser, i, tokenSource.Token); Task sending = SendAsync(path); await Task.WhenAny(new Task[] { sending, counter }); if (tokenSource.IsCancellationRequested) { break; } tokenSource.Cancel(); Console.WriteLine(new LogMessage(LogSeverity.Info, "BOT", "Token cancelled")); } catch (Exception e) { await Context.Channel.SendMessageAsync(e.Message); } } }
protected AudioOutStream CreateOutput() { if (output == null) { throw new NullReferenceException("You need to call SetOutput first."); } return(output.CreatePCMStream(AudioApplication.Music, 96 * 1024, 10, 0)); }
public static async Task SendAsync(IAudioClient audioClient, Process ffmpeg) { var output = ffmpeg.StandardOutput.BaseStream; var discord = audioClient.CreatePCMStream(AudioApplication.Mixed); await output.CopyToAsync(discord); await discord.FlushAsync(); }
private async Task PlayQueueAsync(IAudioClient client, SocketCommandContext Context) { try { if (queueDict.ContainsKey(Context.Guild.Id)) { List <SongStruct> queue = new List <SongStruct>(); queueDict.TryGetValue(Context.Guild.Id, out queue); for (int i = 1; i <= queue.Count;) { string name = queue[0].name; var ffmpeg = CreateStream(name); audioStream_Token strToken; if (audioStreamDict.ContainsKey(client)) { audioStreamDict.TryGetValue(client, out strToken); strToken.tokenSource.Cancel(); strToken.tokenSource.Dispose(); strToken.tokenSource = new CancellationTokenSource(); strToken.token = strToken.tokenSource.Token; audioStreamDict.TryUpdate(client, strToken); } else { strToken.audioStream = client.CreatePCMStream(AudioApplication.Music, null, 1920); strToken.tokenSource = new CancellationTokenSource(); strToken.token = strToken.tokenSource.Token; audioStreamDict.TryAdd(client, strToken); } var output = ffmpeg.StandardOutput.BaseStream; //1920, 2880, 960 await output.CopyToAsync(strToken.audioStream, 1920, strToken.token).ContinueWith(task => { if (!task.IsCanceled && task.IsFaulted) //supress cancel exception { Console.WriteLine(task.Exception); } }); ffmpeg.WaitForExit(); await strToken.audioStream.FlushAsync(); queueDict.TryGetValue(Context.Guild.Id, out queue); queue.RemoveAt(0); queueDict.TryUpdate(Context.Guild.Id, queue); } } else { await Context.Channel.SendMessageAsync(":no_entry_sign: Please add a song to the Queue first!"); } } catch (Exception e) { Console.WriteLine(e); await SentryService.SendError(e, Context); } }
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 async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) { var filename = Path.Combine(Music.MusicDataPath, DateTime.Now.UnixTimestamp().ToString()); SongBuffer inStream = new SongBuffer(MusicPlayer, filename, SongInfo, skipTo, frameBytes * 100); var bufferTask = inStream.BufferSong(cancelToken).ConfigureAwait(false); bytesSent = 0; try { var attempt = 0; var prebufferingTask = CheckPrebufferingAsync(inStream, cancelToken, 1.MiB()); //Fast connection can do this easy var finished = false; var count = 0; var sw = new Stopwatch(); var slowconnection = false; sw.Start(); while (!finished) { var t = await Task.WhenAny(prebufferingTask, Task.Delay(2000, cancelToken)); if (t != prebufferingTask) { count++; if (count == 10) { slowconnection = true; prebufferingTask = CheckPrebufferingAsync(inStream, cancelToken, 20.MiB()); _log.Warn("Slow connection buffering more to ensure no disruption, consider hosting in cloud"); continue; } if (inStream.BufferingCompleted && count == 1) { _log.Debug("Prebuffering canceled. Cannot get any data from the stream."); return; } else { continue; } } else if (prebufferingTask.IsCanceled) { _log.Debug("Prebuffering canceled. Cannot get any data from the stream."); return; } finished = true; } sw.Stop(); _log.Debug("Prebuffering successfully completed in "+ sw.Elapsed); var outStream = voiceClient.CreatePCMStream(960); int nextTime = Environment.TickCount + milliseconds; byte[] buffer = new byte[frameBytes]; while (!cancelToken.IsCancellationRequested) { //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------"); var read = await inStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); //await inStream.CopyToAsync(voiceClient.OutputStream); if(read < frameBytes) _log.Debug("read {0}", read); unchecked { bytesSent += (ulong)read; } if (read < frameBytes) { if (read == 0) { if (inStream.BufferingCompleted) break; if (attempt++ == 20) { MusicPlayer.SongCancelSource.Cancel(); break; } if (slowconnection) { _log.Warn("Slow connection has disrupted music, waiting a bit for buffer"); await Task.Delay(1000, cancelToken).ConfigureAwait(false); } else await Task.Delay(100, cancelToken).ConfigureAwait(false); } else attempt = 0; } else attempt = 0; while (this.MusicPlayer.Paused) await Task.Delay(200, cancelToken).ConfigureAwait(false); buffer = AdjustVolume(buffer, MusicPlayer.Volume); if (read != frameBytes) continue; nextTime = unchecked(nextTime + milliseconds); int delayMillis = unchecked(nextTime - Environment.TickCount); if (delayMillis > 0) await Task.Delay(delayMillis, cancelToken).ConfigureAwait(false); await outStream.WriteAsync(buffer, 0, read).ConfigureAwait(false); } } finally { await bufferTask; if(inStream != null) inStream.Dispose(); } }