/// <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 about.</param> /// <param name="options">The options that control the behaviors of the process.</param> /// <returns>The frame count.</returns> public static long GetFrameCount(string source, ProcessStartOptions options) { if (!File.Exists(source)) { return(0); } string TempScriptBase = Path.ChangeExtension(source, null); string TempScript = PathManager.GetTempFile("avs"); string TempResult = Path.ChangeExtension(TempScript, "txt"); AviSynthScriptBuilder Script; if (source.ToLower().EndsWith(".avs")) { // Read source script and remove MT. Also remove Deshaker if present. string FileContent = File.ReadAllText(source); FileContent.Replace(Environment.NewLine + "Deshaker", Environment.NewLine + "#Deshaker"); Script = new AviSynthScriptBuilder(FileContent); Script.RemoveMT(); } else { // Generate script to read media file. Script = new AviSynthScriptBuilder(); Script.AddPluginPath(); Script.OpenDirect(source, false); } // Get frame count. Script.AppendLine(); Script.AppendLine(@"WriteFileStart(""{0}"", ""FrameRate""{1}""Framecount"")", TempResult, @", """""" "","" """""", "); Script.AppendLine("Trim(0,-1)"); Script.WriteToFile(TempScript); // Run script. FFmpegProcess Worker = new FFmpegProcess(options); Worker.RunAvisynth(TempScript); // Read frame count long Result = 0; if (File.Exists(TempResult)) { string FileString = File.ReadAllText(TempResult); string[] FileValues = FileString.Split(','); try { //Result.FrameRate = float.Parse(FileValues[0], CultureInfo.InvariantCulture); Result = int.Parse(FileValues[1]); } catch { } } // Delete temp files. File.Delete(TempScript); File.Delete(TempResult); return(Result); }
/// <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); }
/// <summary> /// Returns whether the GPU supports the latest version of KNLMeans with OpenCL 1.2 /// </summary> /// <param name="supports11">If true, it will instead test whether the GPU supports OpenCL 1.1</param> /// <returns>True if OpenCL is supported.</returns> private static bool GpuSupportsOpenCL(bool version12) { string TempScript = Path.Combine(Path.GetTempPath(), "GpuSupportsOpenCL.avs"); string TempResult = Path.Combine(Path.GetTempPath(), "GpuSupportsOpenCL.txt"); AviSynthScriptBuilder Script = new AviSynthScriptBuilder(); Script.AddPluginPath(); Script.LoadPluginDll(string.Format("KNLMeansCL{0}.dll", version12 ? "" : "-6.11")); Script.AppendLine(@"colorbars(pixel_type = ""yv12"").killaudio().trim(1, 1)"); Script.AppendLine("Result = true"); Script.AppendLine("try {"); Script.AppendLine(@"KNLMeansCL(device_type=""GPU"")"); Script.AppendLine("} catch(error_msg) {"); Script.AppendLine("Result = false"); Script.AppendLine("}"); Script.AppendLine(@"WriteFileStart(""{0}"", string(Result))", TempResult); Script.WriteToFile(TempScript); // Run script. FFmpegProcess Worker = new FFmpegProcess(); Worker.Options.Timeout = TimeSpan.FromSeconds(10); Worker.Options.DisplayMode = FFmpegDisplayMode.ErrorOnly; Worker.RunAvisynth(TempScript); // Read frame count bool Result = false; if (File.Exists(TempResult)) { string FileString = File.ReadAllText(TempResult); try { Result = bool.Parse(FileString.TrimEnd()); } catch { Result = false; } } // Delete temp files. File.Delete(TempScript); File.Delete(TempResult); return(Result); }
/// <summary> /// Calculates auto-crop coordinates for specified video script. /// </summary> /// <param name="filePath">The script to analyze.</param> /// <param name="sourceWidth">The width of the source video.</param> /// <param name="sourceHeight">The height of the source video.</param> /// <param name="options">The options that control the behaviors of the process.</param> /// <returns>The auto-crop coordinates.</returns> public static Rect GetAutoCropRect(string filePath, int sourceWidth, int sourceHeight, ProcessStartOptions options) { string TempScript = PathManager.GetTempFile(".avs"); string TempResult = Path.ChangeExtension(TempScript, ".txt"); // Create script to get auto-crop coordinates AviSynthScriptBuilder Script = new AviSynthScriptBuilder(); Script.AddPluginPath(); Script.OpenDirect(filePath, false); Script.LoadPluginDll("RoboCrop26.dll"); Script.AppendLine(@"RoboCrop(LogFn=""{0}"")", Script.GetAsciiPath(TempResult)); Script.AppendLine("Trim(0,-1)"); Script.WriteToFile(TempScript); // Run script. FFmpegProcess Worker = new FFmpegProcess(options); Worker.RunAvisynth(TempScript); // Read auto crop coordinates Rect Result = new Rect(); if (File.Exists(TempResult)) { string[] Values = File.ReadAllText(TempResult).Split(' '); if (Values.Length >= 13) { Result.Left = Math.Max(int.Parse(Values[10]), 0); Result.Top = Math.Max(int.Parse(Values[11]), 0); Result.Right = Math.Max(sourceWidth - int.Parse(Values[12]), 0); Result.Bottom = Math.Max(sourceHeight - int.Parse(Values[13]), 0); // Make result conservative, we have to visually see a line of black border to know the right dimensions. if (Result.Left > 0) { Result.Left--; } if (Result.Top > 0) { Result.Top--; } if (Result.Right > 0) { Result.Right--; } if (Result.Bottom > 0) { Result.Bottom--; } } } // Delete temp files. Exception LastError = null; for (int i = 0; i < 10; i++) { try { File.Delete(TempScript); File.Delete(TempResult); break; } catch (Exception e) { LastError = e; System.Threading.Thread.Sleep(500); } } if (LastError != null) { throw LastError; } return(Result); }