Restart ffmpeg if it crashes? Maybe i should reconsider file-based cache. Ffmpeg doesn't like being slowed down it seems
This commit is contained in:
		@@ -19,20 +19,14 @@ namespace NadekoBot.Services.Music
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public string SongUri { get; private set; }
 | 
					        public string SongUri { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private volatile bool restart = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public SongBuffer(string songUri, string skipTo)
 | 
					        public SongBuffer(string songUri, string skipTo)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _log = LogManager.GetCurrentClassLogger();
 | 
					            _log = LogManager.GetCurrentClassLogger();
 | 
				
			||||||
            this.SongUri = songUri;
 | 
					            this.SongUri = songUri;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.p = Process.Start(new ProcessStartInfo
 | 
					            this.p = StartFFmpegProcess(songUri, 0);
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FileName = "ffmpeg",
 | 
					 | 
				
			||||||
                Arguments = $"-i {songUri} -f s16le -ar 48000 -vn -ac 2 pipe:1 -loglevel error -threads 0 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5",
 | 
					 | 
				
			||||||
                UseShellExecute = false,
 | 
					 | 
				
			||||||
                RedirectStandardOutput = true,
 | 
					 | 
				
			||||||
                RedirectStandardError = true,
 | 
					 | 
				
			||||||
                CreateNoWindow = true,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            var t = Task.Run(() =>
 | 
					            var t = Task.Run(() =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                this.p.BeginErrorReadLine();
 | 
					                this.p.BeginErrorReadLine();
 | 
				
			||||||
@@ -41,9 +35,27 @@ namespace NadekoBot.Services.Music
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Process StartFFmpegProcess(string songUri, float skipTo = 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return Process.Start(new ProcessStartInfo
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FileName = "ffmpeg",
 | 
				
			||||||
 | 
					                Arguments = $"-ss {skipTo:F4} -i {songUri} -f s16le -ar 48000 -vn -ac 2 pipe:1 -loglevel error -threads 0 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5",
 | 
				
			||||||
 | 
					                UseShellExecute = false,
 | 
				
			||||||
 | 
					                RedirectStandardOutput = true,
 | 
				
			||||||
 | 
					                RedirectStandardError = true,
 | 
				
			||||||
 | 
					                CreateNoWindow = true,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
 | 
					        private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _log.Error(">>> " + e.Data);
 | 
					            _log.Error(">>> " + e.Data);
 | 
				
			||||||
 | 
					            if (e.Data.Contains("Error in the pull function"))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _log.Info("Got error in the pull function!");
 | 
				
			||||||
 | 
					                restart = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly object locker = new object();
 | 
					        private readonly object locker = new object();
 | 
				
			||||||
@@ -56,14 +68,27 @@ namespace NadekoBot.Services.Music
 | 
				
			|||||||
                var sw = Stopwatch.StartNew();
 | 
					                var sw = Stopwatch.StartNew();
 | 
				
			||||||
                var delay = 1000 / maxLoopsPerSec;
 | 
					                var delay = 1000 / maxLoopsPerSec;
 | 
				
			||||||
                int currentLoops = 0;
 | 
					                int currentLoops = 0;
 | 
				
			||||||
 | 
					                int _bytesSent = 0;
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 | 
					                    do
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (restart)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var cur = _bytesSent / 3840 / (1000 / 20.0f);
 | 
				
			||||||
 | 
					                            _log.Info("Restarting");
 | 
				
			||||||
 | 
					                            try { this.p.StandardOutput.Dispose(); } catch { }
 | 
				
			||||||
 | 
					                            try { this.p.Dispose(); } catch { }
 | 
				
			||||||
 | 
					                            this.p = StartFFmpegProcess(SongUri, cur);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        restart = false;
 | 
				
			||||||
                        ++currentLoops;
 | 
					                        ++currentLoops;
 | 
				
			||||||
                        byte[] buffer = new byte[readSize];
 | 
					                        byte[] buffer = new byte[readSize];
 | 
				
			||||||
                        int bytesRead = 1;
 | 
					                        int bytesRead = 1;
 | 
				
			||||||
                        while (!cancelToken.IsCancellationRequested && !this.p.HasExited)
 | 
					                        while (!cancelToken.IsCancellationRequested && !this.p.HasExited)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, readSize, cancelToken).ConfigureAwait(false);
 | 
					                            bytesRead = await p.StandardOutput.BaseStream.ReadAsync(buffer, 0, readSize, cancelToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					                            _bytesSent += bytesRead;
 | 
				
			||||||
                            if (bytesRead == 0)
 | 
					                            if (bytesRead == 0)
 | 
				
			||||||
                                break;
 | 
					                                break;
 | 
				
			||||||
                            bool written;
 | 
					                            bool written;
 | 
				
			||||||
@@ -89,6 +114,11 @@ namespace NadekoBot.Services.Music
 | 
				
			|||||||
                            _log.Info("Song buffered completely (FFmpeg exited)");
 | 
					                            _log.Info("Song buffered completely (FFmpeg exited)");
 | 
				
			||||||
                        else if (bytesRead == 0)
 | 
					                        else if (bytesRead == 0)
 | 
				
			||||||
                            _log.Info("Nothing read");
 | 
					                            _log.Info("Nothing read");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (restart)
 | 
				
			||||||
 | 
					                            _log.Info("Lets do some magix");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    while (restart && !cancelToken.IsCancellationRequested);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (System.ComponentModel.Win32Exception)
 | 
					                catch (System.ComponentModel.Win32Exception)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user