/* public string Stats() => * "--------------------------------\n" + * $"Music stats for {string.Join("", parent.Title.TrimTo(50))}\n" + * $"Server: {parent.Server.Name}\n" + * $"Length:{buffer.Length * 1.0f / 1.MB()}MB Status: {State}\n" + * "--------------------------------\n";*/ private async Task BufferSong() { //start feeding the buffer var p = Process.Start(new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-i {Url} -f s16le -ar 48000 -ac 2 pipe:1", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Normal, }); int attempt = 0; while (true) { while (buffer.writePos - buffer.readPos > 5.MB() && State != StreamState.Completed) { prebufferingComplete = true; await Task.Delay(200); } if (State == StreamState.Completed) { try { p.CancelOutputRead(); p.Close(); } catch (Exception) { } Console.WriteLine("Buffering canceled, stream is completed."); return; } if (buffer.readPos > 5.MiB() && buffer.writePos > 5.MiB()) // if buffer is over 5 MiB, create new one { var skip = 5.MB(); //remove only 5 MB, just in case var newBuffer = new DualStream(); lock (_bufferLock) { byte[] data = buffer.ToArray().Skip(skip).ToArray(); var newReadPos = buffer.readPos - skip; var newPos = buffer.Position - skip; buffer = newBuffer; buffer.Write(data, 0, data.Length); buffer.readPos = newReadPos; buffer.Position = newPos; } } var buf = new byte[2048]; int read = 0; read = await p.StandardOutput.BaseStream.ReadAsync(buf, 0, 2048); // Console.WriteLine($"Read: {read}"); if (read == 0) { if (attempt == 5) { try { p.CancelOutputRead(); p.Close(); } catch (Exception) { } Console.WriteLine($"Didn't read anything from the stream for {attempt} attempts. {buffer.Length/1.MB()}MB length"); return; } else { ++attempt; await Task.Delay(20); } } else { attempt = 0; await buffer.WriteAsync(buf, 0, read); } } }
private async Task BufferSong() { //start feeding the buffer var p = Process.Start(new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-i {Url} -f s16le -ar 48000 -ac 2 pipe:1 -loglevel quiet", //+ (NadekoBot.IsLinux ? "2> /dev/null" : "2>NUL"), UseShellExecute = false, RedirectStandardOutput = true, }); int attempt = 0; while (true) { while (buffer.writePos - buffer.readPos > 5.MB() && State != StreamState.Completed) { prebufferingComplete = true; await Task.Delay(200); } if (State == StreamState.Completed) { try { p.CancelOutputRead(); p.Close(); } catch { } Console.WriteLine("Buffering canceled, stream is completed."); return; } if (buffer.readPos > 5.MiB() && buffer.writePos > 5.MiB()) { var skip = 5.MB(); lock (_bufferLock) { byte[] data = new byte[buffer.Length - skip]; Buffer.BlockCopy(buffer.GetBuffer(), skip, data, 0, (int)(buffer.Length - skip)); var newReadPos = buffer.readPos - skip; var newPos = buffer.Position - skip; buffer = new DualStream(); buffer.Write(data, 0, data.Length); buffer.readPos = newReadPos; buffer.Position = newPos; } } int blockSize = 1920 * NadekoBot.client.GetService <AudioService>()?.Config?.Channels ?? 3840; var buf = new byte[blockSize]; int read = 0; read = await p.StandardOutput.BaseStream.ReadAsync(buf, 0, blockSize); //Console.WriteLine($"Read: {read}"); if (read == 0) { if (attempt == 5) { try { p.Dispose(); } catch { } Console.WriteLine($"Didn't read anything from the stream for {attempt} attempts. {buffer.Length / 1.MB()}MB length"); return; } else { ++attempt; await Task.Delay(20); } } else { attempt = 0; lock (_bufferLock) { buffer.Write(buf, 0, read); } } } }