Example #1
0
        internal static void Extract(MediaQueue queue, string tempDir)
        {
            frmMain.PrintStatus("Extracting...");

            frmMain.PrintLog("[INFO] Extracting subtitle file...");

            for (int i = 0; i < queue.Subtitle.Count; i++)
            {
                var id   = queue.Subtitle[i].Id;
                var fmt  = queue.Subtitle[i].Codec;
                var file = queue.Subtitle[i].File;
                var lang = queue.Subtitle[i].Lang;
                var fext = Path.GetExtension(file);

                if (id < 0)
                {
                    File.Copy(file, Path.Combine(tempDir, $"subtitle{i:D4}_{lang}{fext}"));
                }
                else
                {
                    ProcessManager.Start(tempDir, $"\"{FFmpeg}\" -hide_banner -v error -stats -i \"{file}\" -map 0:{id} -map_metadata -1 -map_chapters -1 -vn -an -dn -scodec copy -y subtitle{i:D4}_{lang}.{fmt}");
                }
            }

            frmMain.PrintLog("[INFO] Extracting embeded attachment...");
            var tempDirFont = Path.Combine(tempDir, "attachment");

            for (int i = 0; i < queue.Attachment.Count; i++)
            {
                var id   = queue.Attachment[i].Id;
                var file = queue.Attachment[i].File;
                var name = queue.Attachment[i].Name;

                if (!Directory.Exists(tempDirFont))
                {
                    Directory.CreateDirectory(tempDirFont);
                }

                if (id < 0)
                {
                    File.Copy(file, Path.Combine(tempDirFont, Path.GetFileName(file)));
                }
                else
                {
                    ProcessManager.Start(tempDirFont, $"\"{FFmpeg}\" -hide_banner -v panic -stats -dump_attachment:{id} {name} -i \"{file}\" -y");
                }
            }

            // Hard Sub

            // Chapters
            ProcessManager.Start(tempDir, $"\"{FFmpeg}\" -hide_banner -v error -stats -i \"{queue.FilePath}\" -f ffmetadata metadata.ini -y");
        }
Example #2
0
        internal static void Audio(MediaQueue queue, string tempDir)
        {
            for (int i = 0; i < queue.Audio.Count; i++)
            {
                var item = queue.Audio[i];

                frmMain.PrintStatus($"Encoding Audio Id: {i}");

                frmMain.PrintLog("[INFO] Extract audio file...");
                if (item.Copy && queue.OutputFormat == MediaContainer.MKV)
                {
                    ProcessManager.Start(tempDir, $"\"{FFmpeg}\" -hide_banner -v error -i \"{item.File}\" -map 0:{item.Id} -c:a copy -y \"audio{i:D4}_{item.Lang}.mka\"");
                    continue;
                }

                frmMain.PrintLog("[INFO] Encoding audio file...");
                if (Plugins.Items.Audio.TryGetValue(item.Encoder.Id, out PluginsAudio codec))
                {
                    var ac = codec.Audio;
                    var md = item.Encoder.Mode;
                    var en = Path.Combine(codec.FilePath, ac.Encoder);

                    var trim = (queue.Trim.Enable ? $"-ss {queue.Trim.Start} -t {queue.Trim.Duration}" : string.Empty);

                    var qfix = $"{ac.Mode[md].QualityPrefix}{item.Encoder.Quality}{ac.Mode[md].QualityPostfix}";

                    var qu = (string.IsNullOrEmpty(ac.Mode[md].Args) ? string.Empty : $"{ac.Mode[md].Args} {qfix}");
                    var hz = (item.Encoder.SampleRate == 0 ? string.Empty : $"-ar {item.Encoder.SampleRate}");
                    var ch = (item.Encoder.Channel == 0 ? string.Empty : $"-ac {item.Encoder.Channel}");

                    var outfmtfile = $"audio{i:D4}_{item.Lang}.{ac.Extension}";

                    var af = string.Empty;

                    if (!item.CommandFilter.IsDisable())
                    {
                        af = $"-af {item.CommandFilter}";
                    }

                    if (ac.Args.Pipe)
                    {
                        ProcessManager.Start(tempDir, $"\"{FFmpeg}\" -hide_banner -v error -i \"{item.File}\" {trim} -map 0:{item.Id} -acodec pcm_s16le {hz} {ch} {af} -f wav {item.Command} - | \"{Path.Combine(codec.FilePath, ac.Encoder)}\" {qu} {ac.Args.Command} {ac.Args.Input} {item.Encoder.Command} {ac.Args.Output} \"{outfmtfile}\"");
                    }
                    else
                    {
                        ProcessManager.Start(tempDir, $"\"{en}\" {ac.Args.Input} \"{item.File}\" {trim} -map 0:{item.Id} {ac.Args.Command} {qu} {hz} {ch} {af} {item.Encoder.Command} {ac.Args.Output} \"{outfmtfile}\"");
                    }
                }
            }
        }
