Пример #1
0
 private async Task CheckPrebufferingAsync(SongBuffer inStream, CancellationToken cancelToken, long size)
 {
     while (!inStream.BufferingCompleted && inStream.Length < size)
     {
         await Task.Delay(100, cancelToken);
     }
     _log.Debug("Buffering successfull");
 }
Пример #2
0
        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();
                }
            }
        }