/// <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)); }); }
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); }
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); }
/// <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); }
/// <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); } }
/// <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}")); }
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); }
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); }
/// <inheritdoc /> public IConversion SetCodec(VideoCodec codec) { return(SetCodec(codec.ToString())); }
/// <inheritdoc /> public IConversion SetVideo(VideoCodec codec, int bitrate = 0) { return(SetVideo(codec.ToString(), bitrate)); }
internal static string ForceFormat(VideoCodec codec) { return($"-f {codec.ToString().ToLower()} "); }
/// <inheritdoc /> public IConversion UseHardwareAcceleration(HardwareAccelerator hardwareAccelerator, VideoCodec decoder, VideoCodec encoder, int device = 0) { return(UseHardwareAcceleration($"{hardwareAccelerator}", decoder.ToString(), encoder.ToString(), device)); }
internal static string IntelVideo(VideoCodec codec) { var video = $"-vcodec {codec.ToString().ToLower()} "; return(video); }
internal static string NVVideo(VideoCodec codec) { var video = $"-c:v {codec.ToString().ToLower()} "; return(video); }
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); } } }