Пример #1
0
        public Status EncodeVideo(EncodeObject eo)
        {
            Status Result = Status.Done;

            if (!File.Exists(eo.MO.FileInfo.FullName))
            {
                if (Completed != null)
                {
                    CompletedEventArgs e = new CompletedEventArgs();
                    e.Result  = Status.ErrorFileNotFound;
                    eo.Status = Status.ErrorFileNotFound;
                    e.EO      = eo;
                    Completed(this, e);
                }
            }

            string filename = Path.GetFileNameWithoutExtension(eo.MO.FileInfo.FullName);
            string ext      = eo.MO.FileInfo.Extension;

            // -i 101S102_CT01V01.mp4 -c:v libx265 -vf scale=-1:720 -preset medium -crf 23 -acodec copy 101S102_CT01V01-x265.mp4
            // nvenc_hevc  hevc_qsv

            // \"'-1':'if(gt(a,720),720,-1)'\"
            if (eo.outdir == string.Empty)
            {
                eo.outdir = eo.MO.FileInfo.DirectoryName;
            }
            string outfilename = Path.Combine(eo.outdir, filename) + eo.suffix + ".mp4";

            if (File.Exists(outfilename))
            {
                if (Completed != null)
                {
                    CompletedEventArgs e = new CompletedEventArgs();
                    e.Result  = Status.ErrorFileAlreadyExists;
                    eo.Status = Status.ErrorFileAlreadyExists;
                    e.EO      = eo;
                    Completed(this, e);
                }
                return(Status.ErrorFileAlreadyExists);
            }

            int exitcode = -1;

            try
            {
                if (eo.QType == EncodeObject.QualityEnum.CRF)
                {
                    StringBuilder arguments = new StringBuilder();
                    arguments.Append(" -i \"").Append(eo.MO.FileInfo.FullName).Append("\"");
                    arguments.Append(" -c:v ").Append(eo.codec);
                    if (eo.scale > 0)
                    {
                        arguments.Append(" -vf scale=\"'-1':'if(gt(ih," + eo.scale.ToString() + ")," + eo.scale.ToString() + ",-1)':flags=lanczos\"");
                    }
                    arguments.Append(" -preset medium");
                    arguments.Append(" -crf ").Append(eo.Q);
                    if (eo.MO.Audio.StartsWith("aac"))
                    {
                        arguments.Append(" -acodec copy ");
                    }
                    arguments.Append(" \"").Append(outfilename).Append("\"");

                    exitcode = executeFFmpeg(arguments.ToString(), eo);
                }
                else if (eo.QType == EncodeObject.QualityEnum.AvgBitrate)
                {
                    StringBuilder arguments = new StringBuilder();

                    if (eo.codec == "libx264" || eo.codec == "libx265")
                    {
                        // first pass
                        arguments.Append(" -y -i \"").Append(eo.MO.FileInfo.FullName).Append("\"");
                        arguments.Append(" -c:v ").Append(eo.codec);
                        if (eo.scale > 0)
                        {
                            arguments.Append(" -vf scale=\"'-1':'if(gt(ih," + eo.scale.ToString() + ")," + eo.scale.ToString() + ",-1)':flags=lanczos\"");
                        }
                        arguments.Append(" -preset medium");
                        arguments.Append(" -b:v ").Append(eo.Q).Append("k");
                        arguments.Append(" -an");
                        if (eo.codec == "libx265")
                        {
                            arguments.Append(" -x265-params no-slow-firstpass=1:pass=1");
                        }
                        else if (eo.codec == "libx264")
                        {
                            arguments.Append(" -pass 1 -fastfirstpass 1 ");
                        }
                        arguments.Append(" -f mp4");
                        arguments.Append(" NUL");
                        exitcode = executeFFmpeg(arguments.ToString(), eo);
                    }
                    else
                    {
                        exitcode = 0;
                    }
                    if (exitcode == 0)
                    {
                        arguments.Clear();
                        arguments.Append(" -i \"").Append(eo.MO.FileInfo.FullName).Append("\"");
                        arguments.Append(" -c:v ").Append(eo.codec);
                        if (eo.scale > 0)
                        {
                            arguments.Append(" -vf scale=\"'-1':'if(gt(ih," + eo.scale.ToString() + ")," + eo.scale.ToString() + ",-1)':flags=lanczos\"");
                        }
                        arguments.Append(" -preset medium");
                        arguments.Append(" -b:v ").Append(eo.Q).Append("k");
                        if (eo.codec == "libx265")
                        {
                            arguments.Append(" -x265-params pass=2");
                        }
                        else
                        {
                            arguments.Append(" -pass 2");
                        }
                        if (eo.MO.Audio.StartsWith("aac"))
                        {
                            arguments.Append(" -acodec copy ");
                        }
                        arguments.Append(" \"").Append(outfilename).Append("\"");

                        exitcode = executeFFmpeg(arguments.ToString(), eo);
                    }
                }
            } catch (Exception e)
            {
                eo.Status = Status.ErrorUnknown;
            }

            if (eo.Status != Status.New)
            {
                // Set by event handler
                Result = eo.Status;
            }
            else if (exitcode == 0 && Result == Status.Done)
            {
                eo.NewSize = (new FileInfo(outfilename)).Length;
            }
            else if (exitcode != 0 && Result != Status.Done)
            {
                Result = Status.ErrorUnknown;
            }

            if (Completed != null)
            {
                CompletedEventArgs e = new CompletedEventArgs();
                e.Result  = Result;
                eo.Status = Result;
                e.EO      = eo;
                Completed(this, e);
            }

            return(Result);
        }
