示例#1
0
        private static void FFmpegSceneDetect()
        {
            // Skip Scene Detect if the file already exist
            if (File.Exists(Path.Combine(Global.temp_path, Global.temp_path_folder, "splits.txt")) == false)
            {
                Helpers.Logging("Scene Detection with FFmpeg");

                List <string> scenes = new List <string>();

                // Starts FFmpeg Process
                Process          FFmpegSceneDetect = new Process();
                ProcessStartInfo startInfo         = new ProcessStartInfo
                {
                    WindowStyle           = ProcessWindowStyle.Hidden,
                    UseShellExecute       = false,
                    CreateNoWindow        = true,
                    WorkingDirectory      = Global.FFmpeg_Path,
                    RedirectStandardError = true,
                    FileName  = "cmd.exe",
                    Arguments = "/C ffmpeg.exe -i " + '\u0022' + Global.Video_Path + '\u0022' + " -hide_banner -loglevel 32 -filter_complex select=" + '\u0022' + "gt(scene\\," + FFmpeg_Threshold + "),select=eq(key\\,1),showinfo" + '\u0022' + " -an -f null -"
                };
                FFmpegSceneDetect.StartInfo = startInfo;
                FFmpegSceneDetect.Start();

                // Reads Standard Err from FFmpeg Output
                string stream = FFmpegSceneDetect.StandardError.ReadToEnd();

                FFmpegSceneDetect.WaitForExit();

                // Splits the Console Output by spaces
                string[] array = stream.Split(' ');

                // Searches for pts_time, if found it removes "pts_time:" to get only values
                foreach (string value in array)
                {
                    if (value.Contains("pts_time:"))
                    {
                        scenes.Add(value.Remove(0, 9));
                    }
                }

                // Temporary value for Arg creation
                string previousScene = "0.000";

                // Clears the Args List to avoid conflicts in Batch Encode Mode
                FFmpegArgs.Clear();

                // Creates the seeking args for ffmpeg piping
                foreach (string sc in scenes)
                {
                    FFmpegArgs.Add("-ss " + previousScene + " -to " + sc);
                    previousScene = sc;
                }
                // Argument for seeking until the end of the video
                FFmpegArgs.Add("-ss " + previousScene);

                // Writes splitting arguments to text file
                foreach (string line in FFmpegArgs)
                {
                    using (StreamWriter sw = File.AppendText(Path.Combine(Global.temp_path, Global.temp_path_folder, "splits.txt")))
                    {
                        sw.WriteLine(line);
                        sw.Close();
                    }
                }

                if (File.Exists(Path.Combine(Global.temp_path, Global.temp_path_folder, "splits.txt")))
                {
                    Global.Video_Chunks = File.ReadAllLines(Path.Combine(Global.temp_path, Global.temp_path_folder, "splits.txt")); // Reads the split file for VideoEncode() function
                }
            }
        }
示例#2
0
        private static void FFmpegChunking()
        {
            // Skips Splitting of already existent
            if (!File.Exists(Path.Combine(Global.temp_path, Global.temp_path_folder, "splitting.log")))
            {
                // Create Chunks Folder
                Helpers.Create_Temp_Folder(Path.Combine(Global.temp_path, Global.temp_path_folder, "Chunks"));

                // Generate Command
                string ffmpeg_command = "/C ffmpeg.exe";
                ffmpeg_command += " -y -i " + '\u0022' + Global.Video_Path + '\u0022';                                              // Video Input
                ffmpeg_command += " -reset_timestamps 1 -map_metadata -1 -sn -an";                                                  // Remove unnecessary metadata etc

                if (skip_reencode)
                {
                    ffmpeg_command += " -c:v copy";
                }
                else
                {
                    if (encode_method == 0)
                    {
                        ffmpeg_command += " -c:v libx264 -preset ultrafast -crf 0";                                                     // Re-Encoding - Needed because else it WILL loose frames
                    }
                    else if (encode_method == 1)
                    {
                        ffmpeg_command += " -c:v ffv1 -level 3 -threads 4 -coder 1 -context 1 -slicecrc 0 -slices 4";                   // Re-Encoding - Needed because else it WILL loose frames
                    }
                    else if (encode_method == 2)
                    {
                        ffmpeg_command += " -c:v utvideo";                                                                              // Re-Encoding - Needed because else it WILL loose frames
                    }

                    // Hardsub
                    if (MainWindow.subHardSubEnabled)
                    {
                        ffmpeg_command += " " + MainWindow.hardsub_command;
                    }

                    // Filters
                    ffmpeg_command += MainWindow.FilterCommand;

                    // Reset Filter Command so it is not being used later by encoders
                    MainWindow.FilterCommand = "";

                    ffmpeg_command += " -sc_threshold 0 -g " + chunking_length;                                                         // Make Splitting more accurate
                    ffmpeg_command += " -force_key_frames " + '\u0022' + "expr:gte(t, n_forced * " + chunking_length + ")" + '\u0022';  // Make Splitting more accurate
                }

                ffmpeg_command += " -segment_time " + chunking_length + " -f segment " + '\u0022';                                  // Segmenting
                ffmpeg_command += Path.Combine(Global.temp_path, Global.temp_path_folder, "Chunks", "split%6d.mkv") + '\u0022';     // Video Output

                Helpers.Logging("Equal Chunking: " + ffmpeg_command);

                // Start Splitting
                Process          chunking_process = new Process();
                ProcessStartInfo startInfo        = new ProcessStartInfo
                {
                    WindowStyle      = ProcessWindowStyle.Hidden,
                    FileName         = "cmd.exe",
                    WorkingDirectory = Global.FFmpeg_Path,
                    Arguments        = ffmpeg_command
                };
                chunking_process.StartInfo = startInfo;

                // Start Process
                chunking_process.Start();

                // Get launched Process ID
                int temp_pid = chunking_process.Id;

                // Add Process ID to Array, inorder to keep track / kill the instances
                Global.Launched_PIDs.Add(temp_pid);

                // Wait for Exit
                chunking_process.WaitForExit();

                // Get Exit Code
                int exit_code = chunking_process.ExitCode;

                // Remove PID from Array after Exit
                Global.Launched_PIDs.RemoveAll(i => i == temp_pid);

                // Write Save Point
                Helpers.WriteToFileThreadSafe("", Path.Combine(Global.temp_path, Global.temp_path_folder, "splitting.log"));
            }

            // Add Chunks to Array
            Global.Video_Chunks = Directory.GetFiles(Path.Combine(Global.temp_path, Global.temp_path_folder, "Chunks"), "*mkv", SearchOption.AllDirectories).Select(x => Path.GetFileName(x)).ToArray();
        }