Example #3
0
        private void MediaFileListAdd(string path)
        {
            var fileData  = new FFmpeg.MediaInfo(path);
            var fileQueue = new MediaQueue()
            {
                Enable       = true,
                FilePath     = path,
                FileSize     = fileData.FileSize,
                Duration     = fileData.Duration,
                InputFormat  = fileData.FormatNameFull,
                OutputFormat = MediaContainer.MKV,
                Info         = fileData
            };

            foreach (var item in fileData.Video)
            {
                fileQueue.Video.Add(MediaQueueParse.Video(path, item));
            }

            foreach (var item in fileData.Audio)
            {
                fileQueue.Audio.Add(MediaQueueParse.Audio(path, item));
            }

            foreach (var item in fileData.Subtitle)
            {
                fileQueue.Subtitle.Add(MediaQueueParse.Subtitle(path, item));
            }

            foreach (var item in fileData.Attachment)
            {
                fileQueue.Attachment.Add(MediaQueueParse.Attachment(path, item));
            }

            lstFile.Items.Add(new ListViewItem(new[]
            {
                Path.GetFileName(path),
                Path.GetExtension(path).Substring(1).ToUpperInvariant(),
                TimeSpan.FromSeconds(fileData.Duration).ToString("hh\\:mm\\:ss"),
                OS.PrintFileSize(fileData.FileSize),
                fileQueue.Enable ? "Ready" : "Done",
                ""
            })
            {
                Tag      = fileQueue,
                Checked  = true,
                Selected = true
            });
        }
Example #4
0
        internal static void Muxing(MediaQueue queue, string tempDir, string saveDir)
        {
            var x        = 0;
            var metadata = string.Empty;
            var metafile = string.Empty;
            var map      = "-map_metadata -1 -map_chapters -1 -dn ";

            var argVideo    = string.Empty;
            var argAudio    = string.Empty;
            var argSubtitle = string.Empty;
            var argEmbed    = string.Empty;

            var outFile = Path.Combine(saveDir, $"{Path.GetFileNameWithoutExtension(queue.FilePath)}_encoded.{queue.OutputFormat.ToString().ToLowerInvariant()}");

            frmMain.PrintStatus("Repacking...");
            frmMain.PrintLog($"[INFO] Multiplexing encoded files into single file...");

            if (File.Exists(Path.Combine(tempDir, "metadata.ini")))
            {
                metafile = "-i metadata.ini ";
            }

            foreach (var video in Directory.GetFiles(tempDir, "video*"))
            {
                argVideo += $"-i \"{Path.GetFileName(video)}\" ";
                metadata += $"-metadata:s:{x} language={video.GetLanguageCodeFromFileName()}  ";
                map      += $"-map {x} ";
                x++;
            }

            foreach (var audio in Directory.GetFiles(tempDir, "audio*"))
            {
                argAudio += $"-i \"{Path.GetFileName(audio)}\" ";
                metadata += $"-metadata:s:{x} language={audio.GetLanguageCodeFromFileName()} ";
                map      += $"-map {x} ";
                x++;
            }

            if (queue.OutputFormat == MediaContainer.MKV)
            {
                var d = 0;
                foreach (var subtitle in Directory.GetFiles(tempDir, "subtitle*"))
                {
                    argSubtitle += $"-i \"{Path.GetFileName(subtitle)}\" ";
                    metadata    += $"-metadata:s:{x} language={subtitle.GetLanguageCodeFromFileName()} {(d == 0 ? $"-disposition:s:{d} default " : "")}";
                    map         += $"-map {x} ";
                    x++;
                    d++;
                }

                var tempDirFont = Path.Combine(tempDir, "attachment");
                if (Directory.Exists(tempDirFont))
                {
                    var files = Directory.GetFiles(tempDirFont, "*");
                    for (int i = 0; i < files.Length; i++)
                    {
                        argEmbed += $"-attach \"{Path.GetFileName(files[i])}\" ";
                        metadata += $"-metadata:s:{x++} \"mimetype={queue.Attachment[i].Mime}\" ";
                    }
                }
            }

            var author  = $"{Version.Name} v{Version.Release} {Version.OSPlatform} {Version.OSArch} {Version.March} @ {Version.CodeName}";
            var command = $"\"{FFmpeg}\" -hide_banner -v error -stats {argVideo}{argAudio}{argSubtitle}{argEmbed}{metafile}{map}{metadata}-metadata \"encoded_by={author}\" -c copy -y \"{outFile}\"";

            ProcessManager.Start(tempDir, command);
        }
