Esempio n. 1
0
 public MusicStreamer(StreamRequest parent, string directUrl)
 {
     this.parent = parent;
     this.buffer = new DualStream();
     this.Url    = directUrl;
     State       = StreamState.Queued;
 }
Esempio n. 2
0
        /*  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);
                }
            }
        }
Esempio n. 3
0
        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);
                    }
                }
            }
        }