Exemple #1
0
        static void Main(string[] args)
        {
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);

            try
            {
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i].Substring(0, 2) != "--")
                    {
                        switch (args[i])
                        {
                        case "-p": SourcePath = args[++i].TrimEnd('\\'); break;

                        case "-it": InputsType = args[++i].TrimStart('.').ToLower(); break;

                        case "-i": Intervals = int.TryParse(args[++i], out int intervals) ? intervals : 3; break;
                        }
                    }
                    else
                    {
                        string param = args[i].Remove(args[i].IndexOf('=') + 1);
                        string value = args[i].Substring(args[i].IndexOf('=') + 1);
                        switch (param)
                        {
                        case "--path": SourcePath = value.TrimEnd('\\'); break;

                        case "--inputs_type": InputsType = value.TrimStart('.').ToLower(); break;

                        case "--output_type": OutputType = value.TrimStart('.').ToLower(); break;

                        case "--interval": Intervals = int.TryParse(value, out int intervals) ? intervals : 3; break;

                        case "--preset":
                            if (Enum.GetNames(typeof(PresetType)).Any(type => type.ToLower() == args[i + 1].ToLower()))
                            {
                                FFMpegSettings.Preset = (PresetType)Enum.Parse(typeof(PresetType), value, true);
                            }
                            else
                            {
                                PresetRecord = value;
                            }
                            break;

                        case "--crf":
                            if (int.TryParse(value, out int crfScale))
                            {
                                FFMpegSettings.CRFScale = crfScale;
                            }
                            else
                            {
                                FFMpegSettings.CRFScale = -1;
                            }
                            break;

                        case "--aq":
                            if (decimal.TryParse(args[i + 1], out decimal audioQuality))
                            {
                                FFMpegSettings.AudioQuality = Math.Round(audioQuality, 1, MidpointRounding.AwayFromZero);
                            }
                            else
                            {
                                FFMpegSettings.AudioQuality = -1;
                            }
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log(contents: "Error input", messageType: MessageType.ERROR);
                Log(contents: ex.Message, messageType: MessageType.ERROR);
                Console.WriteLine();
                return;
            }

            Log(contents: "Start processing");
            long beginTick = DateTime.Now.Ticks;

            if (!Directory.Exists(SourcePath))
            {
                Log(contents: $@"Can NOT match the source folder ""{ SourcePath }""", messageType: MessageType.ERROR);
            }
            else if (!typeof(Format).GetFields(BindingFlags.Public | BindingFlags.Static).Any(format => format.Name.ToLower() == InputsType))
            {
                Log(contents: $@"""{ InputsType.ToUpper() }"" is NOT support for input", messageType: MessageType.ERROR);
            }
            else if (!typeof(Format).GetFields(BindingFlags.Public | BindingFlags.Static).Any(format => format.Name.ToLower() == OutputType))
            {
                Log(contents: $@"""{ OutputType.ToUpper() }"" is NOT support for output", messageType: MessageType.ERROR);
            }
            else if (!string.IsNullOrEmpty(PresetRecord))
            {
                Log(contents: $@"""{ PresetRecord.ToUpper() }"" is NOT support for preset type", messageType: MessageType.ERROR);
            }
            else if (51 < FFMpegSettings.CRFScale || FFMpegSettings.CRFScale < 0)
            {
                Log(contents: $@"""{ FFMpegSettings.CRFScale }"" is out of CRF scale range (the value should be 0-51)", messageType: MessageType.ERROR);
            }
            else if (10m < FFMpegSettings.AudioQuality || FFMpegSettings.AudioQuality < 0.1m)
            {
                Log(contents: $@"""{ FFMpegSettings.AudioQuality }"" is out of audio quality range (the value should be 1-10)", messageType: MessageType.ERROR);
            }
            else
            {
                try
                {
                    Log(contents: "Parse the folder structure", messageType: MessageType.INFO);
                    Videos     = new Dictionary <string, List <Video> >();
                    PassVideos = new List <string[]>();
                    foreach (var videoPath in Directory.GetFiles(SourcePath, $"*.{ InputsType }").ToList())
                    {
                        string videoName = videoPath;
                        videoName = videoName.Remove(0, videoName.LastIndexOf('\\') + 1);
                        videoName = videoName.Remove(videoName.LastIndexOf('.'));


                        if (Videos.Count <= 0)
                        {
                            Videos.Add(videoName, new List <Video>()
                            {
                                new Video()
                                {
                                    Name = videoName,
                                    Path = videoPath,
                                    Type = InputsType
                                }
                            });
                        }
                        else
                        {
                            int length = DateTime.Now.ToString("yyyyMMdd_HHmmss").Length;
                            if (videoName.Length != length)
                            {
                                PassVideos.Add(new string[] { videoName, $"Error name format (length != { length })" });
                            }
                            else if (!Regex.IsMatch(videoName, @"^\d+_\d+$"))
                            {
                                PassVideos.Add(new string[] { videoName, $"Error name format (is not all numbers)" });
                            }
                            else
                            {
                                DateTime lastTime = DateTime.ParseExact(Videos.Last().Value.Last().Name, "yyyyMMdd_HHmmss", CultureInfo.InvariantCulture);
                                DateTime thisTime = DateTime.ParseExact(videoName, "yyyyMMdd_HHmmss", CultureInfo.InvariantCulture);

                                if ((thisTime - lastTime).TotalMinutes <= Intervals)
                                {
                                    Videos.Last().Value.Add(new Video()
                                    {
                                        Name = videoName,
                                        Path = videoPath,
                                        Type = InputsType
                                    });
                                }
                                else
                                {
                                    Videos.Add(videoName, new List <Video>()
                                    {
                                        new Video()
                                        {
                                            Name = videoName,
                                            Path = videoPath,
                                            Type = InputsType
                                        }
                                    });
                                }
                            }
                        }
                    }
                    DisplayVideos();

                    // Init FFMpegConverter
                    FFMpegConverter = new FFMpegConverter();
                    FFMpegConverter.ConvertProgress += FFMpegConverter_ConvertProgress;
                    var format = typeof(Format)
                                 .GetFields(BindingFlags.Public | BindingFlags.Static)
                                 .First(f => f.Name.ToLower() == OutputType).Name;

                    // Join videos
                    foreach (var pair in Videos)
                    {
                        try
                        {
                            string folderPath = $@"{ SourcePath }\Joins";
                            if (!Directory.Exists(folderPath))
                            {
                                Directory.CreateDirectory(folderPath);
                            }

                            JoinVideoName = pair.Key;

                            Log(contents: $"Preparing to join video in { JoinVideoName }.{ format.ToString() }",
                                messageType: MessageType.INFO);

                            FFMpegConverter.ConcatMedia(
                                inputFiles: pair.Value.Select(video => video.Path).ToArray(),
                                outputFile: $@"{ folderPath }\{ pair.Key }.{ format.ToString() }",
                                outputFormat: Format.mov.ToString(),
                                settings: new ConcatSettings()
                            {
                                CustomOutputArgs = FFMpegSettings.GetArgsLine()
                            });

                            ClearCurrentConsoleLine();
                            Log(contents: $"Join video in { JoinVideoName }.{ format.ToString() }",
                                messageType: MessageType.INFO,
                                writeMode: WriteMode.Append);
                            Log(contents: " take", messageType: MessageType.INFO, withTitle: false, writeMode: WriteMode.Append);
                            Log(contents:
                                $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Days.ToString().PadLeft(2, ' ') } d" +
                                $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Hours.ToString().PadLeft(2, ' ') } h" +
                                $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Minutes.ToString().PadLeft(2, ' ') } m" +
                                $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Seconds.ToString().PadLeft(2, ' ') } s",
                                messageType: MessageType.TIME, withTitle: false, onlyTitleColor: false);
                        }
                        catch (Exception ex)
                        {
                            Log(contents: $"Join video in { JoinVideoName }.{ format.ToString() } ({ ex.Message })",
                                messageType: MessageType.ERROR);
                        }
                    }

                    // Summary
                    Log(contents: $"Process exited in",
                        messageType: MessageType.INFO, withTitle: true, writeMode: WriteMode.Append);
                    Log(contents:
                        $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Days.ToString() } d" +
                        $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Hours.ToString() } h" +
                        $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Minutes.ToString() } m" +
                        $" { new TimeSpan(DateTime.Now.Ticks - beginTick).Seconds.ToString() } s",
                        messageType: MessageType.TIME, withTitle: false, onlyTitleColor: false, writeMode: WriteMode.Append);
                }
                catch (Exception ex) { Log(contents: ex.Message, messageType: MessageType.ERROR); }
            }
            Console.WriteLine();
        }