Esempio n. 1
0
        /// <summary>
        /// This method will run in the background. Please subscribe to <see cref="OnConversionDidStart" />,
        /// <see cref="OnConversionDidFail" />, and <see cref="OnConversionDidFinish" /> events to get status updates and final
        /// processed data
        /// </summary>
        public void BuildAndRun()
        {
            Stopwatch watch = new Stopwatch();

            Task.Run(() =>
            {
                var processInfo  = new ProcessStartInfo(Path.Combine(FFMpegLocation, FFMpegFilenames.FFMpeg));
                string builtArgs = "-i ";
                if (InputFile == null)
                {
                    throw new Exception("InputFile cannot be null");
                }
                if (OutputFile == null)
                {
                    throw new Exception("Output file cannot be null for BuildAndRun");
                }
                builtArgs += InputFile.FullName;
                if (OverwriteOutputFile)
                {
                    builtArgs += " -y";
                }
                builtArgs += $" -c:v {OutputVideoCodec.ToString()}";
                builtArgs += $" -c:a {OutputAudioCodec.ToString()}";
                if (OutputBitrate.HasValue)
                {
                    builtArgs += $" -b:v {OutputBitrate.Value.ToNormalizedString()}";
                }
                if (OutputFrameRate != FrameRate.DEFAULT)
                {
                    builtArgs += $" -r {(int)OutputFrameRate}";
                }
                builtArgs += $" -cpu-used {NumCpuUsed.GetCpuParam()}";
                if (OutputResolution.HasValue)
                {
                    builtArgs += $" -s {OutputResolution.Value.ToNormalizedString()}";
                }
                builtArgs                         += $" {OutputFile.FullName}";
                processInfo.Arguments              = builtArgs;
                processInfo.RedirectStandardError  = true;
                processInfo.RedirectStandardInput  = true;
                processInfo.RedirectStandardOutput = true;
                var process                        = new Process();
                process.StartInfo                  = processInfo;
                watch.Start();
                process.Start();
                System.Console.WriteLine("Process started -- firing event");
                OnConversionDidStart?.Invoke(this, new ConversionEventArgs(InputFile, OutputFile));

                process.ErrorDataReceived += (object sender, DataReceivedEventArgs args) =>
                {
                    OnConversionDidFail?.Invoke(this, new ConversionEventArgs(InputFile, OutputFile));
                };

                process.WaitForExit();
                watch.Stop();
            }).ContinueWith((res) =>
            {
                OnConversionDidFinish?.Invoke(this, new ConversionEventArgs(InputFile, OutputFile, watch.Elapsed));
            });
        }