Пример #2
0
        private int executeFFmpeg(string args, EncodeObject eo)
        {
            ffmpeg_process = new Process
            {
                StartInfo =
                {
                    FileName               = ffmpeg_exe,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    UseShellExecute        = false,
                    Arguments      = args,
                    CreateNoWindow = true
                },
            };

            ffmpeg_process.Start();
            ffmpeg_process.PriorityClass = ProcessPriorityClass.BelowNormal;

            try
            {
                Regex progressRegex = new Regex(@"(?<KEY>[a-z]+)=\s*(?<VALUE>[^ ]+)\s*", RegexOptions.Compiled);
                Regex digRegex      = new Regex(@"\d+");
                Regex fltRegex      = new Regex(@"\d+(\.\d+)?");
                while (true)
                {
                    var line = ffmpeg_process.StandardError.ReadLine();
                    if (line == null || line == string.Empty)
                    {
                        break;
                    }

                    MatchCollection mc = progressRegex.Matches(line);
                    if (mc.Count == 0)
                    {
                        continue;
                    }

                    string[] groups = new string[] { "frame", "fps", "size", "time", "bitrate", "speed" };

                    Dictionary <string, string> info = new Dictionary <string, string>();
                    foreach (Match m in mc)
                    {
                        info[m.Groups["KEY"].Value] = m.Groups["VALUE"].Value;
                    }

                    Debug.WriteLine(line);
                    ProgressInfo pi = new ProgressInfo();
                    string       v;

                    info.TryGetValue("frame", out pi.frame);
                    if (info.TryGetValue("fps", out v))
                    {
                        Match m = fltRegex.Match(v);
                        if (m.Success)
                        {
                            float.TryParse(m.Groups[0].Value, out pi.fps);
                        }
                    }

                    if (info.TryGetValue("size", out v))
                    {
                        Match m = digRegex.Match(v);
                        if (m.Success)
                        {
                            int.TryParse(m.Groups[0].Value, out pi.size);
                        }
                    }
                    if (info.TryGetValue("time", out v))
                    {
                        TimeSpan.TryParse(v, out pi.time);
                    }
                    if (info.TryGetValue("bitrate", out v))
                    {
                        Match m = fltRegex.Match(v);
                        if (m.Success)
                        {
                            float.TryParse(m.Groups[0].Value, out pi.bitrate);
                            eo.NewBitrate = (int)pi.bitrate;
                        }
                    }
                    if (info.TryGetValue("speed", out v))
                    {
                        Match m = fltRegex.Match(v);
                        if (m.Success)
                        {
                            float.TryParse(m.Groups[0].Value, out pi.speed);
                        }
                    }

                    if (ProgressUpdate != null)
                    {
                        ProgressInfoEventArgs e = new ProgressInfoEventArgs();
                        e.Info = pi;
                        e.EO   = eo;
                        ProgressUpdate(this, e);
                    }
                }
            }
            finally { }

            if (!ffmpeg_process.WaitForExit(500))
            {
                ffmpeg_process.Kill();
                ffmpeg_process.WaitForExit();
            }
            int exitcode = ffmpeg_process.ExitCode;

            ffmpeg_process.Dispose();
            return(exitcode);
        }