Пример #1
0
            public void Close()
            {
                Closed = true;

                try
                {
                    if (!FfmpegProcess.HasExitedSafe())
                    {
                        FfmpegProcess.Kill();
                    }
                }
                catch { }
                try { FfmpegProcess.CancelErrorRead(); } catch { }
                try { FfmpegProcess.StandardInput.Dispose(); } catch { }
                try { FfmpegProcess.StandardOutput.Dispose(); } catch { }
                try { FfmpegProcess.Dispose(); } catch { }

                IcyStream?.Dispose();
            }
Пример #2
0
            public void ReadStreamLoop(Id id)
            {
                if (IcyStream is null)
                {
                    throw new InvalidOperationException("Instance is not an icy stream");
                }

                Tools.SetLogId(id.ToString());
                const int IcyMaxMeta     = 255 * 16;
                const int ReadBufferSize = 4096;

                int errorCount = 0;
                var buffer     = new byte[Math.Max(ReadBufferSize, IcyMaxMeta)];
                int readCount  = 0;

                while (!Closed)
                {
                    try
                    {
                        while (readCount < IcyMetaInt)
                        {
                            int read = IcyStream.Read(buffer, 0, Math.Min(ReadBufferSize, IcyMetaInt - readCount));
                            if (read == 0)
                            {
                                Close();
                                return;
                            }
                            readCount += read;
                            FfmpegProcess.StandardInput.BaseStream.Write(buffer, 0, read);
                            errorCount = 0;
                        }
                        readCount = 0;

                        var metaByte = IcyStream.ReadByte();
                        if (metaByte < 0)
                        {
                            Close();
                            return;
                        }

                        if (metaByte > 0)
                        {
                            metaByte *= 16;
                            while (readCount < metaByte)
                            {
                                int read = IcyStream.Read(buffer, 0, metaByte - readCount);
                                if (read == 0)
                                {
                                    Close();
                                    return;
                                }
                                readCount += read;
                            }
                            readCount = 0;

                            var metaString = Tools.Utf8Encoder.GetString(buffer, 0, metaByte).TrimEnd('\0');
                            Log.Debug("Meta: {0}", metaString);
                            OnMetaUpdated?.Invoke(ParseIcyMeta(metaString));
                        }
                    }
                    catch (Exception ex)
                    {
                        errorCount++;
                        if (errorCount >= 50)
                        {
                            Log.Error(ex, "Failed too many times trying to access ffmpeg. Closing stream.");
                            Close();
                            return;
                        }

                        if (ex is InvalidOperationException)
                        {
                            Log.Debug(ex, "Waiting for ffmpeg");
                            Thread.Sleep(100);
                        }
                        else
                        {
                            Log.Debug(ex, "Stream read/write error");
                        }
                    }
                }
            }