Esempio n. 2
0
 private bool HasH264Stream()
 {
     foreach (IStream stream in _streams)
     {
         if (stream is IVideoStream)
         {
             IVideoStream s     = (IVideoStream)stream;
             VideoCodec   codec = ((VideoStream)s).Codec;
             if (codec.ToString() == VideoCodec.Libx264.ToString() ||
                 codec.ToString() == VideoCodec.H264.ToString())
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Esempio n. 3
0
        internal static string Video(VideoCodec codec, int bitrate = 0)
        {
            var video = $"-codec:v {codec.ToString().ToLower()} ";

            if (bitrate > 0)
            {
                video += $"-b:v {bitrate}k ";
            }

            return(video);
        }
Esempio n. 4
0
        /// <inheritdoc />
        public IConversion UseHardwareAcceleration(HardwareAccelerator hardwareAccelerator, VideoCodec decoder, VideoCodec encoder, int device = 0)
        {
            _hardwareAcceleration = $"-hwaccel {hardwareAccelerator.ToString()} -c:v {decoder} ";
            AddParameter($"-c:v {encoder?.ToString()} ");

            if (device != 0)
            {
                _hardwareAcceleration += $"-hwaccel_device {device} ";
            }
            UseMultiThread(false);
            return(this);
        }
Esempio n. 5
0
 /// <inheritdoc />
 public IConversion UseHardwareAcceleration(HardwareAccelerator hardwareAccelerator, VideoCodec decoder, VideoCodec encoder, int device = 0)
 {
     if (hardwareAccelerator != HardwareAccelerator.software)
     {
         return(UseHardwareAcceleration($"{hardwareAccelerator}", decoder.ToString(), encoder.ToString(), device));
     }
     else
     {
         this.UseMultiThread(true);
         return(this);
     }
 }
Esempio n. 6
0
        /// <inheritdoc />
        public IVideoStream SetCodec(VideoCodec codec)
        {
            string input = codec.ToString();

            if (codec == VideoCodec._8bps)
            {
                input = "8bps";
            }
            else if (codec == VideoCodec._4xm)
            {
                input = "4xm";
            }
            else if (codec == VideoCodec._012v)
            {
                input = "012v";
            }
            return(SetCodec($"{input}"));
        }
Esempio n. 7
0
        public async Task BasicTranscode_InputFileWithSubtitles_SkipSubtitlesWithParameter(VideoCodec videoCodec, AudioCodec audioCodec, SubtitleCodec subtitleCodec)
        {
            string output = _storageFixture.GetTempFileName(FileExtensions.Mp4);

            IConversionResult result = await(await FFmpeg.Conversions.FromSnippet.Transcode(Resources.MkvWithSubtitles, output, videoCodec, audioCodec, subtitleCodec, false)).Start();


            IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(output);

            Assert.Equal(9, mediaInfo.Duration.Seconds);
            Assert.Single(mediaInfo.VideoStreams);
            Assert.Single(mediaInfo.AudioStreams);
            Assert.Empty(mediaInfo.SubtitleStreams);
            IAudioStream audioStream = mediaInfo.AudioStreams.First();
            IVideoStream videoStream = mediaInfo.VideoStreams.First();

            Assert.NotNull(videoStream);
            Assert.NotNull(audioStream);
            Assert.Equal(videoCodec.ToString(), videoStream.Codec);
            Assert.Equal(audioCodec.ToString(), audioStream.Codec);
            Assert.Equal(25, videoStream.Framerate);
        }
Esempio n. 8
0
        public async Task BasicTranscode_InputFileWithSubtitles_SkipSubtitles(VideoCodec videoCodec, AudioCodec audioCodec, SubtitleCodec subtitleCodec)
        {
            string output = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + FileExtensions.Mp4);

            IConversionResult result = await(await FFmpeg.Conversions.FromSnippet.Transcode(Resources.MkvWithSubtitles, output, videoCodec, audioCodec, subtitleCodec)).Start();


            IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(output);

            Assert.Equal(TimeSpan.FromSeconds(9), mediaInfo.Duration);
            Assert.Single(mediaInfo.VideoStreams);
            Assert.Single(mediaInfo.AudioStreams);
            Assert.Empty(mediaInfo.SubtitleStreams);
            IAudioStream audioStream = mediaInfo.AudioStreams.First();
            IVideoStream videoStream = mediaInfo.VideoStreams.First();

            Assert.NotNull(videoStream);
            Assert.NotNull(audioStream);
            Assert.Equal(videoCodec.ToString(), videoStream.Codec);
            Assert.Equal(audioCodec.ToString(), audioStream.Codec);
            Assert.Equal(25, videoStream.Framerate);
        }
Esempio n. 9
0
 /// <inheritdoc />
 public IConversion SetCodec(VideoCodec codec)
 {
     return(SetCodec(codec.ToString()));
 }
Esempio n. 10
0
 /// <inheritdoc />
 public IConversion SetVideo(VideoCodec codec, int bitrate = 0)
 {
     return(SetVideo(codec.ToString(), bitrate));
 }
Esempio n. 11
0
 internal static string ForceFormat(VideoCodec codec)
 {
     return($"-f {codec.ToString().ToLower()} ");
 }
Esempio n. 12
0
 /// <inheritdoc />
 public IConversion UseHardwareAcceleration(HardwareAccelerator hardwareAccelerator, VideoCodec decoder, VideoCodec encoder, int device = 0)
 {
     return(UseHardwareAcceleration($"{hardwareAccelerator}", decoder.ToString(), encoder.ToString(), device));
 }
Esempio n. 13
0
        internal static string IntelVideo(VideoCodec codec)
        {
            var video = $"-vcodec {codec.ToString().ToLower()} ";

            return(video);
        }
Esempio n. 14
0
        internal static string NVVideo(VideoCodec codec)
        {
            var video = $"-c:v {codec.ToString().ToLower()} ";

            return(video);
        }
Esempio n. 15
0
        public override void DoWindowContents(Rect area)
        {
            float y = 0f;

            Text.Anchor = TextAnchor.UpperCenter;
            Text.Font   = GameFont.Medium;
            Widgets.Label(new Rect(0, y, area.width, 40f), new GUIContent(" " + "ModDisplayName".Translate(), MenuOption.Icon));
            y        += 36f;
            Text.Font = GameFont.Small;
            Widgets.Label(new Rect(0, y, area.width, 30f), "by Epicguru (James B)");
            y        += 40f;
            Text.Font = GameFont.Medium;

            if (!RimworldRendererMod.Is64)
            {
                Text.Anchor = TextAnchor.UpperLeft;
                Label($"<color=red>{"UI_Error64Bit".Translate()}\n[Debug info]\nOperating system: {SystemInfo.operatingSystem}\nIntPtr size: {IntPtr.Size}</color>");
                // Close button...
                GUI.color = Color.white;
                Rect rect4 = new Rect(area.width - 120, area.height - 35f, 120, 35f);
                if (Widgets.ButtonText(rect4, "UI_Close".Translate(), true, false, true))
                {
                    Close();
                }
                return;
            }

            if (inHelp)
            {
                DrawHelpMenu(area, ref y);

                GUI.color = Color.white;
                Rect rect4 = new Rect(area.width - 120, area.height - 35f, 120, 35f);
                if (Widgets.ButtonText(rect4, "UI_Back".Translate(), true, false, true))
                {
                    inHelp = false;
                }
                Text.Anchor = TextAnchor.UpperLeft;

                return;
            }

            if (!confirmClose && !Runner.IsRendering && Widgets.ButtonText(new Rect(0f, y, 250f, 40f), "UI_Start".Translate()))
            {
                Runner.StartRender();
            }
            GUI.color = Color.green;
            if (!confirmClose && Widgets.ButtonText(new Rect(area.width - 100f, y + 2.5f, 100f, 35f), "UI_Help".Translate()))
            {
                inHelp = true;
            }
            GUI.color = Color.white;
            y        += 50f;

            Text.Anchor = TextAnchor.MiddleLeft;
            Label($"Status: {(Status.Length > 120 ? Status.Substring(0, 120) + "..." : Status)}");

            if (confirmClose)
            {
                if (!Status.StartsWith("Error"))
                {
                    Label($"<color=green>{"UI_SaveConfirmation".Translate(Runner.SavePath)}</color>");
                }
                if (Widgets.ButtonText(new Rect(0, y, 200, 30), "UI_Confirm".Translate()))
                {
                    confirmClose = false;
                }

                Text.Anchor = TextAnchor.UpperLeft;
                return;
            }

            Widgets.FillableBarLabeled(new Rect(0, y, area.width, 30f), ProgressBarPercentage, 50, $"{ProgressBarPercentage * 100f:F0}%");
            y += 40f;

            if (Runner.IsRendering)
            {
                Label($"ETA: {ETA}");
                Label($"<color=green>{"UI_SafeContinueMessage".Translate()}</color>");
            }
            else
            {
                y += inputsPreSapce;
                Widgets.BeginScrollView(new Rect(0, y, area.width, area.height - y - 40), ref scrollPos, new Rect(0, y, 100, LastHeight));
                y += inputsPreSapce * 0.5f;

                string s = $"{"UI_ImagesFolder".Translate()}:";
                float  w = Text.CalcSize(s).x;
                Widgets.Label(new Rect(0, y, w, 30), s);
                bool          dirExists         = Directory.Exists(SourceFolder);
                bool          dirContainsImages = false;
                List <string> suggestions       = null;
                if (dirExists)
                {
                    dirContainsImages = ContainsImages(SourceFolder);

                    if (!dirContainsImages)
                    {
                        try
                        {
                            suggestions = new List <string>();
                            foreach (var dir in Directory.GetDirectories(SourceFolder))
                            {
                                if (ContainsImages(dir))
                                {
                                    suggestions.Add(new DirectoryInfo(dir).Name);
                                }
                            }
                        }
                        catch
                        {
                            // ignored
                        }
                    }
                }
                string dirString = dirExists ? (dirContainsImages ? $"<color=green>{"UI_Good".Translate()}</color>" : $"<color=yellow>{"UI_NoImgInFolder".Translate()}</color>") : $"<color=red>{"UI_FolderNotFound".Translate()}</color>";
                float  width     = Text.CalcSize(dirString).x + 5;
                SourceFolder = Widgets.TextField(new Rect(w + 5, y, area.width - width - 30 - w, textInputHeights), SourceFolder);

                // Folder path status.
                Text.Font = GameFont.Medium;
                Widgets.Label(new Rect(area.width - width - 20, y, width + 30, textInputHeights), dirString);
                Text.Font = GameFont.Medium;
                y        += textInputHeights + 15;

                // Suggestions for folders.
                if (dirExists && !dirContainsImages && suggestions != null && suggestions.Count > 0)
                {
                    Widgets.Label(new Rect(0, y, width + 30, 32), $"<color=yellow>{"UI_PerhapsYouMeant".Translate()}:</color>");
                    y += 32 + 5;
                    foreach (var dir in suggestions)
                    {
                        if (Widgets.ButtonText(new Rect(0, y, width + 30, 32), $"...{dir}"))
                        {
                            SourceFolder = Path.Combine(SourceFolder, dir);
                        }
                        y += 35;
                    }
                }

                s = $"{"UI_Resolution".Translate()}:";
                w = Text.CalcSize(s).x;
                Widgets.Label(new Rect(0, y, w, 30), s);
                Widgets.TextFieldNumeric(new Rect(w + 5, y, resolutionInputWidths, 30), ref ResX, ref ResXS, 1, 9999);
                Widgets.Label(new Rect(w + resolutionInputWidths + 10, y, 20, 32), "x");
                Widgets.TextFieldNumeric(new Rect(w + resolutionInputWidths + 25, y, resolutionInputWidths, 30), ref ResY, ref ResYS, 1, 9999);
                Widgets.Label(new Rect(w + resolutionInputWidths * 2 + 30, y, 120, 32), $"{"UI_Pixels".Translate()}:");
                y += 40;

                s = $"{"UI_Bitrate".Translate()}:";
                w = Text.CalcSize(s).x;
                Widgets.Label(new Rect(0, y, w, 30), s);
                bitsPerSecondRaw = Widgets.HorizontalSlider(new Rect(w + 5, y + 12, area.width - 120 - w, 30), bitsPerSecondRaw, 1000, 1000 * 1000 * 40);
                Widgets.Label(new Rect(area.width - 110, y, 120, 30), PrettyBitrate(bitsPerSecondRaw).ToString());
                y += 40;

                s = $"{"UI_ImagesPerSecond".Translate()}:";
                w = Text.CalcSize(s).x;
                Widgets.Label(new Rect(0, y, w, 30), s);
                Widgets.IntEntry(new Rect(w, y, 200, 30), ref ImagesPerSecond, ref IPSS);
                if (ImagesPerSecond < 1)
                {
                    IPSS            = "1";
                    ImagesPerSecond = 1;
                }
                if (ImagesPerSecond > 120)
                {
                    ImagesPerSecond = 120;
                    IPSS            = "120";
                }
                y += 40f;

                s = $"{"UI_Sampling".Translate()}:";
                w = Text.CalcSize(s).x;
                Widgets.Label(new Rect(0, y, w, 30), s);
                Widgets.Dropdown(new Rect(w, y, 250, 30), InterpolationMode.HighQualityBicubic, (enumThing) => { return(enumThing.ToString()); }, (thing) => this.DropdownGenerator(thing), CurrentInterpolationMode.ToString());
                y += 40f;

                s = $"{"UI_VideoCodec".Translate()}:";
                w = Text.CalcSize(s).x;
                Widgets.Label(new Rect(0, y, w, 30), new GUIContent(s, "The codec to use in the ouput video. Only change if you know what you are doing."));
                Widgets.Dropdown(new Rect(w, y, 250, 30), VideoCodec.Default, (enumThing) => { return(enumThing.ToString()); }, (thing) => this.DropdownGenerator2(thing), CurrentCodec.ToString());
                y += 40f;

                Widgets.EndScrollView();
            }

            // Close button...
            GUI.color = Color.white;
            Rect rect3 = new Rect(area.width - 120, area.height - 35f, 120, 35f);

            if (Widgets.ButtonText(rect3, "UI_Close".Translate(), true, false, true))
            {
                Close();
            }
            Text.Anchor = TextAnchor.UpperLeft;

            LastHeight = (int)y + 10;

            void Label(string s)
            {
                float h = Text.CalcHeight(s, area.width);

                Widgets.Label(new Rect(0, y, area.width, h), s);
                y += h + 5f;
            }

            bool ContainsImages(string dir)
            {
                try
                {
                    foreach (var path in Directory.GetFiles(dir))
                    {
                        var info = new FileInfo(path);
                        if (info.Extension.ToLower() == ".png" || info.Extension.ToLower() == ".jpg")
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
                catch
                {
                    return(false);
                }
            }
        }