/// <summary> /// Returns the code for the MatrixIn argument based on SourceColorMatrix. /// </summary> private static string GetMatrixIn(MediaEncoderSettings settings) { string Result = null; if (settings.SourceColorMatrix == ColorMatrix.Rec601) { Result = "Rec601"; } else if (settings.SourceColorMatrix == ColorMatrix.Pc601) { Result = "Pc601"; } else if (settings.SourceColorMatrix == ColorMatrix.Pc709) { Result = "Pc709"; } if (Result != null) { return(string.Format(@", MatrixIn=""{0}""", Result)); } else { return(""); } }
private EncodingCompletedEventArgs FinalizeEncoding(MediaEncoderSettings settings, DateTime? startTime) { settings.ResumePos = -1; string VideoFile = settings.VideoAction == VideoAction.Discard ? null : settings.VideoAction == VideoAction.Copy ? settings.FilePath : settings.OutputFile; if (!File.Exists(settings.OutputFile) && settings.VideoAction != VideoAction.Copy) { // Merge segments. settings.CompletionStatus = MergeSegments(settings, VideoFile); if (settings.CompletionStatus != CompletionStatus.Success) return null; } if (!File.Exists(settings.FinalFile)) { // Muxe video with audio. string AudioFile = settings.AudioAction == AudioActions.Discard ? null : settings.AudioAction == AudioActions.Copy ? settings.FilePath : settings.AudioFile; if (AudioFile == null) File.Move(VideoFile, settings.FinalFile); else if (VideoFile == null) File.Move(AudioFile, settings.FinalFile); else settings.CompletionStatus = MediaMuxer.Muxe(VideoFile, AudioFile, settings.FinalFile, new ProcessStartOptions(settings.JobIndex, "Muxing Audio and Video", false)); if (settings.CompletionStatus != CompletionStatus.Success) return null; } return GetEncodingResults(settings, settings.FinalFile, startTime); }
private static void ApplyDegrain(AviSynthScriptBuilder Script, MediaEncoderSettings settings, ref bool isLsb, ref bool isYV24) { Script.LoadPluginAvsi("smdegrain.avsi"); Script.LoadPluginDll("MVTools2.dll"); Script.LoadPluginDll("MedianBlur2.dll"); if (settings.DegrainSharp) { Script.LoadPluginDll("rgtools.dll"); } else { Script.LoadPluginDll("RemoveGrain.dll"); } if (isYV24) { if (isLsb) { Script.AppendLine(@"Dither_resize16nr(Width, Height/2, kernel=""Spline36"", csp=""YV12"")"); } else { Script.AppendLine("ConvertToYV12()"); } isYV24 = false; } Script.AppendLine("SMDegrain(thsad={0}, prefilter={1}{2}{3})", settings.DegrainStrength * 10, settings.DegrainPrefilter == DegrainPrefilters.SD ? 1 : settings.DegrainPrefilter == DegrainPrefilters.HD ? 2 : 4, settings.DegrainSharp ? ", contrasharp=true" : "", isLsb ? ", lsb_in=true, lsb_out=true" : ""); }
public static float?GetPixelAspectRatio(MediaEncoderSettings settings) { string ConsoleOut = RunToString("Encoder\\ffmpeg.exe", string.Format(@"-i ""{0}""", settings.FilePath)); int PosStart = ConsoleOut.IndexOf("[SAR ") + 5; int PosEnd = ConsoleOut.IndexOf(" DAR ", PosStart); if (PosStart < 0 || PosEnd < 0) { return(null); } string SARText = ConsoleOut.Substring(PosStart, PosEnd - PosStart); string[] SAR = SARText.Split(':'); if (SAR.Length != 2) { return(null); } try { float Result = (float)Math.Round((decimal)int.Parse(SAR[0]) / int.Parse(SAR[1]), 3); return(Result); } catch { return(null); } }
public static bool RunDeshakerPass(MediaEncoderSettings settings, ExecutingProcessHandler callback) { string TempOut = settings.DeshakerLog + ".y4m"; string Args = string.Format(@"""{0}"" -o - ""{1}""", settings.DeshakerScript, TempOut); bool Result = Run(@"Encoder\avs2yuv.exe", Args, true, ProcessPriorityClass.Normal, callback); File.Delete(TempOut); return(Result); }
public void GenerateScript(MediaEncoderSettings settings, bool preview, bool multiThreaded) { string Script = settings.CustomScript; if (string.IsNullOrEmpty(Script)) Script = GetVideoScript(settings, GetPreviewSourceFile(settings), preview, multiThreaded); else if (preview) Script = ConvertScriptForPreview(Script); WriteFile(Script, PreviewScriptFile); SaveSettingsFile(settings, PreviewSettingsFile); }
/// <summary> /// Saves the audio output of specified script into a WAV file. /// </summary> /// <param name="settings">An object containing the encoding settings.</param> /// <param name="destination">The WAV file to write.</param> /// <param name="options">The options that control the behaviors of the process.</param> public static void SaveAudioToWav(MediaEncoderSettings settings, string destination, ProcessStartOptions options) { string TempFile = settings.TempFile + ".avs"; AviSynthScriptBuilder Script = new AviSynthScriptBuilder(); if (settings.VideoAction != VideoAction.Copy) { // Read source script. Script.Script = File.ReadAllText(settings.ScriptFile); // Remote MT code. Script.RemoveMT(); Script.AppendLine("Trim(0,0)"); } else { // Read full video file. Script.AddPluginPath(); if (settings.ConvertToAvi || settings.InputFile.ToLower().EndsWith(".avi")) { Script.OpenAvi(settings.InputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat)); } else { Script.OpenDirect(settings.InputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat)); } Script.AppendLine("KillVideo()"); } Script.AppendLine(); // Add audio gain. if (settings.AudioGain.HasValue && settings.AudioGain != 0) { Script.AppendLine("AmplifydB({0})", settings.AudioGain.Value); } if (settings.ChangeAudioPitch) { // Change pitch to 432hz. Script.LoadPluginDll("TimeStretch.dll"); Script.AppendLine("ResampleAudio(48000)"); Script.AppendLine("TimeStretchPlugin(pitch = 100.0 * 0.98181819915771484)"); } // Add TWriteWAV. Script.AppendLine(); Script.LoadPluginDll("TWriteAVI.dll"); Script.AppendLine(@"TWriteWAV(""{0}"", true)", Script.GetAsciiPath(destination)); Script.AppendLine("ForceProcessWAV()"); // Write temp script. Script.WriteToFile(TempFile); // Execute. It aways returns an error but the file is generated. FFmpegProcess Worker = new FFmpegProcess(options); Worker.RunAvisynth(TempFile); File.Delete(TempFile); }
public bool PauseEncoding() { if (IsEncoding) { IsEncoding = false; MediaEncoderSettings Job = ProcessingQueue.FirstOrDefault(); if (Job != null) { Job.CompletionStatus = CompletionStatus.Cancelled; FFmpegConfig.UserInterfaceManager.Stop(Job.JobIndex); return true; } } return false; }
public void GenerateScript(MediaEncoderSettings settings, bool preview, bool multiThreaded) { AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript); if (Script.IsEmpty) Script = GenerateVideoScript(settings, GetPreviewSourceFile(settings), preview, multiThreaded); else if (preview) { Script.RemoveMT(); Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")"); } else if (!multiThreaded) Script.RemoveMT(); Script.WriteToFile(PreviewScriptFile); SaveSettingsFile(settings, PreviewSettingsFile); }
/// <summary> /// Prepares the files of an existing job. /// </summary> /// <returns>A MediaEncoderSegments object containing the segments analysis.</returns> public MediaEncoderSegments PrepareExistingJob(MediaEncoderSettings settings) { settings.ResumePos = 0; settings.CompletionStatus = CompletionStatus.Success; if (File.Exists(settings.FinalFile)) { // Merging was completed. return null; } else { MediaEncoderSegments SegBusiness = new MediaEncoderSegments(); SegBusiness.Analyze(settings); return SegBusiness; } }
public void GenerateScript(MediaEncoderSettings settings, bool preview, bool multiThreaded) { AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript); if (Script.IsEmpty) Script = MediaEncoderScript.GenerateVideoScript(settings, GetPreviewSourceFile(settings), preview, multiThreaded); else if (preview) { Script.RemoveMT(); Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")"); } else if (!multiThreaded) Script.RemoveMT(); Script.WriteToFile(PathManager.PreviewScriptFile); settings.Save(PathManager.PreviewSettingsFile); }
private CompletionStatus GenerateDeshakerLogSegment(MediaEncoderSettings settings, string inputFile, int segment, long jobStart, long frameStart, long frameEnd, ProcessStartOptions jobOptions) { // Write Deshaker Pass 1 script to file. string Script = MediaEncoderScript.GenerateDeshakerScript(settings, inputFile, segment, frameStart, frameEnd); File.WriteAllText(settings.DeshakerScript, Script); // Run pass. jobOptions.IsMainTask = true; jobOptions.Title = "Running Deshaker Prescan"; jobOptions.ResumePos = frameStart - jobStart; CompletionStatus Result = MediaEncoder.ConvertToAvi(settings.DeshakerScript, settings.DeshakerTempOut, false, jobOptions); File.Delete(settings.DeshakerScript); File.Delete(settings.DeshakerTempOut); return Result; }
/// <summary> /// Auto-load Preview file if encoded was unexpectedly closed. /// </summary> /// <returns>The previous preview encoding settings.</returns> public async Task<MediaEncoderSettings> AutoLoadPreviewFileAsync() { if (File.Exists(PathManager.PreviewSettingsFile)) { MediaEncoderSettings settings = MediaEncoderSettings.Load(PathManager.PreviewSettingsFile); if (!File.Exists(PathManager.PreviewSourceFile) && File.Exists(settings.FilePath)) { double? SourceFps = settings.SourceFrameRate; // Keep FPS in case it cannot be read from the file. await PreparePreviewFile(settings, false, false); if (!settings.SourceFrameRate.HasValue) settings.SourceFrameRate = SourceFps; } settings.JobIndex = -1; return settings; } return null; }
/// <summary> /// Encodes specified audio file according to settings. The script file must already be written. /// </summary> /// <param name="settings">An object containing the encoding settings.</param> /// <returns>The endoding completion status..</returns> public static CompletionStatus EncodeAudio(MediaEncoderSettings settings) { CompletionStatus Result = CompletionStatus.Success; string WavFile = PathManager.GetAudioFile(settings.JobIndex, AudioActions.Wav); ProcessStartOptions Options = new ProcessStartOptions(settings.JobIndex, "Exporting Audio", false).TrackProcess(settings); if (!File.Exists(WavFile)) { EncoderBusiness.SaveAudioToWav(settings, WavFile, Options); if (settings.CompletionStatus == CompletionStatus.Cancelled) { File.Delete(WavFile); return(CompletionStatus.Cancelled); } if (!File.Exists(WavFile)) { settings.Cancel(); return(CompletionStatus.Error); } } string DestFile = PathManager.GetAudioFile(settings.JobIndex, settings.AudioAction); if (!File.Exists(DestFile)) { Options.Title = "Encoding Audio"; if (settings.AudioAction == AudioActions.Opus) { string Args = string.Format(@"--bitrate {0} ""{1}"" ""{2}""", settings.AudioQuality, WavFile, DestFile); FFmpegProcess Worker = new FFmpegProcess(Options); Result = Worker.Run("Encoder\\opusenc.exe", Args); } else if (settings.AudioAction == AudioActions.Aac || settings.AudioAction == AudioActions.Flac) { Result = MediaEncoder.Encode(WavFile, null, settings.AudioAction == AudioActions.Flac ? "flac" : "aac", string.Format("-b:a {0}k", settings.AudioQuality), DestFile, Options); } } if (Result != CompletionStatus.Success || !File.Exists(DestFile)) { File.Delete(DestFile); settings.Cancel(); } return(Result); }
/// <summary> /// Gets an AviSynth clip information by running a script that outputs the frame count to a file. /// </summary> /// <param name="source">The AviSynth script to get information for.</param> /// <param name="silent">If true, the x264 window will be hidden.</param> /// <returns>The clip information.</returns> public static ClipInfo GetClipInfo(MediaEncoderSettings settings, string scriptFile, bool silent) { string TempScript = settings.TempFile + ".avs"; string TempResult = settings.TempFile + ".txt"; string TempOut = settings.TempFile + ".y4m"; // Read source script and remove MT. Also remove Deshaker if present. string FileContent = File.ReadAllText(scriptFile); FileContent.Replace(Environment.NewLine + "Deshaker", Environment.NewLine + "#Deshaker"); AviSynthScriptBuilder Script = new AviSynthScriptBuilder(FileContent); Script.RemoveMT(); //Script.DitherOut(false); // Get frame count. Script.AppendLine(); Script.AppendLine(@"WriteFileStart(""{0}"", ""FrameRate""{1}""Framecount"")", TempResult, @", """""" "","" """""", "); Script.AppendLine("Trim(0,-1)"); Script.WriteToFile(TempScript); // Run script. Run(@"Encoder\avs2yuv.exe", String.Format(@"""{0}"" -o {1}", TempScript, TempOut), true); // Read frame count ClipInfo Result = null; if (File.Exists(TempResult)) { string FileString = File.ReadAllText(TempResult); string[] FileValues = FileString.Split(','); Result = new ClipInfo(); try { Result.FrameRate = float.Parse(FileValues[0], CultureInfo.InvariantCulture); Result.FrameCount = int.Parse(FileValues[1]); } catch { Result = null; } } // Delete temp files. File.Delete(TempScript); File.Delete(TempResult); File.Delete(TempOut); // Dummy file that received avs2yuv output. return(Result); }
/// <summary> /// Moves specified settings file as preview files. /// </summary> /// <param name="settings">The settings to use for re-encoding.</param> public async Task MovePreviewFilesAsync(MediaEncoderSettings settings) { await DeletePreviewFilesAsync(); if (settings.ConvertToAvi) File.Move(settings.InputFile, PathManager.PreviewSourceFile); if (settings.Deshaker && File.Exists(settings.DeshakerLog)) File.Move(settings.DeshakerLog, PathManager.PreviewDeshakerLog); if (!string.IsNullOrEmpty(settings.CustomScript) && (settings.ConvertToAvi || settings.Deshaker)) { AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript); if (settings.ConvertToAvi) Script.Replace(Script.GetAsciiPath(settings.InputFile), Script.GetAsciiPath(PathManager.PreviewSourceFile)); if (settings.Deshaker) Script.Replace(Script.GetAsciiPath(settings.DeshakerLog), Script.GetAsciiPath(PathManager.PreviewDeshakerLog)); settings.CustomScript = Script.Script; } settings.Save(PathManager.PreviewSettingsFile); }
public static MediaEncoderSettings Load(string filePath) { using (var stream = File.OpenRead(filePath)) { var serializer = new XmlSerializer(typeof(MediaEncoderSettings)); MediaEncoderSettings Result = serializer.Deserialize(stream) as MediaEncoderSettings; if (Result.DeshakerSettings == null) { Result.DeshakerSettings = new MediaEncoderDeshakerSettings(); } // Serialization changes new lines; restore them. if (Result.CustomScript != null) { Result.CustomScript = Result.CustomScript.Replace("\n", "\r\n"); } return(Result); } }
/// <summary> /// Starts encoding with specified settings. If an encoding is already in process, it will be added /// to the queue and start once the previous encodings are finished. /// </summary> /// <param name="settings">The encoding settings.</param> public async Task EncodeFileAsync(MediaEncoderSettings settings) { settings.JobIndex = ++JobIndex; // Files must be prepared before adding to queue so that user can replace preview files. DeleteJobFiles(settings); File.Delete(PreviewScriptFile); File.Delete(PreviewSettingsFile); if (settings.ConvertToAvi) SafeMove(PreviewSourceFile, settings.InputFile); SaveSettingsFile(settings, settings.SettingsFile); string Script = settings.CustomScript; if (string.IsNullOrEmpty(Script)) Script = GetVideoScript(settings, settings.InputFile, false, true); else Script = Script.Replace(GetAsciiPath(PreviewSourceFile), GetAsciiPath(settings.InputFile)); WriteFile(Script, settings.ScriptFile); await StartEncodeFileAsync(settings); }
/// <summary> /// Starts encoding with specified settings. If an encoding is already in process, it will be added /// to the queue and start once the previous encodings are finished. /// </summary> /// <param name="settings">The encoding settings.</param> public async Task EncodeFileAsync(MediaEncoderSettings settings) { settings.JobIndex = ++JobIndex; // Files must be prepared before adding to queue so that user can replace preview files. DeleteJobFiles(settings); File.Delete(PreviewScriptFile); File.Delete(PreviewSettingsFile); if (settings.ConvertToAvi) SafeMove(PreviewSourceFile, settings.InputFile); SaveSettingsFile(settings, settings.SettingsFile); AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript); if (Script.IsEmpty) Script = GenerateVideoScript(settings, settings.InputFile, false, true); else Script.Replace(Script.GetAsciiPath(PreviewSourceFile), Script.GetAsciiPath(settings.InputFile)); //Script.DitherOut(true); Script.WriteToFile(settings.ScriptFile); await StartEncodeFileAsync(settings); }
private EncodingCompletedEventArgs GetEncodingResults(MediaEncoderSettings settings, string finalFile, DateTime? startTime) { // Create encoding result object. EncodingCompletedEventArgs Result = null; if (finalFile == null || File.Exists(finalFile)) { Result = new EncodingCompletedEventArgs(); Result.Settings = settings; Result.OldFileName = settings.FilePath; Result.NewFileName = settings.FinalFile; if (startTime.HasValue) Result.EncodingTime = DateTime.Now - startTime.Value; if (finalFile != null) { FileInfo FinalFileInfo = new FileInfo(finalFile); Result.NewFileSize = FinalFileInfo.Length; FinalFileInfo = new FileInfo(settings.FilePath); Result.OldFileSize = FinalFileInfo.Length; } } return Result; }
public async Task PreparePreviewFile(MediaEncoderSettings settings, bool overwrite, bool calcAutoCrop) { if (string.IsNullOrEmpty(settings.FilePath)) return; if (overwrite) { File.Delete(PathManager.PreviewSourceFile); // Select default open method. if (settings.FilePath.ToLower().EndsWith(".avi")) settings.ConvertToAvi = false; else { FFmpegProcess FileInfo = await Task.Run(() => MediaInfo.GetFileInfo(settings.FilePath)); if (settings.ConvertToAvi && FileInfo?.VideoStream?.Height >= 720) settings.ConvertToAvi = false; } } bool AviFileReady = File.Exists(PathManager.PreviewSourceFile); if (!AviFileReady && settings.ConvertToAvi) AviFileReady = await Task.Run(() => MediaEncoder.ConvertToAvi(settings.FilePath, PathManager.PreviewSourceFile, true, new ProcessStartOptions(FFmpegDisplayMode.Interface, "Converting to AVI"))) == CompletionStatus.Success; if (AviFileReady && settings.ConvertToAvi) await GetMediaInfo(PathManager.PreviewSourceFile, settings); else { settings.ConvertToAvi = false; await GetMediaInfo(settings.FilePath, settings); } // Auto-calculate crop settings. if (calcAutoCrop) { if (settings.CropLeft == 0 && settings.CropTop == 0 && settings.CropRight == 0 && settings.CropBottom == 0) { Rect AutoCrop = await Task.Run(() => EncoderBusiness.GetAutoCropRect(settings.FilePath, settings.SourceHeight ?? 0, settings.SourceWidth ?? 0, null)); if (settings.CropLeft == 0) settings.CropLeft = AutoCrop.Left; if (settings.CropTop == 0) settings.CropTop = AutoCrop.Top; if (settings.CropRight == 0) settings.CropRight = AutoCrop.Right; if (settings.CropBottom == 0) settings.CropBottom = AutoCrop.Bottom; } } }
/// <summary> /// Prepares the files of an existing job that we resume. /// </summary> /// <returns>Whether job still needs to execute.</returns> //private bool PrepareResumeJob(MediaEncoderSettings settings) { // AvisynthTools.EditStartPosition(settings.ScriptFile, 0); // // At least one segment has been processed. Check if the entire file has been processed. // ProcessStartOptions Options = new ProcessStartOptions(settings.JobIndex, "Resuming...", false).TrackProcess(settings); // Task<long> TaskCount = Task.Run(() => AvisynthTools.GetFrameCount(settings.ScriptFile, Options)); // int Segment = 0; // List<Task<long>> TaskList = new List<Task<long>>(); // while (File.Exists(PathManager.GetOutputFile(settings.JobIndex, ++Segment, settings.VideoCodec)) && settings.CompletionStatus != CompletionStatus.Cancelled) { // string SegmentFile = PathManager.GetOutputFile(settings.JobIndex, Segment, settings.VideoCodec); // // Discard segments of less than 10kb. // if (new FileInfo(SegmentFile).Length > 10000) { // int SegmentLocal = Segment; // TaskList.Add(Task.Run(() => AvisynthTools.GetFrameCount(PathManager.GetOutputFile(settings.JobIndex, SegmentLocal, settings.VideoCodec), null))); // } else { // // There shouldn't be any resumed job following a segment that is being deleted. // File.Delete(SegmentFile); // break; // } // } // long OutputFrames = 0; // Task.WaitAll(TaskList.ToArray()); // foreach (Task<long> item in TaskList) { // OutputFrames += item.Result; // } // TaskCount.Wait(); // if (settings.CompletionStatus == CompletionStatus.Cancelled) // return false; // long ScriptFrames = TaskCount.Result; // if (OutputFrames >= ScriptFrames) { // // Job completed. // //EncodingCompletedEventArgs EncodeResult = FinalizeEncoding(settings, null); // //if (EncodeResult != null) // // EncodingCompleted(this, EncodeResult); // //else { // // PathManager.DeleteJobFiles(settings.JobIndex); // //} // return false; // } else { // // Resume with new segment. // AvisynthTools.EditStartPosition(settings.ScriptFile, OutputFrames); // settings.ResumeSegment = Segment; // settings.ResumePos = OutputFrames; // File.Delete(settings.OutputFile); // return true; // } //} private async Task GetMediaInfo(string previewFile, MediaEncoderSettings settings) { FFmpegProcess FInfo = await Task.Run(() => MediaInfo.GetFileInfo(previewFile)); FFmpegVideoStreamInfo VInfo = FInfo.VideoStream; FFmpegAudioStreamInfo AInfo = settings.ConvertToAvi ? await Task.Run(() => MediaInfo.GetFileInfo(settings.FilePath).AudioStream) : FInfo.AudioStream; settings.SourceWidth = FInfo.VideoStream.Width; settings.SourceHeight = FInfo.VideoStream.Height; if (settings.SourceHeight > 768) settings.OutputHeight = settings.SourceHeight.Value; settings.SourceAspectRatio = (float)(VInfo?.PixelAspectRatio ?? 1); // Fix last track of VCDs that is widescreen. if (settings.SourceHeight == 288 && settings.SourceWidth == 352 && settings.SourceAspectRatio == 1.485f) settings.SourceAspectRatio = 1.092f; settings.SourceFrameRate = VInfo?.FrameRate; settings.SourceAudioFormat = AInfo?.Format; settings.SourceVideoFormat = VInfo?.Format; bool IsTvRange = VInfo?.ColorRange != "pc"; if (!string.IsNullOrEmpty(VInfo?.ColorMatrix)) { settings.SourceColorMatrix = VInfo.ColorMatrix.EndsWith("601") ? (IsTvRange ? ColorMatrix.Rec601 : ColorMatrix.Pc601) : (IsTvRange ? ColorMatrix.Rec709 : ColorMatrix.Pc709); } else settings.SourceColorMatrix = VInfo?.Height < 600 ? (IsTvRange ? ColorMatrix.Rec601 : ColorMatrix.Pc601) : (IsTvRange ? ColorMatrix.Rec709 : ColorMatrix.Pc709); settings.SourceChromaPlacement = string.Compare(VInfo?.Format, "mpeg1video", true) == 0 ? ChromaPlacement.MPEG1 : ChromaPlacement.MPEG2; settings.DegrainPrefilter = VInfo?.Height < 600 ? DegrainPrefilters.SD : DegrainPrefilters.HD; settings.SourceVideoBitrate = (int)(new FileInfo(previewFile).Length / FInfo.FileDuration.TotalSeconds / 1024 * 8); settings.SourceAudioBitrate = AInfo?.Bitrate; if (!settings.HasAudioOptions) settings.AudioQuality = AInfo?.Bitrate > 0 ? AInfo.Bitrate : 256; if (settings.AudioQuality > 384) settings.AudioQuality = 384; settings.SourceBitDepth = 8; // VInfo.BitDepth; //settings.DenoiseD = 2; //settings.DenoiseA = settings.SourceHeight < 720 ? 2 : 1; settings.Position = FInfo.FileDuration.TotalSeconds / 2; settings.VideoAction = settings.SourceHeight >= 1080 ? VideoAction.x264 : VideoAction.x265; settings.EncodeQuality = settings.SourceHeight >= 1080 ? 23 : 22; settings.EncodePreset = settings.SourceHeight >= 1080 ? EncodePresets.veryslow : EncodePresets.medium; // Use Cache to open file when file is over 500MB settings.CalculateSize(); }
public static bool EncodeAudio(MediaEncoderSettings settings, bool silent) { if (settings.AudioAction == AudioActions.EncodeOpus) { string Args = string.Format(@"--bitrate {0} ""{1}"" ""{2}""", settings.AudioQuality, settings.AudioFileWav, settings.AudioFileOpus); return(Run("Encoder\\opusenc.exe", Args, silent)); } else if (settings.AudioAction == AudioActions.EncodeAac || settings.AudioAction == AudioActions.EncodeFlac) { string Args = string.Format(@"-i {2}{0} -b:a {1}k {3}", settings.AudioAction == AudioActions.EncodeFlac ? " -c:a flac" : "", settings.AudioQuality, settings.AudioFileWav, settings.AudioAction == AudioActions.EncodeFlac ? settings.AudioFileFlac : settings.AudioFileAac); return(Run("Encoder\\ffmpeg.exe", Args, silent)); } else { return(true); } }
/// <summary> /// For files encoded in various segments (stop/resume), merge the various segments. /// </summary> private CompletionStatus MergeSegments(MediaEncoderSettings settings, string destination) { MediaEncoderSegments segBusiness = new MediaEncoderSegments(); segBusiness.Analyze(settings); if (segBusiness.SegLeft.Count() > 0) return CompletionStatus.Error; List<string> SegmentList = new List<string>(); foreach (SegmentInfo seg in segBusiness.SegDone) { SegmentList.Add(PathManager.GetOutputFile(settings.JobIndex, seg.Start, settings.Container)); } CompletionStatus Result = CompletionStatus.Success; File.Delete(destination); if (SegmentList.Count == 1) File.Move(SegmentList[0], destination); else if (SegmentList.Count > 1) { Result = MediaMuxer.Concatenate(SegmentList, destination, new ProcessStartOptions(settings.JobIndex, "Merging Files", false)); } settings.CompletionStatus = Result; return Result; }
public void PrepareJobFiles(MediaEncoderSettings settings) { settings.JobIndex = ++JobIndex; // Files must be prepared before adding to queue so that user can replace preview files. PathManager.DeleteJobFiles(settings.JobIndex); File.Delete(PathManager.PreviewScriptFile); File.Delete(PathManager.PreviewSettingsFile); if (settings.ConvertToAvi) PathManager.SafeMove(PathManager.PreviewSourceFile, settings.InputFile); if (settings.Deshaker) PathManager.SafeMove(PathManager.PreviewDeshakerLog, settings.DeshakerLog); settings.Save(settings.SettingsFile); AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript); if (Script.IsEmpty) Script = MediaEncoderScript.GenerateVideoScript(settings, settings.InputFile, false, true); else { Script.Replace(Script.GetAsciiPath(PathManager.PreviewSourceFile), Script.GetAsciiPath(settings.InputFile)); Script.Replace(Script.GetAsciiPath(PathManager.PreviewDeshakerLog), Script.GetAsciiPath(settings.DeshakerLog)); } Script.WriteToFile(settings.ScriptFile); // if (settings.DeshakerSettings.PrescanAction == PrescanType.Full) }
private static void ApplyInterFrame(AviSynthScriptBuilder Script, MediaEncoderSettings settings, int CPU) { Script.LoadPluginDll("FrameRateConverter.dll"); Script.LoadPluginAvsi("FrameRateConverter.avsi"); Script.LoadPluginDll("MaskTools2.dll"); Script.LoadPluginDll("MvTools2.dll"); string Prefilter = ""; if (!settings.Denoise) { Script.LoadPluginDll("RgTools.dll"); Prefilter = ", Prefilter=RemoveGrain(21)"; } if (settings.IncreaseFrameRateValue == FrameRateModeEnum.Double) { Script.AppendLine(@"FrameRateConverter(FrameDouble=true){0}", Prefilter); } else { int NewNum = 0; int NewDen = 0; if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps30) { NewNum = 30; // 30000; NewDen = 1; // 1001; } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps60) { NewNum = 60; // 60000; NewDen = 1; // 1001; } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps120) { NewNum = 120; // 120000; NewDen = 1; // 1001; } Script.AppendLine(@"FrameRateConverter(NewNum={0}, NewDen={1}, Preset=""{2}""{3})", NewNum, NewDen, settings.IncreaseFrameRatePreset, Prefilter); } }
/// <summary> /// Returns the audio gain that can be applied to an audio file. /// </summary> /// <param name="settings">The settings pointing to the file to analyze.</param> /// <returns>A float value representing the audio gain that can be applied, or null if it failed.</returns> public static float?GetAudioGain(MediaEncoderSettings settings) { string TempResult = settings.TempFile + ".txt"; string Args = string.Format(@"""{0}ffmpeg.exe"" -i ""{1}"" -af ""volumedetect"" -f null null > ""{1}"" 2>&1", Settings.AviSynthPluginsPath, settings.FilePath, TempResult); Run("cmd", CommandPipe(Args), true); float?Result = null; if (File.Exists(TempResult)) { string FileString = File.ReadAllText(TempResult); // Find max_volume. string SearchVal = "max_volume: "; int Pos1 = FileString.IndexOf(SearchVal); if (Pos1 >= 0) { Pos1 += SearchVal.Length; // Find end of line. int Pos2 = FileString.IndexOf('\r', Pos1); if (Pos2 >= 0) { string MaxVolString = FileString.Substring(Pos1, Pos2 - Pos1); if (MaxVolString.Length > 3) { // Remove ' dB' MaxVolString = MaxVolString.Substring(0, MaxVolString.Length - 3); float MaxVol = 0; if (float.TryParse(MaxVolString, out MaxVol)) { Result = Math.Abs(MaxVol); } } } } File.Delete(TempResult); } return(Result); }
/// <summary> /// Automatically reloads jobs if the encoder was unexpectedly closed. /// </summary> public void AutoLoadJobs() { try { if (!Directory.Exists(PathManager.TempFilesPath)) Directory.CreateDirectory(PathManager.TempFilesPath); } catch { return; } var JobList = Directory.EnumerateFiles(PathManager.TempFilesPath, "Job*_Settings.xml"); int Index = 0; MediaEncoderSettings settings; //List<Task> TaskList = new List<Task>(); // Get list of interrupted jobs. foreach (string item in JobList) { // Load settings file. settings = null; try { settings = MediaEncoderSettings.Load(item); } catch { } // Resume job. if (int.TryParse(Path.GetFileName(item).Replace("Job", "").Replace("_Settings.xml", ""), out Index)) { if (Index > JobIndex) JobIndex = Index; if (settings != null && File.Exists(settings.InputFile) && File.Exists(settings.ScriptFile) && File.Exists(settings.SettingsFile) && File.Exists(settings.FilePath)) { ProcessingQueue.Add(settings); //TaskList.Add(StartJobAsync(settings)); } else { // Resume job failed, delete files. PathManager.DeleteJobFiles(settings.JobIndex); } } } }
private static void ApplyDeshaker(AviSynthScriptBuilder Script, MediaEncoderSettings settings, ref bool isLsb, ref bool isYV24, bool multiProcess) { settings.DeshakerSettings.LogFile = Script.GetAsciiPath(settings.DeshakerLog); settings.DeshakerSettings.Pass = 2; Script.LoadPluginDll(@"VDubFilter.dll"); Script.AppendLine(@"LoadVirtualDubPlugin(P+""deshaker.vdf"", ""deshaker"", preroll=0)"); Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")"); if (multiProcess) { Script.AppendLine("### prefetch: 3, 3"); // Keep 3 frames before and after for temporal filters. Script.AppendLine("### ###"); // MP_Pipeline starts new process here } Script.AppendLine(@"deshaker(""{0}"")", settings.DeshakerSettings.ToString()); Script.AppendLine(@"ConvertToYV12(matrix=""Rec709"")"); if (multiProcess) { Script.AppendLine("### prefetch: {0}, {1}", settings.DeshakerSettings.FillBordersWithFutureFrames ? settings.DeshakerSettings.FillBordersWithFutureFramesCount : 0, settings.DeshakerSettings.FillBordersWithPreviousFrames ? settings.DeshakerSettings.FillBordersWithPreviousFramesCount : 0); Script.AppendLine("### ###"); // MP_Pipeline starts another here } isLsb = false; isYV24 = false; }
/// <summary> /// Encodes specified file into H264 format. The script file must already be written. /// </summary> /// <param name="settings">An object containing the encoding settings.</param> /// <returns>Whether the operation was completed.</returns> public static bool EncodeVideo(MediaEncoderSettings settings) { File.Delete(settings.OutputFile); string PipeArgs; if (settings.VideoCodec == VideoCodecs.x264) { PipeArgs = string.Format(@"""{0}avs2yuv.exe"" ""{1}"" -o - | ""{0}ffmpeg.exe"" -y -i - -an -c:v libx264 -psy-rd 1:0.05 -preset {2} -crf {3} ""{4}""", Settings.AviSynthPluginsPath, settings.ScriptFile, settings.EncodePreset, settings.EncodeQuality, settings.OutputFile); } else if (settings.VideoCodec == VideoCodecs.x265) { PipeArgs = string.Format(@"""{0}avs2yuv.exe"" ""{1}"" -o - | ""{0}ffmpeg.exe"" -y -i - -an -c:v libx265 -preset {2} -crf {3} ""{4}""", Settings.AviSynthPluginsPath, settings.ScriptFile, settings.EncodePreset, settings.EncodeQuality, settings.OutputFile); } else // AVI { PipeArgs = string.Format(@"""{0}avs2yuv.exe"" ""{1}"" -o - | ""{0}ffmpeg.exe"" -y -i - -an -c:v utvideo ""{4}""", Settings.AviSynthPluginsPath, settings.ScriptFile, settings.EncodePreset, settings.EncodeQuality, settings.OutputFile); } //} return(Run("cmd", CommandPipe(PipeArgs), false)); }
public void SaveSettingsFile(MediaEncoderSettings settings, string fileName) { Directory.CreateDirectory(Path.GetDirectoryName(fileName)); using (var writer = new StreamWriter(fileName)) { var serializer = new XmlSerializer(typeof(MediaEncoderSettings)); XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); serializer.Serialize(writer, settings, ns); writer.Flush(); } }
public static AviSynthScriptBuilder GenerateVideoScript(MediaEncoderSettings settings, string inputFile, bool preview, bool multiThreaded) { // int CPU = multiThreaded ? Environment.ProcessorCount : 1; int CPU = multiThreaded ? settings.Threads : 1; if (CPU <= 1) { multiThreaded = false; } bool RunMultiProcesses = false; if (settings.Deshaker && multiThreaded) { RunMultiProcesses = true; // Run through MP_Pipeline multiThreaded = false; // Deshaker doesn't work with MT CPU = 1; } //if (settings.Threads > 0) { // multiThreaded = false; // CPU = 1; //} settings.CalculateSize(); // Calculate encoding and final frame rates. double ChangeSpeedValue = (settings.ChangeSpeed && settings.CanAlterAudio) ? (double)settings.ChangeSpeedValue / 100 : 1; double FrameRateBefore = settings.SourceFrameRate.Value * ChangeSpeedValue; // Generate video script. AviSynthScriptBuilder Script = new AviSynthScriptBuilder(); bool IsYV24 = false; Script.AppendLine(); // After clean-up, this adds a line after LoadPlugin commands. Script.AddPluginPath(); if (multiThreaded) { Script.LoadPluginAvsi("AviSynthMT.avsi"); } if (settings.ConvertToAvi || inputFile.ToLower().EndsWith(".avi")) { Script.OpenAvi(inputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat)); } else { Script.OpenDirect(inputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat)); } if (FrameRateBefore != settings.SourceFrameRate) { Script.AppendLine(CultureInfo.InvariantCulture, "AssumeFPS({0}, true)", FrameRateBefore); } if (settings.Trim && settings.CanAlterAudio) { Script.AppendLine("Trim({0}, {1})", (settings.TrimStart ?? 0) > 0 ? (int)(settings.TrimStart.Value * settings.SourceFrameRate.Value) : 0, (settings.TrimEnd ?? 0) > 0 && !preview ? (int)(settings.TrimEnd.Value * settings.SourceFrameRate.Value) : 0); } if (settings.Denoise) { //Script.LoadPluginDll("MvTools2.dll"); //Script.LoadPluginDll("MaskTools2.dll"); //Script.LoadPluginDll("FFT3DFilter.dll"); //Script.LoadPluginDll("ModPlus.dll"); //Script.LoadPluginDll("RgTools.dll"); //Script.LoadPluginDll("DCTFilter.dll"); //Script.LoadPluginAvsi("mClean.avsi"); //Script.AppendLine("mClean(rn={0}{1})", 10, IsHD ? ", outbits=16" : ""); Script.AppendLine(@"MCTemporalDenoise(settings=""{0}""{1})", "medium", settings.Deblock ? ", deblock=true" : ""); } else if (settings.Deblock) { Script.LoadPluginDll("MaskTools2.dll"); Script.LoadPluginDll("DCTFilter.dll"); Script.LoadPluginDll("deblock.dll"); Script.LoadPluginAvsi("Deblock_QED.avsi"); Script.AppendLine("Deblock_QED()"); } if (settings.CropSource.HasValue) { Script.AppendLine("Crop({0}, {1}, -{2}, -{3})", settings.CropSource.Left, settings.CropSource.Top, settings.CropSource.Right, settings.CropSource.Bottom); } // If possible, KNLMeans will output 16-bit frames before upscaling. bool IsHD = (settings.Dering || settings.Deblock || settings.Degrain || settings.SourceColorMatrix != ColorMatrix.Rec709 || (settings.FrameDouble > 0 && (settings.SuperRes || settings.UpscaleMethod == UpscaleMethods.SuperXbr))); bool IsColorMatrixHD = IsHD; bool IsChromaFixed = settings.SourceChromaPlacement == ChromaPlacement.MPEG2; if (IsHD) { //if (!settings.Denoise) Script.AppendLine("ConvertBits(16)"); if (settings.SourceColorMatrix != ColorMatrix.Rec709) { Script.AppendLine("[ColorMatrixShader]"); // Placeholder that will be replaced after generating the rest. } } if (settings.FixDoubleFrames) { Script.LoadPluginDll("FrameRateConverter.dll"); Script.LoadPluginAvsi("FrameRateConverter.avsi"); Script.LoadPluginDll("MaskTools2.dll"); Script.LoadPluginDll("MvTools2.dll"); Script.AppendLine("InterpolateDoubles(.1)"); } if (settings.Dering) { Script.LoadPluginAvsi("HQDeringmod.avsi"); Script.LoadPluginDll("MedianBlur2.dll"); Script.LoadPluginDll("dfttest.dll"); Script.LoadPluginDll("RgTools.dll"); Script.LoadPluginDll("SmoothAdjust.dll"); Script.AppendLine("HQDeringmod({0})", IsHD ? "lsb_in=true, lsb=true" : ""); } if (settings.Degrain) { ApplyDegrain(Script, settings, ref IsHD, ref IsYV24); } if (settings.Deshaker) { ApplyDeshaker(Script, settings, ref IsHD, ref IsYV24, RunMultiProcesses); } if (settings.FrameDouble > 0) { Script.AppendLine(@"ConvertToYUV444({0})", !IsChromaFixed ? string.Format(@"ChromaInPlacement=""{0}""", settings.SourceChromaPlacement.ToString()) : ""); IsYV24 = true; IsChromaFixed = true; } string FinalSize = string.Format("fWidth={0}, fHeight={1}", settings.OutputWidth + settings.CropAfter.Left + settings.CropAfter.Right, settings.OutputHeight + settings.CropAfter.Top + settings.CropAfter.Bottom); string FinalResize = FinalSize; if (settings.DownscaleMethod == DownscaleMethods.SSim) { FinalResize += string.Format(@", fKernel=""SSim"", fB={0}{1}", settings.SSimStrength / 100, settings.SSimSoft ? ", fC=1" : ""); } else // DownscaleMethod == Bicubic { FinalResize += string.Format(@", fKernel=""Bicubic"", fB=0, fC=.75"); } if (settings.FrameDouble > 0) { if (settings.UpscaleMethod == UpscaleMethods.NNedi3) { bool IsLastDouble = false; DitherPost(Script, ref IsHD, ref IsYV24, true); Script.LoadPluginDll("nnedi3.dll"); Script.LoadPluginAvsi("edi_rpow2.avsi"); Script.LoadPluginAvsi("ResizeX.avsi"); for (int i = 0; i < settings.FrameDouble; i++) { IsLastDouble = i == settings.FrameDouble - 1; string DoubleScript = string.Format("edi_rpow2(2, nns=4, {0}, Threads=2)", IsLastDouble && settings.DownscaleMethod == DownscaleMethods.Bicubic ? @"cshift=""Bicubic"", a1=0, a2=.75, " + FinalSize : @"cshift=""Spline16Resize"""); if (settings.SuperRes) { Script.AppendLine(CultureInfo.InvariantCulture, @"SuperRes({0}, {1}, {2}, """"""{3}""""""{4}{5}{6})", settings.SuperRes3Passes ? (i == 0 && settings.FrameDouble > 1 ? 5 : 3) : 2, settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f, DoubleScript, i == 0 ? GetMatrixIn(settings) : "", IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim ? ", " + FinalResize : "", multiThreaded ? "" : ", Engines=1"); } else { Script.AppendLine(DoubleScript); if (IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim) { Script.AppendLine("ResizeShader({0}{1})", FinalResize.Replace("fWidth=", "").Replace("fHeight=", "").Replace(" f", " "), // Use same string as FinalResize but remove 'f' parameter sufix. GetMatrixIn(settings)); } } } } else // UpscaleMethod == SuperXBR { if (settings.SuperRes) { Script.AppendLine(CultureInfo.InvariantCulture, @"SuperResXBR({0}, {1}, {2}{3}, XbrStr={4}, XbrSharp={5}{6}, {7}, FormatOut=""YV12""{8})", settings.SuperRes3Passes ? (settings.IncreaseFrameRate ? 5 : 3) : 2, settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f, settings.FrameDouble > 1 ? ", Factor=" + (1 << settings.FrameDouble).ToString() : "", settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f, GetMatrixIn(settings), FinalResize, multiThreaded ? "" : ", Engines=1"); } else { Script.AppendLine(@"SuperXBR(Str={0}, Sharp={1}{2}{3}, {4}, FormatOut=""YV12""{5})", settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f, settings.FrameDouble > 1 ? ", Factor=" + (1 << settings.FrameDouble).ToString() : "", GetMatrixIn(settings), FinalResize, multiThreaded ? "" : ", Engines=1"); } IsHD = false; IsYV24 = false; } } if (settings.DownscaleMethod != DownscaleMethods.SSim) { DitherPost(Script, ref IsHD, ref IsYV24, settings.IncreaseFrameRate); } string[] ShaderCommands = new string[] { "SuperRes", "SuperXBR", "SuperResXBR", "ResizeShader" }; if (settings.CropAfter.HasValue || settings.FrameDouble == 0) { if (settings.CropAfter.HasValue || settings.SourceAspectRatio != 1 || settings.OutputWidth != settings.SourceWidth || settings.OutputHeight != settings.OutputHeight) { if (settings.DownscaleMethod == DownscaleMethods.SSim && settings.FrameDouble == 0) { Script.AppendLine("ResizeShader({0}{1})", FinalResize.Replace("fWidth=", "").Replace("fHeight=", "").Replace(" f", " "), // Use same string as FinalResize but remove 'f' parameter sufix. GetMatrixIn(settings)); } DitherPost(Script, ref IsHD, ref IsYV24, false); if (settings.CropAfter.HasValue || settings.DownscaleMethod == DownscaleMethods.Bicubic) { Script.LoadPluginAvsi("ResizeX.avsi"); bool ApplyResize = settings.FrameDouble == 0 || !Script.ContainsAny(ShaderCommands); string CropFormat = "ResizeX"; CropFormat += settings.CropAfter.HasValue ? "({0}, {1}, {2}, {3}, -{4}, -{5}{6})" : "({0}, {1}{6})"; Script.AppendLine(CropFormat, settings.OutputWidth, settings.OutputHeight, settings.CropAfter.Left, settings.CropAfter.Top, settings.CropAfter.Right, settings.CropAfter.Bottom, ApplyResize ? @", kernel=""Bicubic"", a1=0, a2=.75" : ""); } } } // Use ColorMatrixShader only if it wasn't already applied through any other shader. if (Script.ContainsAny(ShaderCommands)) { // ColorMatrix was applied though another shader. Script.Replace("[ColorMatrixShader]" + Environment.NewLine, ""); Script.LoadPluginDll("Shader.dll"); Script.LoadPluginAvsi("Shader.avsi"); } else { string ColorMatrixScript = ""; // Apply color matrix if (settings.SourceColorMatrix == ColorMatrix.Pc709) { Script.LoadPluginDll("SmoothAdjust.dll"); ColorMatrixScript = string.Format(@"ColorYUV(levels=""PC->TV"""); } else if (settings.SourceColorMatrix != ColorMatrix.Rec709) { Script.LoadPluginDll("Shader.dll"); Script.LoadPluginAvsi("Shader.avsi"); ColorMatrixScript = string.Format(@"ResizeShader(Kernel=""ColorMatrix""{0})", GetMatrixIn(settings)); } Script.Replace("[ColorMatrixShader]" + Environment.NewLine, ColorMatrixScript + Environment.NewLine); } if (settings.IncreaseFrameRate) { if (IsYV24) { Script.AppendLine(@"ConvertToYUV420()"); IsYV24 = false; } DitherPost(Script, ref IsHD, ref IsYV24, true); ApplyInterFrame(Script, settings, CPU); } if (preview) { if (settings.Crop) { Script.AppendLine("AddBorders(2, 2, 2, 2, $FFFFFF)"); } Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")"); } if (multiThreaded) { Script.AppendLine("Prefetch({0})", CPU); } if (RunMultiProcesses) { Script.ConvertToMultiProcesses(settings.SourceFrameRate.Value); } else { Script.Cleanup(); } return(Script); }
public void ApplyInterFrame(AviSynthScriptBuilder Script, MediaEncoderSettings settings, int CPU) { Script.LoadPluginDll("svpflow1.dll"); Script.LoadPluginDll("svpflow2.dll"); Script.LoadPluginAvsi("InterFrame2.avsi"); if (settings.IncreaseFrameRateValue == FrameRateModeEnum.Double) Script.AppendLine(@"InterFrame(Cores={0}{1}, FrameDouble=true{2})", CPU, settings.IncreaseFrameRateSmooth ? @", Tuning=""Smooth""" : "", Settings.SavedFile.EnableMadVR ? ", GPU=true" : ""); else { int NewNum = 0; int NewDen = 0; if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps30) { NewNum = 30; // 30000; NewDen = 1; // 1001; } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps60) { NewNum = 60; // 60000; NewDen = 1; // 1001; } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps120) { NewNum = 120; // 120000; NewDen = 1; // 1001; } Script.AppendLine(@"InterFrame(Cores={0}{1}, NewNum={2}, NewDen={3}, GPU=true)", CPU, settings.IncreaseFrameRateSmooth ? @", Tuning=""Smooth""" : "", NewNum, NewDen); } }
/// <summary> /// Encodes specified video file according to settings. The script file must already be written. /// </summary> /// <param name="settings">An object containing the encoding settings.</param> /// <param name="frameCount">The amount of frames to process.</param> /// <param name="totalFrameCount">If encoding in various segments, the total amount of frames in the script.</param> /// <returns>The endoding completion status..</returns> public static CompletionStatus EncodeVideo(MediaEncoderSettings settings, long frameCount, long totalFrameCount) { CompletionStatus Result = CompletionStatus.None; File.Delete(settings.OutputFile); string Codec = "", Args = ""; if (settings.VideoAction == VideoAction.x264) { Codec = "libx264"; } else if (settings.VideoAction == VideoAction.x265) { Codec = "libx265"; Args = string.Format("-preset {0} -crf {1}", settings.EncodePreset, settings.EncodeQuality); } else if (settings.VideoAction == VideoAction.Avi) { Codec = "huffyuv"; } else if (settings.VideoAction == VideoAction.AviUtVideo) { Codec = "utvideo"; } else if (settings.VideoAction == VideoAction.xvid) { Codec = "xvid"; } else if (settings.VideoAction == VideoAction.x264_10bit) { Args = string.Format("--preset {0} --crf {1}", settings.EncodePreset, settings.EncodeQuality); } if (settings.ParallelProcessing > 1) { Args += settings.VideoAction == VideoAction.x264_10bit ? " --threads 4" : " -threads 4"; } ProcessStartOptions Options = new ProcessStartOptions(settings.JobIndex, "Processing Video", true).TrackProcess(settings); // Options.FrameCount = AvisynthTools.GetFrameCount(settings.ScriptFile, new ProcessStartOptions(settings.JobIndex, "Getting Frame Count", false).TrackProcess(settings)); Options.FrameCount = frameCount; Options.ResumePos = settings.ResumePos; Options.TotalFrameCount = totalFrameCount; if (settings.CompletionStatus == CompletionStatus.Success) { string JobScript = settings.OutputScriptFile; File.Delete(JobScript); File.Copy(settings.ScriptFile, JobScript); EditStartPosition(JobScript, settings.ResumePos, settings.ResumePos + frameCount - 1); if (settings.VideoAction == VideoAction.x264_10bit) { Result = EncodeX264_10bit(JobScript, Args, settings.OutputFile, Options); } else { Result = MediaEncoder.Encode(JobScript, Codec, null, Args, settings.OutputFile, Options); } File.Delete(JobScript); } else { Result = settings.CompletionStatus; } return(Result); }
public async Task PreparePreviewFile(MediaEncoderSettings settings, bool overwrite) { if (string.IsNullOrEmpty(settings.FileName)) return; if (overwrite) { File.Delete(PreviewSourceFile); // Select default open method. if (settings.FileName.ToLower().EndsWith(".avi")) settings.ConvertToAvi = false; else { using (MediaInfoReader InfoReader = new MediaInfoReader()) { InfoReader.LoadInfo(Settings.NaturalGroundingFolder + settings.FileName); if (settings.ConvertToAvi && InfoReader.Height.HasValue && InfoReader.Height >= 720) settings.ConvertToAvi = false; } } } bool AviFileReady = File.Exists(PreviewSourceFile); if (!AviFileReady && settings.ConvertToAvi) AviFileReady = await Task.Run(() => FfmpegBusiness.ConvertToAVI(Settings.NaturalGroundingFolder + settings.FileName, PreviewSourceFile, false)); if (AviFileReady && settings.ConvertToAvi) await GetMediaInfo(PreviewSourceFile, settings); else { settings.ConvertToAvi = false; await GetMediaInfo(Settings.NaturalGroundingFolder + settings.FileName, settings); } // Auto-calculate crop settings. if (settings.CropLeft == 0 && settings.CropTop == 0 && settings.CropRight == 0 && settings.CropBottom == 0) { Rect AutoCrop = await Task.Run(() => FfmpegBusiness.GetAutoCropRect(settings, true)); if (settings.CropLeft == 0) settings.CropLeft = AutoCrop.Left; if (settings.CropTop == 0) settings.CropTop = AutoCrop.Top; if (settings.CropRight == 0) settings.CropRight = AutoCrop.Right; if (settings.CropBottom == 0) settings.CropBottom = AutoCrop.Bottom; } }
private async Task GetMediaInfo(string previewFile, MediaEncoderSettings settings) { MediaInfoReader InfoReader = new MediaInfoReader(); await InfoReader.LoadInfoAsync(previewFile); settings.SourceWidth = InfoReader.Width; settings.SourceHeight = InfoReader.Height; settings.SourceAspectRatio = InfoReader.PixelAspectRatio ?? 1; // Fix last track of VCDs that is widescreen. if (settings.SourceHeight == 288 && settings.SourceWidth == 352 && settings.SourceAspectRatio == 1.485f) settings.SourceAspectRatio = 1.092f; settings.SourceFrameRate = InfoReader.FrameRate; if (settings.ConvertToAvi) await InfoReader.LoadInfoAsync(Settings.NaturalGroundingFolder + settings.FileName); settings.AudioRequiresMkv = (InfoReader.AudioFormat != "AAC"); settings.Position = (InfoReader.Length ?? 0) / 2; }
public bool CustomScriptHasChanges(MediaEncoderSettings settings) { return settings.CustomScript != GetVideoScript(settings, GetPreviewSourceFile(settings), false, true); }
public void DeleteJobFiles(MediaEncoderSettings settings) { if (settings.ConvertToAvi) File.Delete(settings.InputFile); File.Delete(settings.OutputFile); File.Delete(settings.FinalFile); File.Delete(settings.ScriptFile); File.Delete(settings.SettingsFile); }
public string GetPreviewSourceFile(MediaEncoderSettings settings) { if (settings.ConvertToAvi) return PreviewSourceFile; else return Settings.NaturalGroundingFolder + settings.FileName; }
public bool EncodeAudio(MediaEncoderSettings settings) { FfmpegBusiness.SaveAudioToWav(settings, true); return FfmpegBusiness.EncodeAudio(settings, true); }
/// <summary> /// Moves specified settings file as preview files. /// </summary> /// <param name="settings">The settings to use for re-encoding.</param> public async Task MovePreviewFilesAsync(MediaEncoderSettings settings) { await DeletePreviewFilesAsync(); if (settings.ConvertToAvi) File.Move(settings.InputFile, PreviewSourceFile); SaveSettingsFile(settings, PreviewSettingsFile); }
public void SaveSettingsFile(MediaEncoderSettings settings, string fileName) { Directory.CreateDirectory(Path.GetDirectoryName(fileName)); using (var writer = new StreamWriter(fileName)) { var serializer = new XmlSerializer(typeof(MediaEncoderSettings)); XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlWriterSettings ws = new XmlWriterSettings(); ws.NewLineHandling = NewLineHandling.Entitize; using (XmlWriter wr = XmlWriter.Create(writer, ws)) { serializer.Serialize(wr, settings, ns); } writer.Flush(); } }
public bool CustomScriptHasChanges(MediaEncoderSettings settings) { return settings.CustomScript.Replace("\r\n", "\n") != GenerateVideoScript(settings, GetPreviewSourceFile(settings), false, true).Script.Replace("\r\n", "\n"); }
public async Task OpenPreview(MediaEncoderSettings settings, bool overwrite) { if (string.IsNullOrEmpty(settings.FileName)) return; if (overwrite) File.Delete(PreviewSourceFile); bool IsCompleted = File.Exists(PreviewSourceFile) || !settings.ConvertToAvi || await Task.Run(() => FfmpegBusiness.ConvertToAVI(Settings.NaturalGroundingFolder + settings.FileName, PreviewSourceFile, false)); if (IsCompleted && settings.ConvertToAvi) await GetMediaInfo(PreviewSourceFile, settings); else { settings.ConvertToAvi = false; await GetMediaInfo(Settings.NaturalGroundingFolder + settings.FileName, settings); } }
private async Task GetMediaInfo(string previewFile, MediaEncoderSettings settings) { using (MediaInfoReader InfoReader = new MediaInfoReader()) { await InfoReader.LoadInfoAsync(previewFile); settings.SourceWidth = InfoReader.Width; settings.SourceHeight = InfoReader.Height; settings.SourceAspectRatio = InfoReader.PixelAspectRatio ?? 1; if (settings.SourceAspectRatio != 1) { // Get aspect ratio from FFMPEG which is more accurate. float? SAR = FfmpegBusiness.GetPixelAspectRatio(settings); if (SAR.HasValue) settings.SourceAspectRatio = SAR.Value; } // Fix last track of VCDs that is widescreen. if (settings.SourceHeight == 288 && settings.SourceWidth == 352 && settings.SourceAspectRatio == 1.485f) settings.SourceAspectRatio = 1.092f; settings.SourceFrameRate = InfoReader.FrameRate; if (settings.ConvertToAvi) await InfoReader.LoadInfoAsync(Settings.NaturalGroundingFolder + settings.FileName); settings.SourceAudioFormat = InfoReader.AudioFormat; settings.SourceVideoFormat = InfoReader.VideoFormat; settings.SourceColorMatrix = InfoReader.Height < 720 ? ColorMatrix.Rec601 : ColorMatrix.Rec709; if (!settings.CanCopyAudio) settings.EncodeFormat = VideoFormats.Mkv; settings.SourceAudioBitrate = InfoReader.AudioBitRate; settings.SourceBitDepth = InfoReader.BitDepth; settings.Position = (InfoReader.Length ?? 0) / 2; settings.CalculateSize(); } }
public void GenerateCustomScript(MediaEncoderSettings settings) { settings.CustomScript = GetVideoScript(settings, GetPreviewSourceFile(settings), false, true); }
public void SetEncodeSettings(MediaEncoderSettings value) { isBinding = true; SettingsTab.SelectedIndex = (String.IsNullOrEmpty(value.CustomScript) ? 0 : 2); encodeSettings = value; this.DataContext = value; isBinding = false; }
public string GetVideoScript(MediaEncoderSettings settings, string inputFile, bool preview, bool multiThreaded) { int CPU = Environment.ProcessorCount; if (CPU > 4 && (settings.DoubleNNEDI3Before || settings.DoubleEEDI3 || settings.DoubleNNEDI3)) CPU = 4; // Limit to 4 threads when NNEDI3 or EEDI3 is the bottleneck. bool AviSynthPlus = false; // multiThreaded = true; // Calculate CropSource and CropAfter values. bool CropSource = false; int CropSourceLeft = 0; int CropSourceTop = 0; int CropSourceRight = 0; int CropSourceBottom = 0; bool CropAfter = false; int CropAfterLeft = 0; int CropAfterTop = 0; int CropAfterRight = 0; int CropAfterBottom = 0; if (settings.Crop) { // CropSource must be a factor of two. CropSourceLeft = settings.CropLeft / 2 * 2; CropSourceTop = settings.CropTop / 2 * 2; CropSourceRight = settings.CropRight / 2 * 2; CropSourceBottom = settings.CropBottom / 2 * 2; } int ScaleFactor = (settings.DoubleNNEDI3Before ? 2 : 1) * (settings.DoubleEEDI3 ? 2 : 1) * (settings.DoubleNNEDI3 ? 2 : 1); int ExtraDouble = 0; // If cropping makes the output smaller than the resize dimension, keep doubling to enlarge. if (settings.Resize) { while ((settings.SourceHeight - CropSourceTop - CropSourceBottom) * ScaleFactor < settings.ResizeHeight) { ExtraDouble += 2; ScaleFactor *= 2; } } if (settings.Crop) { CropAfterTop = (settings.CropTop - CropSourceTop) * ScaleFactor; CropAfterLeft = (settings.CropLeft - CropSourceLeft) * ScaleFactor; CropAfterRight = (settings.CropRight - CropSourceRight) * ScaleFactor; CropAfterBottom = (settings.CropBottom - CropSourceBottom) * ScaleFactor; CropSource = (CropSourceLeft > 0 || CropSourceRight > 0 || CropSourceTop > 0 || CropSourceBottom > 0); CropAfter = (CropAfterLeft > 0 || CropAfterRight > 0 || CropAfterTop > 0 || CropAfterBottom > 0); } // Calculate encoding and final frame rates. double ChangeSpeedValue = settings.ChangeSpeed ? (double)settings.ChangeSpeedValue / 100 : 1; double FrameRateBefore = settings.SourceFrameRate.Value * ChangeSpeedValue; // Generate video script. StringBuilder Script = new StringBuilder(); if (multiThreaded) { // Script.AppendLine("Setmemorymax(1024)"); if (AviSynthPlus) { Script.AppendLine(@"SetFilterMTMode(""DEFAULT_MT_MODE"",2)"); Script.AppendLine(@"SetFilterMTMode(""AviSource"",3)"); } else { Script.AppendFormat("SetMTMode(3,{0})", CPU).AppendLine(); } } Script.AppendFormat(@"PluginPath = ""{0}""", GetAsciiPath(Settings.AviSynthPluginsPath)).AppendLine(); if (settings.ConvertToAvi) Script.AppendFormat(@"AviSource(""{0}"", audio=false, pixel_type=""YV12"")", GetAsciiPath(inputFile)).AppendLine(); //.ConvertToYV12() else Script.AppendFormat(@"DirectShowSource(""{0}"", audio=false, pixel_type=""YV12""{1})", GetAsciiPath(inputFile), settings.SourceFrameRate.HasValue ? ", fps=" + settings.SourceFrameRate : string.Empty).AppendLine(); //.ConvertToYV12() if (multiThreaded && !AviSynthPlus) Script.AppendLine("SetMTMode(2)"); if (settings.FixColors && !preview) { LoadPluginDll(Script, "ColorMatrix.dll"); Script.AppendLine(@"ColorMatrix(mode=""Rec.601->Rec.709"")"); } if (FrameRateBefore != settings.SourceFrameRate) Script.AppendFormat(CultureInfo.InvariantCulture, "AssumeFPS({0})", FrameRateBefore).AppendLine(); if (settings.Trim) { Script.AppendFormat("Trim({0}, {1})", settings.TrimStart.HasValue ? settings.TrimStart.Value * settings.SourceFrameRate.Value : 0, settings.TrimEnd.HasValue && !preview ? settings.TrimEnd.Value * settings.SourceFrameRate.Value : 0).AppendLine(); } if (CropSource) { Script.AppendFormat("Crop({0}, {1}, -{2}, -{3})", CropSourceLeft, CropSourceTop, CropSourceRight, CropSourceBottom).AppendLine(); } if (settings.Denoise || settings.SharpenAfterDouble || settings.SharpenFinal) LoadPluginDll(Script, "FFT3DFilter.dll"); if (settings.Denoise) { Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(sigma={0}, bt=5, bw=48, bh=48, ow=24, oh=24, sharpen={1}, ncpu={2})", ((double)settings.DenoiseStrength / 10).ToString(CultureInfo.InvariantCulture), (double)settings.SharpenAfterDoubleStrength / 100, CPU).AppendLine(); } //if (settings.SharpenAfterDouble || settings.SharpenFinal) { // LoadPluginDll(Script, "masktools2.dll"); // LoadPluginDll(Script, "RgTools.dll"); // LoadPluginAvsi(Script, "LSFmod.avsi"); //} if (settings.DoubleNNEDI3 || settings.DoubleNNEDI3Before || ExtraDouble > 0) LoadPluginDll(Script, "nnedi3.dll"); if (settings.DoubleNNEDI3Before) { Script.AppendLine("nnedi3_rpow2 (2)"); if (settings.SharpenAfterDouble && (settings.DoubleEEDI3 || (settings.DoubleNNEDI3 || ExtraDouble > 0))) // Script.AppendFormat(@"LSFmod(strength={0}, defaults=""slow"")", settings.SharpenAfterDoubleStrength).AppendLine(); Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(bt=-1, sharpen={0}, ncpu={1})", (double)settings.SharpenAfterDoubleStrength / 100, CPU).AppendLine(); } if (settings.DoubleEEDI3) { LoadPluginDll(Script, "eedi3.dll"); Script.AppendLine("eedi3_rpow2 (2)"); if (settings.SharpenAfterDouble && (settings.DoubleNNEDI3 || ExtraDouble > 0)) // Script.AppendFormat(@"LSFmod(strength={0}, defaults=""slow"")", settings.SharpenAfterDoubleStrength).AppendLine(); Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(bt=-1, sharpen={0}, ncpu={1})", (double)settings.SharpenAfterDoubleStrength / 100, CPU).AppendLine(); } if (settings.DoubleNNEDI3 || ExtraDouble > 0) { Script.AppendFormat("nnedi3_rpow2 ({0})", (settings.DoubleNNEDI3 ? 2 : 0) + ExtraDouble).AppendLine(); } if (settings.Resize || settings.SourceAspectRatio != 1 || CropAfter) { // Calculate width for resize. if (!settings.Resize) // If pixels are not square, we must always resize to preserve aspect ratio. settings.ResizeHeight = settings.SourceHeight.Value * ScaleFactor; int CropHeight = ((settings.SourceHeight.Value - CropSourceTop - CropSourceBottom) * ScaleFactor); int CropWidth = ((settings.SourceWidth.Value - CropSourceLeft - CropSourceRight) * ScaleFactor); if (CropAfter) { CropHeight = CropHeight - CropAfterTop - CropAfterBottom; CropWidth = CropWidth - CropAfterLeft - CropAfterRight; } int ResizeWidth = (int)Math.Round((double)CropWidth * settings.SourceAspectRatio / CropHeight * settings.ResizeHeight / 4) * 4; if (CropAfter) { Script.AppendFormat("Spline36Resize({0}, {1}, {2}, {3}, -{4}, -{5})", ResizeWidth, settings.ResizeHeight, CropAfterLeft, CropAfterTop, CropAfterRight, CropAfterBottom).AppendLine(); } else { Script.AppendFormat("Spline36Resize({0}, {1})", ResizeWidth, settings.ResizeHeight).AppendLine(); } } if (settings.IncreaseFrameRate) { LoadPluginDll(Script, "svpflow1.dll"); LoadPluginDll(Script, "svpflow2.dll"); LoadPluginAvsi(Script, "InterFrame2.avsi"); if (settings.IncreaseFrameRateValue == FrameRateModeEnum.Double) Script.AppendFormat(@"InterFrame(Cores={0}, Tuning=""Smooth"", FrameDouble=true{1})", CPU, Settings.SavedFile.EnableMadVR ? ", GPU=true" : "").AppendLine(); else { int NewNum = 0; int NewDen = 0; if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps30) { NewNum = 30000; NewDen = 1001; } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps60) { NewNum = 60000; NewDen = 1001; } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps120) { NewNum = 120000; NewDen = 1001; } Script.AppendFormat(@"InterFrame(Cores={0}, Tuning=""Smooth"", NewNum={1}, NewDen={2}{3})", CPU, NewNum, NewDen, Settings.SavedFile.EnableMadVR ? ", GPU=true" : "").AppendLine(); } } if (settings.SharpenFinal) // Script.AppendFormat(@"LSFmod(strength={0}, defaults=""slow"")", settings.SharpenFinalStrength).AppendLine(); Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(bt=-1, sharpen={0}, ncpu={1})", (double)settings.SharpenFinalStrength / 100, CPU).AppendLine(); if (preview && (settings.Crop)) Script.AppendLine("AddBorders(2, 2, 2, 2, $FFFFFF)"); if (preview) Script.AppendLine("ConvertToRGB32()"); if (multiThreaded) { if (AviSynthPlus) Script.AppendLine("Prefetch(4)"); else Script.AppendLine("Distributor()"); } return Script.ToString(); }
/// <summary> /// Tracks the process that will be run into a MediaEncoderSettings object. /// </summary> /// <param name="options">The options object used to track process status.</param> /// <param name="settings">The settings object that will store the process reference.</param> /// <returns>The options object.</returns> public static ProcessStartOptions TrackProcess(this ProcessStartOptions options, MediaEncoderSettings settings) { options.Started += (sender, e) => { if (settings.Processes == null) { settings.Processes = new List <FFmpegProcess>(); } settings.Processes.Add(e.Process); e.Process.Completed += (sender2, e2) => { settings.CompletionStatus = e2.Status; settings.Processes.Remove(e.Process); }; }; return(options); }
private EncodingCompletedEventArgs GetEncodingResults(MediaEncoderSettings settings, string finalFile, DateTime? startTime) { // Create encoding result object. EncodingCompletedEventArgs Result = null; if (File.Exists(finalFile)) { Result = new EncodingCompletedEventArgs(); Result.OldFileName = settings.FileName; Result.NewFileName = settings.FinalFile.Substring(Settings.NaturalGroundingFolder.Length); if (startTime.HasValue) Result.EncodingTime = DateTime.Now - startTime.Value; FileInfo FinalFileInfo = new FileInfo(finalFile); Result.NewFileSize = FinalFileInfo.Length; FinalFileInfo = new FileInfo(Settings.NaturalGroundingFolder + settings.FileName); Result.OldFileSize = FinalFileInfo.Length; Result.Settings = settings; } return Result; }
public AviSynthScriptBuilder GenerateVideoScript(MediaEncoderSettings settings, string inputFile, bool preview, bool multiThreaded) { int CPU = Environment.ProcessorCount; if (CPU <= 1) multiThreaded = false; bool AviSynthPlus = (Settings.EncoderAviSynthVersion == AviSynthVersion.AviSynthPlus); // multiThreaded = true; settings.CalculateSize(); // Calculate encoding and final frame rates. double ChangeSpeedValue = settings.ChangeSpeed ? (double)settings.ChangeSpeedValue / 100 : 1; double FrameRateBefore = settings.SourceFrameRate.Value * ChangeSpeedValue; // Generate video script. AviSynthScriptBuilder Script = new AviSynthScriptBuilder(); bool IsYV24 = false; Script.AppendLine(); // After clean-up, this adds a line after LoadPlugin commands. Script.AddPluginPath(); if (multiThreaded) { // Script.AppendLine("Setmemorymax(1500)"); if (AviSynthPlus) { Script.LoadPluginAvsi("AviSynthMT.avsi"); //Script.AppendLine(@"SetFilterMTMode(""DEFAULT_MT_MODE"",2)"); //Script.AppendLine(@"SetFilterMTMode(""LWLibavVideoSource"",3)"); //Script.AppendLine(@"SetFilterMTMode(""LWLibavAudioSource"",3)"); //if (settings.Denoise1) // Script.AppendLine(@"SetFilterMTMode(""KNLMeansCL"",3)"); } else { Script.AppendLine("SetMTMode(3,{0})", CPU); } } if (settings.ConvertToAvi || inputFile.ToLower().EndsWith(".avi")) Script.OpenAvi(inputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat)); else Script.OpenDirect(inputFile, null, !string.IsNullOrEmpty(settings.SourceAudioFormat), 1); if (FrameRateBefore != settings.SourceFrameRate) Script.AppendLine(CultureInfo.InvariantCulture, "AssumeFPS({0}, true)", FrameRateBefore); if (settings.Trim) { Script.AppendLine("Trim({0}, {1})", (settings.TrimStart ?? 0) > 0 ? (int)(settings.TrimStart.Value * settings.SourceFrameRate.Value) : 0, (settings.TrimEnd ?? 0) > 0 && !preview ? (int)(settings.TrimEnd.Value * settings.SourceFrameRate.Value) : 0); } if (settings.CropSource.HasValue) { Script.AppendLine("Crop({0}, {1}, -{2}, -{3})", settings.CropSource.Left, settings.CropSource.Top, settings.CropSource.Right, settings.CropSource.Bottom); } if (settings.Denoise1) { if (GpuSupport == SupportedOpenClVersion.v12) Script.LoadPluginDll("KNLMeansCL.dll"); else Script.LoadPluginDll("KNLMeansCL-6.11.dll"); Script.AppendLine("ConvertToYV24()"); IsYV24 = true; if (multiThreaded && !AviSynthPlus) Script.AppendLine("SetMTMode(5)"); Script.AppendLine(CultureInfo.InvariantCulture, @"KNLMeansCL(D=1, A=2, h={0}, cmode=true, device_type=""{1}""{2})", ((double)settings.Denoise1Strength / 10).ToString(CultureInfo.InvariantCulture), GpuSupport != SupportedOpenClVersion.None ? "GPU" : "CPU", GpuSupport != SupportedOpenClVersion.None ? ", device_id=" + Settings.SavedFile.GraphicDeviceId.ToString() : ""); } if (multiThreaded && !AviSynthPlus) Script.AppendLine("SetMTMode(2)"); if (settings.FrameDouble > 0 || settings.SourceColorMatrix == ColorMatrix.Rec601) { Script.LoadPluginDll("Shaders\\Shader.dll"); Script.LoadPluginAvsi("Shaders\\Shader.avsi"); } bool HasNoShader = (!settings.SuperRes && settings.UpscaleMethod == UpscaleMethods.NNedi3 && settings.DownscaleMethod == DownscaleMethods.Bicubic); if (settings.SourceColorMatrix == ColorMatrix.Rec601 && settings.FrameDouble == 0 || HasNoShader) { Script.AppendLine("ColorMatrixShader(MatrixIn=\"601\")"); } if (settings.Denoise2) { Script.LoadPluginDll("FFT3DFilter.dll"); Script.AppendLine(CultureInfo.InvariantCulture, @"fft3dfilter(sigma={0}, bt=5, bw=48, bh=48, ow=24, oh=24, sharpen={1})", ((double)settings.Denoise2Strength / 10).ToString(CultureInfo.InvariantCulture), (double)settings.Denoise2Sharpen / 100); } if (settings.FrameDouble > 0) { string FinalSize = string.Format("fWidth={0}, fHeight={1}", settings.OutputWidth + settings.CropAfter.Left + settings.CropAfter.Right, settings.OutputHeight + settings.CropAfter.Top + settings.CropAfter.Bottom); string FinalResize = FinalSize; if (settings.DownscaleMethod == DownscaleMethods.SSim) FinalResize += string.Format(@", fKernel=""SSim"", fB={0}{1}", settings.SSimStrength / 100, settings.SSimSoft ? ", fC=1" : ""); else // DownscaleMethod == Bicubic FinalResize += string.Format(@", fKernel=""Bicubic"", fB=0, fC=.75"); bool IsLastDouble = false; if (settings.UpscaleMethod == UpscaleMethods.NNedi3) { if (IsYV24) { Script.AppendLine("ConvertToYV12()"); IsYV24 = false; } Script.LoadPluginDll("nnedi3.dll"); //Script.LoadPluginDll("FTurn.dll"); Script.LoadPluginAvsi("edi_rpow2.avsi"); for (int i = 0; i < settings.FrameDouble; i++) { IsLastDouble = i == settings.FrameDouble - 1; string DoubleScript = string.Format("edi_rpow2(2, nns=4, {0}, Threads=2)", IsLastDouble && settings.DownscaleMethod == DownscaleMethods.Bicubic ? @"cshift=""Bicubic"", a1=0, a2=.75, " + FinalSize : @"cshift=""Spline16Resize"""); if (settings.SuperRes) { Script.AppendLine(CultureInfo.InvariantCulture, @"SuperRes({0}, {1}, {2}, """"""{3}""""""{4}{5})", settings.SuperRes3Passes ? (i == 0 && settings.FrameDouble > 1 ? 5 : 3) : 2, settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f, DoubleScript, i == 0 && settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "", IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim ? ", " + FinalResize : ""); } else { Script.AppendLine(DoubleScript); if (IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim) { Script.AppendLine("SSimDownscaler({0}{1})", FinalResize.Replace(" f", " ").Replace("fW", "W"), // Use same string as FinalResize but remove 'f' parameter sufix. settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : ""); } } if (i == 0 && settings.IncreaseFrameRate) ApplyInterFrame(Script, settings, CPU); } } else { // UpscaleMethod == SuperXBR for (int i = 0; i < settings.FrameDouble; i++) { IsLastDouble = i == settings.FrameDouble - 1; if (settings.SuperRes) { Script.AppendLine(CultureInfo.InvariantCulture, @"SuperResXBR({0}, {1}, {2}, XbrStr={3}, XbrSharp={4}{5}{6})", settings.SuperRes3Passes ? (i == 0 && settings.FrameDouble > 1 ? 5 : 3) : 2, settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f, settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f, i == 0 && settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "", IsLastDouble ? ", " + FinalResize : ""); } else { Script.AppendLine("SuperXBR(Str={0}, Sharp={1}{2}{3})", settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f, i == 0 && settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "", IsLastDouble ? ", " + FinalResize : ""); } if (i == 0 && settings.IncreaseFrameRate) { if (IsYV24) { Script.AppendLine("ConvertToYV12()"); IsYV24 = false; } ApplyInterFrame(Script, settings, CPU); } } } } if (IsYV24) { Script.AppendLine("ConvertToYV12()"); IsYV24 = false; } if (settings.FrameDouble == 0 && settings.IncreaseFrameRate) ApplyInterFrame(Script, settings, CPU); Script.LoadPluginAvsi("ResizeX.avsi"); if (settings.CropAfter.HasValue || settings.FrameDouble == 0) { bool ApplyResize = settings.FrameDouble == 0 || HasNoShader; string CropFormat = "ResizeX"; CropFormat += settings.CropAfter.HasValue ? "({0}, {1}, {2}, {3}, -{4}, -{5}{6})" : "({0}, {1}{6})"; Script.AppendLine(CropFormat, settings.OutputWidth, settings.OutputHeight, settings.CropAfter.Left, settings.CropAfter.Top, settings.CropAfter.Right, settings.CropAfter.Bottom, ApplyResize ? @", kernel=""Bicubic"", a1=0, a2=.75" : ""); } if (preview) { if (settings.Crop) Script.AppendLine("AddBorders(2, 2, 2, 2, $FFFFFF)"); Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")"); } if (multiThreaded && AviSynthPlus) Script.AppendLine("Prefetch({0})", CPU); Script.Cleanup(); return Script; }
private EncodingCompletedEventArgs FinalizeEncoding(MediaEncoderSettings settings, DateTime? startTime) { EncodingCompletedEventArgs Result = null; if (File.Exists(settings.OutputFile)) { // Muxe video with audio. string FinalFile = GetNextAvailableFileName(settings.FinalFile); if (!settings.IgnoreAudio) FfmpegBusiness.JoinAudioVideo(settings.OutputFile, Settings.NaturalGroundingFolder + settings.FileName, FinalFile, true); else FfmpegBusiness.JoinAudioVideo(settings.OutputFile, null, FinalFile, true); Result = GetEncodingResults(settings, FinalFile, startTime); } return Result; }
private EncodingCompletedEventArgs FinalizeEncoding(MediaEncoderSettings settings, DateTime? startTime) { EncodingCompletedEventArgs Result = null; if (File.Exists(settings.OutputFile) || (settings.VideoCodec == VideoCodecs.Copy && File.Exists(settings.AudioFileAac))) { // Muxe video with audio. string FinalFile = GetNextAvailableFileName(settings.FinalFile); string VideoFile = null; if (settings.VideoCodec == VideoCodecs.Copy) VideoFile = Settings.NaturalGroundingFolder + settings.FileName; else VideoFile = settings.OutputFile; string AudioFile = null; if (settings.AudioAction == AudioActions.Copy) AudioFile = Settings.NaturalGroundingFolder + settings.FileName; else if (settings.AudioAction == AudioActions.Encode) AudioFile = settings.AudioFileAac; FfmpegBusiness.JoinAudioVideo(VideoFile, AudioFile, FinalFile, true); Result = GetEncodingResults(settings, FinalFile, startTime); } return Result; }
private EncodingCompletedEventArgs EncodeFileThread(MediaEncoderSettings settings) { EncodingCompletedEventArgs Result = null; DateTime StartTime = DateTime.Now; FfmpegBusiness.ConvertToH264(settings.ScriptFile, settings.OutputFile, settings.EncodeQuality); Result = FinalizeEncoding(settings, StartTime); return Result; }
private async Task WaitEncodeProcessAsync(MediaEncoderSettings settings, Process jobProcess) { ProcessingQueue.Add(Path.GetFileNameWithoutExtension(settings.FileName)); EncodingCompletedEventArgs EncodingResult; if (EncoderTask == null) EncoderTask = Task.Run(() => { jobProcess.WaitForExit(); return FinalizeEncoding(settings, DateTime.Now); }); else EncoderTask = EncoderTask.ContinueWith((prevTask) => { jobProcess.WaitForExit(); return FinalizeEncoding(settings, DateTime.Now); }); EncodingResult = await EncoderTask; ProcessingQueue.RemoveAt(0); if (EncodingResult != null && EncodingCompleted != null) EncodingCompleted(this, EncodingResult); }
private async Task StartEncodeFileAsync(MediaEncoderSettings settings) { ProcessingQueue.Add(Path.GetFileNameWithoutExtension(settings.FileName)); EncodingCompletedEventArgs EncodingResult; if (EncoderTask == null) EncoderTask = Task.Run(() => EncodeFileThread(settings)); else EncoderTask = EncoderTask.ContinueWith((prevTask) => EncodeFileThread(settings)); EncodingResult = await EncoderTask; ProcessingQueue.RemoveAt(0); if (EncodingResult != null && EncodingCompleted != null) EncodingCompleted(this, EncodingResult); }
/// <summary> /// Generates a script for Deshaker prescan. This is a much simplified version of the full script that will execute faster. /// </summary> public static string GenerateDeshakerScript(MediaEncoderSettings settings, string inputFile, int segment, long frameStart, long frameEnd) { bool MultiProcesses = false; // Calculate encoding and final frame rates. double ChangeSpeedValue = settings.ChangeSpeed ? (double)settings.ChangeSpeedValue / 100 : 1; double FrameRateBefore = settings.SourceFrameRate.Value * ChangeSpeedValue; // Generate video script. AviSynthScriptBuilder Script = new AviSynthScriptBuilder(); Script.AddPluginPath(); Script.LoadPluginDll("VDubFilter.dll"); Script.AppendLine(@"LoadVirtualDubPlugin(P+""deshaker.vdf"", ""deshaker"", preroll=0)"); if (settings.ConvertToAvi || inputFile.ToLower().EndsWith(".avi")) { Script.OpenAvi(inputFile, false); } else { Script.OpenDirect(inputFile, false); } if (FrameRateBefore != settings.SourceFrameRate) { Script.AppendLine(CultureInfo.InvariantCulture, "AssumeFPS({0}, true)", FrameRateBefore); } if (settings.Trim) { Script.AppendLine("Trim({0}, {1})", (settings.TrimStart ?? 0) > 0 ? (int)(settings.TrimStart.Value * settings.SourceFrameRate.Value) : 0, (settings.TrimEnd ?? 0) > 0 ? (int)(settings.TrimEnd.Value * settings.SourceFrameRate.Value) : 0); } if (settings.CropSource.HasValue) { Script.AppendLine("Crop({0}, {1}, -{2}, -{3})", settings.CropSource.Left, settings.CropSource.Top, settings.CropSource.Right, settings.CropSource.Bottom); } // Generate script for a segment. if (frameStart > 0 || frameEnd > 0) { Script.AppendLine("Trim({0}, {1})", frameStart, frameEnd); } // Resize to the dimention deshaker will run at. if (settings.FrameDouble == 1) { int FinalWidth = settings.OutputWidth.Value + settings.CropAfter.Left + settings.CropAfter.Right; int FinalHeight = settings.OutputHeight + settings.CropAfter.Top + settings.CropAfter.Bottom; Script.AppendLine("BicubicResize({0}, {1})", FinalWidth, FinalHeight); } else if (settings.FrameDouble > 1) { Script.AppendLine("BicubicResize(Width*2, Height*2)"); } // Deshaker requires RGB input. Script.AppendLine(@"ConvertToRGB32(matrix=""{0}"")", settings.SourceColorMatrix == ColorMatrix.Rec601 ? "Rec601" : settings.SourceColorMatrix == ColorMatrix.Pc709 ? "Pc709" : settings.SourceColorMatrix == ColorMatrix.Pc601 ? "Pc601" : "Rec709"); // Generate log file Script.AppendLine(@"deshaker(""{0}"")", settings.DeshakerSettings.ToString(segment)); // FFMPEG will generate an AVI file; make it 8x8 to minimize processing. Script.AppendLine("ConvertToYV12()"); Script.AppendLine("PointResize(64,64)"); if (MultiProcesses) { Script.AppendLine("### prefetch: 0, 0"); Script.AppendLine("### branch: 2"); Script.AppendLine("### ###"); Script.ConvertToMultiProcesses(settings.SourceFrameRate.Value); } return(Script.Script); }
private EncodingCompletedEventArgs EncodeFileThread(MediaEncoderSettings settings) { EncodingCompletedEventArgs Result = null; DateTime StartTime = DateTime.Now; Task<bool> VideoEnc = null; if (settings.VideoCodec != VideoCodecs.Copy) VideoEnc = Task.Run(() => FfmpegBusiness.EncodeH264(settings)); // Encode audio stream with Nero Aac Encoder if (settings.AudioAction == AudioActions.Encode) { Task<bool> AudioEnc = Task.Run(() => EncodeAudio(settings)); if (VideoEnc != null) Task.WaitAll(VideoEnc, AudioEnc); else Task.WaitAll(AudioEnc); } else if (VideoEnc != null) Task.WaitAll(VideoEnc); Result = FinalizeEncoding(settings, StartTime); return Result; }