Example #5
0
        internal static void Video(MediaQueue queue, string tempDir)
        {
            for (int i = 0; i < queue.Video.Count; i++)
            {
                var item = queue.Video[i];

                if (Plugins.Items.Video.TryGetValue(item.Encoder.Id, out PluginsVideo codec))
                {
                    var vc         = codec.Video;
                    var en         = Path.Combine(codec.FilePath, vc.Encoder.Find(b => b.BitDepth == item.Quality.BitDepth).Binary);
                    var outrawfile = $"raw-v{i:D4}_{item.Lang}.{vc.Extension}";
                    var outfmtfile = $"video{i:D4}_{item.Lang}.{codec.Format[0]}";

                    var m = item.Encoder.Mode;

                    var trim = string.Empty;

                    var yuv = $"yuv{item.Quality.PixelFormat}p";
                    var res = string.Empty;
                    var fps = $"-r 23.976";

                    var preset     = string.Empty;
                    var tune       = string.Empty;
                    var quality    = string.Empty;
                    var bitdepth   = string.Empty;
                    var framecount = string.Empty;

                    var vf = string.Empty;
                    var fi = new List <string>();

                    // cmd builder
                    if (queue.Trim.Enable)
                    {
                        trim += $"-ss {queue.Trim.Start} -t {queue.Trim.Duration}";
                    }

                    if (item.Quality.BitDepth > 8)
                    {
                        yuv += $"{item.Quality.BitDepth}le";
                    }

                    if (item.Quality.FrameRate >= 5)
                    {
                        fps = $"-r {item.Quality.FrameRate}";
                    }

                    if (!vc.Args.Preset.IsDisable() && !item.Encoder.Preset.IsDisable())
                    {
                        preset = $"{vc.Args.Preset} {item.Encoder.Preset}";
                    }

                    if (!vc.Args.Tune.IsDisable() && !item.Encoder.Tune.IsDisable())
                    {
                        tune = $"{vc.Args.Tune} {item.Encoder.Tune}";
                    }

                    if (!vc.Mode[m].Args.IsDisable())
                    {
                        quality = $"{vc.Mode[m].Args} {vc.Mode[m].Prefix}{item.Encoder.Value}{vc.Mode[m].Postfix}";
                    }

                    if (!vc.Args.BitDepth.IsDisable() && item.Quality.BitDepth >= 8)
                    {
                        bitdepth = $"{vc.Args.BitDepth} {item.Quality.BitDepth}";
                    }

                    if (!vc.Args.FrameCount.IsDisable())
                    {
                        if (item.Quality.FrameCount > 0)
                        {
                            framecount = $"{vc.Args.FrameCount} {item.Quality.FrameCount}";
                        }
                    }

                    // FFmpeg Video Filter
                    if (item.Quality.Width >= 128 && item.Quality.Height >= 128)
                    {
                        res = $"scale={item.Quality.Width}:{item.Quality.Height}";

                        if (item.Quality.OriginalWidth > item.Quality.Width)
                        {
                            res += ":flags=lanczos";
                        }
                    }
                    else
                    {
                        res = $"scale={item.Quality.OriginalWidth}:{item.Quality.OriginalHeight}";
                    }

                    if (item.DeInterlace.Enable)
                    {
                        fi.Add($"yadif={item.DeInterlace.Mode}:{item.DeInterlace.Field}:0");
                    }

                    if (!item.Quality.CommandFilter.IsDisable())
                    {
                        fi.Add(item.Quality.CommandFilter);
                    }

                    if (queue.HardSub)
                    {
                        var files = Directory.GetFiles(tempDir, "subtitle*");

                        if (files.Length > 0)
                        {
                            var file = Path.GetFileName(files[0]);
                            var ext  = Path.GetExtension(file).ToLowerInvariant();

                            if (ext.IsOneOf(".srt"))
                            {
                                fi.Add($"subtitles={file}");
                            }
                            else if (ext.IsOneOf(".ass", ".ssa"))
                            {
                                fi.Add($"ass={file}");
                            }
                        }
                    }

                    // Resolution filter
                    fi.Add(res);

                    // Concat multiple filter
                    if (fi.Count > 0)
                    {
                        vf = $"-vf \"{string.Join(",", fi)}\"";
                    }



                    // begin encoding
                    frmMain.PrintStatus($"Encoding Video Id: {i}");
                    frmMain.PrintLog($"[INFO] Encoding video file...");

                    // Tell You
                    frmMain.PrintLog($"[INFO] Video filter command is: {vf}");

                    if (vc.Mode[item.Encoder.Mode].MultiPass)
                    {
                        var p    = 1;
                        var pass = string.Empty;

                        frmMain.PrintLog("[WARN] Frame count is disable for Multi-pass encoding, Avoid inconsistent across multi-pass.");

                        do
                        {
                            pass = vc.Args.PassNth;

                            if (p == 1)
                            {
                                pass = vc.Args.PassFirst;
                            }

                            if (p == item.Encoder.MultiPass)
                            {
                                pass = vc.Args.PassLast;
                            }

                            frmMain.PrintLog($"[INFO] Multi-pass encoding: {p} of {item.Encoder.MultiPass}");

                            if (vc.Args.Pipe)
                            {
                                ProcessManager.Start(tempDir, $"\"{FFmpeg}\" -hide_banner -v error -i \"{item.File}\" -strict -1 {trim} -map 0:{item.Id} -f yuv4mpegpipe -pix_fmt {yuv} {fps} {vf} {item.Quality.Command} - | \"{en}\" {vc.Args.Input} {vc.Args.Y4M} {preset} {quality} {tune} {bitdepth} {pass} {item.Encoder.Command} {vc.Args.Output} {outrawfile}");
                            }
                            else
                            {
                                ProcessManager.Start(tempDir, $"\"{en}\" {vc.Args.Input} \"{item.File}\" {trim} -map 0:{item.Id} -pix_fmt {yuv} {fps} {vf} {vc.Args.UnPipe} {preset} {quality} {tune} {pass} {item.Encoder.Command} {vc.Args.Command} {vc.Args.Output} {outrawfile}");
                            }

                            ++p;
                        } while (p <= item.Encoder.MultiPass);
                    }
                    else
                    {
                        if (vc.Args.Pipe)
                        {
                            ProcessManager.Start(tempDir, $"\"{FFmpeg}\" -hide_banner -v error -i \"{item.File}\" -strict -1 {trim} -map 0:{item.Id} -f yuv4mpegpipe -pix_fmt {yuv} {fps} {vf} {item.Quality.Command} - | \"{en}\" {vc.Args.Input} {vc.Args.Y4M} {preset} {quality} {tune} {bitdepth} {framecount} {item.Encoder.Command} {vc.Args.Output} {outrawfile}");
                        }
                        else
                        {
                            ProcessManager.Start(tempDir, $"\"{en}\" {vc.Args.Input} \"{item.File}\" {trim} -map 0:{item.Id} -pix_fmt {yuv} {fps} {vf} {vc.Args.UnPipe} {preset} {quality} {tune} {item.Encoder.Command} {vc.Args.Output} {outrawfile}");
                        }
                    }

                    // Raw file dont have pts (time), need to remux
                    frmMain.PrintStatus($"Restructure...");
                    frmMain.PrintLog($"[INFO] Restructure RAW video file...");

                    if (vc.RawOutput)
                    {
                        if (File.Exists(Path.Combine(tempDir, outrawfile)))
                        {
                            ProcessManager.Start(tempDir, $"\"{MP4Box}\" -add \"{outrawfile}\" -set-meta 0 -new \"{outfmtfile}\" ");
                            File.Delete(Path.Combine(tempDir, outrawfile));
                        }
                    }
                    else
                    {
                        if (File.Exists(Path.Combine(tempDir, outrawfile)))
                        {
                            File.Move(Path.Combine(tempDir, outrawfile), Path.Combine(tempDir, outfmtfile));
                        }
                    }
                }
            }
        }