Exemplo n.º 1
0
        public static int ConvertAndDecode(string inputFile, string inputFileType, string outputFile)
        {
            ProcessStartInfo startInfo = GetStartInfo($"ffmpeg -hide_banner -loglevel warning -i \"{inputFile}\" -f {inputFileType} - | sox -V2 -V2 -t {inputFileType} - -t raw -e signed-integer -b 16 -r 22050 - remix 1", true, true);
            FileStream       fs        = null;

            if (outputFile != null)
            {
                File.WriteAllText(outputFile, string.Empty);
                fs = new FileStream(outputFile, FileMode.OpenOrCreate);
            }

            ulong bytesReadIn = 0;

            using (Process soxProcess = Process.Start(startInfo)) {
                if (!Program.SuppressInfo)
                {
                    Console.WriteLine("info: ffmpeg and sox have started");
                }
                soxProcess.EnableRaisingEvents = true;
                soxProcess.BeginErrorReadLine();
                soxProcess.ErrorDataReceived += new DataReceivedEventHandler((s, e) => {
                    if (!string.IsNullOrWhiteSpace(e.Data))
                    {
                        Console.WriteLine($"proc: {e.Data}\n");                         // arguments have been modified in ffmpeg so that it only prints to standard error when warnings are raised or errors occur
                    }
                });

                FileStream baseStream   = (FileStream)soxProcess.StandardOutput.BaseStream;
                int        lastRead     = 0;
                bool       record       = false;
                bool       lastRecord   = false;
                string     fileName     = null;
                bool       needToBuffer = true;

                Console.WriteLine();
                do                      // sox nor ffmpeg will not produce anything on stdout if an error occurs
                {
                    byte[] buffer = new byte[8192];
                    lastRead     = baseStream.Read(buffer, 0, buffer.Length);
                    bytesReadIn += (ulong)lastRead;
                    Tuple <bool, uint, uint> info = null;
                    if (lastRead > 0)
                    {
                        info       = Decode.DecodeEAS(buffer, lastRead);
                        lastRecord = record;
                        record     = info.Item1;
                        if (fs != null)
                        {
                            fs.Write(buffer, 0, lastRead);
                            fs.Flush();
                        }
                    }
                    if (!record && !lastRecord)
                    {
                        Console.CursorTop -= 1;
                        Console.WriteLine($"Total bytes read in: {Commas(bytesReadIn)}");
                    }
                    else if (!record && lastRecord)
                    {
                        Console.WriteLine();
                    }

                    if (bufferBefore != null)
                    {
                        if (needToBuffer)
                        {
                            for (int i = 0; i < lastRead; i++)
                            {
                                bufferBefore.Enqueue(buffer[i]);
                            }
                            if (easRecord != null && bufferBefore.Size == bufferBefore.Count)
                            {
                                Console.WriteLine("Stopped recording EAS alert");
                                SaveEASRecording(ref easRecord, bufferBefore, fileName);
                            }
                        }
                        if (record && easRecord == null)
                        {
                            Console.WriteLine("Recording EAS alert");
                            DateTime recordingStarted = DateTime.Now;
                            string   month            = $"{AddLeadingZero(recordingStarted.Month)}{months[recordingStarted.Month - 1]}";
                            string   time             = $"{AddLeadingZero(recordingStarted.Hour)}{AddLeadingZero(recordingStarted.Minute)}{AddLeadingZero(recordingStarted.Second)}";
                            fileName = $"{recordingStarted.Year}_{month}_{recordingStarted.Day} - {time}";

                            int idx = 1;
                            while (File.Exists($"{fileName} ({idx}).raw"))
                            {
                                idx++;
                            }
                            fileName += $" ({idx})";

                            easRecord = new FileStream($"{fileName}.raw", FileMode.OpenOrCreate);
                            while (!bufferBefore.IsEmpty)
                            {
                                byte[] b = new byte[1];
                                if (bufferBefore.TryDequeue(out b[0]))
                                {
                                    easRecord.Write(b);
                                }
                            }
                            needToBuffer = false;
                        }
                        else if (record && easRecord != null)
                        {
                            if (needToBuffer)
                            {
                                while (!bufferBefore.IsEmpty)
                                {
                                    byte[] b = new byte[1];
                                    if (bufferBefore.TryDequeue(out b[0]))
                                    {
                                        easRecord.Write(b);
                                    }
                                    needToBuffer = false;
                                }
                            }
                            else
                            {
                                easRecord.Write(buffer, 0, lastRead);
                            }
                        }
                        else if (!record && easRecord != null && !needToBuffer)
                        {
                            easRecord.Write(buffer, 0, lastRead);
                            needToBuffer = true;
                            bufferBefore = new FixedSizeQueue <byte>(bitrate * 5);
                        }
                    }
                } while (lastRead > 0);

                if (easRecord != null)
                {
                    SaveEASRecording(ref easRecord, bufferBefore, fileName);
                }
                soxProcess.WaitForExit();
            }
            return(0);
        }