public static bool Extract(Job job, Motif motif) { IOHelper.CreateDirectory(JobPathHelper.GetLocalJobAnimatedMotifDiretory(job.Production, motif)); string sourcePath = JobPathHelper.GetLocalJobMotifPath(job, motif); string targetPath = Path.Combine(JobPathHelper.GetLocalJobAnimatedMotifDiretory(job.Production, motif), @"motif_F%04d.tga"); string parameters = "-i " + sourcePath + " " + targetPath; VCProcess process = new VCProcess(job); process.StartInfo.FileName = Settings.LocalFfmpegExePath; process.StartInfo.Arguments = parameters; process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardError = false; process.StartInfo.RedirectStandardOutput = false; process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; process.Execute(); process.WaitForExit(); motif.Frames = Directory.GetFiles(JobPathHelper.GetLocalJobAnimatedMotifDiretory(job.Production, motif), "*.tga").Length; //motif.Extension = ".tga"; return(motif.Frames > 0); }
public static bool MergeChunks(Job job) { if (CheckOutputs(job) == false) { job.ErrorStatus = JobErrorStatus.JES_OUTPUTFILE_COUNT_MISMATCH; return(false); } SavePreviewImage(job); if (job.Production.IsZipProduction) { return(true); } CreateChunklistFile(job); string cmd = "-y -loglevel panic -safe 0 -f concat -i " + JobPathHelper.GetChunkListPath(job) + " -c copy "; cmd += JobPathHelper.GetJobClipPath(job); Encode(job, cmd); return(true); }
private static bool StartRendering(Job job) { string parameters = JobPathHelper.GetDeadlineJobFile(job); parameters += " " + Settings.LocalFusionPluginPath; parameters += " " + JobPathHelper.GetJobCompPath(job); VCProcess process = new VCProcess(job); process.StartInfo.FileName = Settings.LocalDeadlineExePath; process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.Arguments = parameters; process.EnableRaisingEvents = true; process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized; process.Execute(); string output = process.StandardOutput.ReadToEnd(); job.RenderID = RenderIDParser.Parse(output); process.WaitForExit(); process.Close(); return(job.RenderID != null); }
private void WriteComposition() { string path = JobPathHelper.GetJobCompPath(job); job.LogText(string.Format("Saving comp '{0}'", path)); File.WriteAllLines(path, CompLines); }
//Pack Zip File private void PrepareJobForZip() { //Remove trailing digits from output pic (e.g. pic0000.jpg -> pic.jpg) //CAVE! four trailing digits are expected! string sourceDirectory = JobPathHelper.GetLocalJobRenderOutputPathForZip(job); if (!Directory.Exists(sourceDirectory)) { return; } DirectoryInfo dirInfo = new DirectoryInfo(sourceDirectory); FileInfo[] fileInfos = dirInfo.GetFiles(); foreach (FileInfo fileInfo in fileInfos) { string sourceFullName = fileInfo.FullName; string extension = Path.GetExtension(sourceFullName); string dir = Path.GetDirectoryName(sourceFullName); string sourceFileNameWithoutExtension = Path.GetFileNameWithoutExtension(sourceFullName); int len = sourceFileNameWithoutExtension.Length; if (char.IsDigit(sourceFileNameWithoutExtension[len - 4]) && char.IsDigit(sourceFileNameWithoutExtension[len - 1])) { string targetNameWithoutExtension = sourceFileNameWithoutExtension.Substring(0, len - 4); string targetName = Path.Combine(dir, targetNameWithoutExtension + extension); File.Move(sourceFullName, targetName); } } job.Status = JobStatus.JS_ENCODING_DONE; Work(); }
private void CreateCliplistFile() { //create cliplist file StreamWriter writer = new StreamWriter(ProductionPathHelper.GetClipListPath(production), false); writer.WriteLine(@"# cliplist"); FilmOutputFormat largestOutputFormat = production.Film.LargestFilmOutputFormat; //clips for (int i = 0; i < production.JobList.Count; i++) { Job job = production.JobList[i]; if (job.IsDicative) { VerifyDicativeSize(job, largestOutputFormat); writer.WriteLine(CreateDicativeLine(job, largestOutputFormat)); } else { writer.WriteLine("file '" + JobPathHelper.GetJobClipPath(job) + "'"); } } writer.Close(); }
private int ModifyOutputs() { int result = 0; job.OutputExtension = GetOutputExtension(); if (ErrorStatus != JobErrorStatus.JES_NONE) { return(-1); } string outputPath; Dictionary <int, string> loaderFileNameArr = null; if (job.IsZip) { loaderFileNameArr = GetLoaders(); outputPath = JobPathHelper.GetLocalJobRenderOutputPathForZip(job); } else { outputPath = JobPathHelper.GetLocalJobRenderOutputMask(job); } if (SetValueInTool("OutputClips", "", outputPath)) { result++; } int saverResult = 0; for (int i = 0; i < saverCount; i++) { bool subResult = false; if (job.IsZip) { subResult = SetValueInTool(string.Format("Saver{0}", i + 1), "Filename", Path.Combine(outputPath, loaderFileNameArr[i + 1]), false); } else { subResult = SetValueInTool(string.Format("Saver{0}", i + 1), "Filename", outputPath, false); } if (subResult == true) { saverResult++; } } if (saverResult > 0) { result++; } return(result); }
//transfers a motif from remote user account to local filesystem public TransferPacket(Job job, Motif motif) { ItemID = motif.ID; Parent = motif; SourcePath = Settings.FtpUserSubdirectory + "/" + job.AccountID + "/motifs/" + motif.DownloadName; TargetPath = JobPathHelper.GetLocalJobMotifPath(job, motif); Type = TransferType.DownloadMotif; LoginData = Settings.MasterLogin; }
private void RenameToProduct() { string sourceFile = JobPathHelper.GetJobClipPath(production.JobList[0]); string targetFile = ProductionPathHelper.GetProductMp4Path(production.JobList[0].ProductID); IOHelper.CreateDirectory(Path.GetDirectoryName(targetFile)); System.IO.File.Copy(sourceFile, targetFile, true); FireSuccessEvent(); }
private void CreateDirectories() { bool success = true; List <string> directoryPaths = new List <string>(); // main production folder (e.g. "render_temp\productions\virtualcampaign\12345") directoryPaths.Add(ProductionPathHelper.GetLocalProductionDirectory(production)); //motif folder (e.g. "render_temp\productions\virtualcampaign\12345\motifs") directoryPaths.Add(ProductionPathHelper.GetProductionMotifDirectory(production)); //preview output folder if (production.IsPreview == false) { //hash output folder directoryPaths.Add(ProductionPathHelper.GetLocalProductionHashDirectory(production)); //production preview directory directoryPaths.Add(ProductionPathHelper.GetLocalProductionPreviewDirectory(production)); } else { //product preview directory directoryPaths.Add(ProductionPathHelper.GetLocalProductPreviewProductionDirectory(production)); } //folders for each clip foreach (Job job in production.JobList) { //main clip folder (e.g. "render_temp\productions\virtualcampaign\12345\54321") directoryPaths.Add(JobPathHelper.GetLocalJobDirectory(job)); directoryPaths.Add(JobPathHelper.GetLocalJobRenderOutputDirectory(job)); if (job.IsZip) { //subfolder for each zip production directoryPaths.Add(JobPathHelper.GetLocalJobRenderOutputPathForZip(job)); } } //create all folders foreach (string directoryPath in directoryPaths) { success = success && IOHelper.CreateDirectory(directoryPath); if (!success) { production.ErrorStatus = ProductionErrorStatus.PES_CREATE_DIRECTORIES; return; } } production.Status = ProductionStatus.PS_START_JOBS; Work(); }
private int ReadComposition() { job.LogText("Reading composition file " + JobPathHelper.GetProductCompositionPath(job)); if (!File.Exists(JobPathHelper.GetProductCompositionPath(job))) { ErrorStatus = JobErrorStatus.JES_COMP_MISSING; return(-1); } CompLines = File.ReadAllLines(JobPathHelper.GetProductCompositionPath(job)); return(CompLines.Select(item => Regex.Matches(item, " = Saver {").Count).Sum()); }
private static bool CheckOutputs(Job job) { return(true); if (job.Production.IsZipProduction) { return(true); } int outputCount = Directory.GetFiles(JobPathHelper.GetLocalJobRenderOutputDirectory(job), "*" + job.OutputExtension).Length; return(outputCount > 1 && outputCount == job.FrameCount); }
public static void EncodeLargestChunk(RenderChunkStatus LargestChunk) { if (IsBusy) { return; } IsBusy = true; bool isZipProduction = LargestChunk.Job.Production.IsZipProduction; if (isZipProduction == false) { for (int i = LargestChunk.StartIndex; i <= LargestChunk.EndIndex; i++) { LargestChunk.Job.RenderChunkStatusList.First(item => item.StartIndex == i).Status = 6; } string cmd = ""; cmd += "-hwaccel cuvid"; cmd += " -y -loglevel panic"; cmd += " -start_number " + LargestChunk.StartFrame; cmd += " -f image2"; cmd += " -i " + JobPathHelper.GetLocalJobRenderOutputFileMask(LargestChunk.Job); cmd += " -vframes " + (LargestChunk.EndFrame - LargestChunk.StartFrame + 1); cmd += " -pix_fmt yuv420p"; if (Settings.UseCuda) { cmd += " -c:v h264_nvenc"; } else { cmd += " -c:v libx264"; } cmd += " -profile:v high -qp 19 -preset fast "; cmd += JobPathHelper.GetRenderChunkPath(LargestChunk); Encode(LargestChunk.Job, cmd); } for (int i = LargestChunk.StartIndex; i <= LargestChunk.EndIndex; i++) { LargestChunk.Job.RenderChunkStatusList.First(item => item.StartIndex == i).Status = 7; } IsBusy = false; }
public static bool Transcode(Job job, Motif motif) { bool result = true; MagickReadSettings settings = new MagickReadSettings(); // Settings the density to 300 dpi will create an image with a better quality settings.Density = new Density(300, 300); string motifPath = JobPathHelper.GetLocalJobMotifPath(job, motif); MagickImage image = new MagickImage(); try { image.Read(motifPath, settings); } catch (Exception ex) { job.LogText("Ghostscript not installed."); return(false); } if ((image.Format != MagickFormat.Jpg && image.Format != MagickFormat.Jpeg) || image.ColorSpace != ColorSpace.sRGB || image.Width > 2000 || image.Height > 2000) { job.LogText(string.Format("Transcoding image from format {0}, colorspace {1} to Jpg and sRGB", image.Format, image.ColorSpace)); image.Format = MagickFormat.Jpg; image.ColorSpace = ColorSpace.sRGB; motif.OriginalExtension = motif.Extension; motif.Extension = ".jpg"; if (image.Width > 2000 || image.Height > 2000) { job.LogText(string.Format("Resizing image from {0}x{1} to 1024x{2}", image.Width, image.Height, (1024f / 2000f) * image.Height)); image.Resize(1024, 0); } string motifOutputPath = JobPathHelper.GetLocalJobMotifPath(job, motif); image.Write(motifOutputPath); return(System.IO.File.Exists(motifOutputPath)); } return(result); }
//create job statistics data and send to server private void WriteStatistics() { if (job.FrameCount < 2) { return; } float totalSeconds = 0; int totalFrames = 0; float totalProcessorFactor = 0; foreach (RenderChunkStatus renderChunk in job.RenderChunkStatusList) { TimeSpan renderTimeSpan = renderChunk.RenderEndDate - renderChunk.RenderStartDate; float seconds = (float)Math.Round(renderTimeSpan.TotalSeconds, 2); totalSeconds += seconds; int frames = (renderChunk.EndFrame - renderChunk.StartFrame + 1); totalFrames += frames; totalProcessorFactor += ((float)frames / (float)job.FrameCount) * renderChunk.Processors * renderChunk.ProcessorSpeed; } float totalStandardizedTime = (float)Math.Round(totalSeconds * totalProcessorFactor / (float)job.FrameCount, 2); string filename = JobPathHelper.GetJobClipPath(job); FileInfo fileInfo = new FileInfo(filename); long fileSize = fileInfo.Length; if (job.Production.IsZipProduction) { fileSize /= job.Production.JobList.Count; } Dictionary <string, string> param = new Dictionary <string, string> { { "productID", job.ProductID.ToString() }, { "seconds", ((decimal)totalSeconds).ToString().Replace(",", ".") }, { "processorFactor", ((decimal)totalProcessorFactor).ToString().Replace(",", ".") }, { "standardizedComplexity", ((decimal)totalStandardizedTime).ToString().Replace(",", ".") }, { "filesize", fileSize.ToString() } }; JobRepository.UpdateProductStatistics(param); }
private static void CreateChunklistFile(Job job) { //get chunk files string[] chunkFiles = Directory.GetFiles(JobPathHelper.GetLocalJobDirectory(job), "clip_" + job.Position + "_chunk_*.mp4"); chunkFiles = chunkFiles.OrderBy(x => x).ToArray(); //create cliplist file string clipListFilename = JobPathHelper.GetChunkListPath(job); StreamWriter writer = new StreamWriter(clipListFilename, false); writer.WriteLine(@"# chunklist"); foreach (string chunkFile in chunkFiles) { writer.WriteLine("file '" + chunkFile + "'"); } writer.Close(); }
//log text to visual log, console and log file public void LogText(string text) { DateTime time = DateTime.Now; string logText = logText = string.Format("[{0}]: {1}", time, text); logLines.Add(logText); Console.WriteLine(logText); string logfilePath = null; if (parent is Job) { logfilePath = JobPathHelper.GetLogFilePath(parent as Job); } else if (parent is Production) { logfilePath = ProductionPathHelper.GetLogFilePath(parent as Production); } else if (parent is Motif) { logfilePath = JobPathHelper.GetLogFilePath((parent as Motif).Job); } if (logfilePath == null) { return; } IOHelper.CreateDirectory(System.IO.Path.GetDirectoryName(logfilePath)); if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(logfilePath))) { Application.Current.Dispatcher.Invoke(new Action(() => System.IO.File.AppendAllText(logfilePath, string.Format("{0}{1}", logText, Environment.NewLine)) )); } RaisePropertyChangedEvent("Log"); }
public static bool WriteJobFile(Job job) { string renderFilename = JobPathHelper.GetDeadlineJobFile(job); StreamWriter jobFile = new StreamWriter(renderFilename); jobFile.WriteLine("Plugin=FusionCmd"); jobFile.WriteLine("Frames={0}-{1}", job.InFrame, job.OutFrame); job.RenderStartTime = DateTime.Now.Ticks; jobFile.WriteLine(string.Format("Name={0} [{1}]", job.ID, job.RenderStartTime)); jobFile.WriteLine("UserName=virtualcampaign"); if (job.Production.Is4K) { jobFile.WriteLine("Group=vc_360"); } else { jobFile.WriteLine("Group=vc"); } jobFile.WriteLine("ArchiveOnComplete=false"); jobFile.WriteLine("OnJobComplete=Nothing"); jobFile.WriteLine("Priority=" + Convert.ToString(job.Production.Priority)); jobFile.WriteLine("Comment=#" + job.FrameCount.ToString()); if (job.FrameCount <= 1) { jobFile.WriteLine("ChunkSize=1"); } else { jobFile.WriteLine("ChunkSize=" + Settings.RenderChunkSize); } jobFile.WriteLine("ExtraInfo1=" + job.ProductID); jobFile.WriteLine("OverrideJobFailureDetection=true"); jobFile.WriteLine("FailureDetectionJobErrors=10"); jobFile.Close(); return(File.Exists(renderFilename)); }
private static bool SavePreviewImage(Job job) { if (job.IsDicative) { return(true); } string directoryName; if (job.Production.IsPreview == false) { directoryName = ProductionPathHelper.GetLocalProductionPreviewDirectory(job.Production); } else { directoryName = ProductionPathHelper.GetLocalProductPreviewProductionDirectory(job.Production); } string fileName; if (job.Production.IsZipProduction == false) { job.PreviewFrame = 20; fileName = Path.Combine(new string[] { JobPathHelper.GetLocalJobRenderOutputDirectory(job), "F" + String.Format("{0:D4}", (job.PreviewFrame + job.InFrame)) + job.OutputExtension }); } else { fileName = Directory.GetFiles(JobPathHelper.GetLocalJobRenderOutputPathForZip(job))[0]; } Dictionary <string, string> previewPicDict = new Dictionary <string, string> { { "hdpi.jpg", "640:360" }, { "mdpi.jpg", "320:180" }, { "ldpi.jpg", "160:90" } }; string cmd = " -y -i " + fileName; foreach (KeyValuePair <string, string> kv in previewPicDict) { if (job.Production.IsPreview == false) { cmd += string.Format(" -vf scale={0} {1}", kv.Value, Path.Combine(directoryName, string.Format("film_{0}_preview_{1}", job.Production.FilmID, kv.Key))); } else { cmd += string.Format(" -vf scale={0} {1}", kv.Value, Path.Combine(directoryName, string.Format("{0:0000}_{1}", job.ProductID, kv.Key))); } } //create previews for krpano productions if (job.Production.ContainsPano) { directoryName = ProductionPathHelper.GetLocalProductionHashDirectory(job.Production); IOHelper.CreateDirectory(directoryName); FilmOutputFormat outputFormat = job.Production.Film.FilmOutputFormatList.First(item => item.Name.Contains("K360")); //full size string scale = outputFormat.Width + ":" + outputFormat.Height; cmd += string.Format(" -vf scale={0} {1}", scale, Path.Combine(directoryName, string.Format("film_{0}_preview_{1}.jpg", job.Production.FilmID, scale.Replace(":", "x")))); //quarter size scale = (int)Math.Round(outputFormat.Width / 2d) + ":" + (int)Math.Round(outputFormat.Height / 2d); cmd += string.Format(" -vf scale={0} {1}", scale, Path.Combine(directoryName, string.Format("film_{0}_preview_{1}.jpg", job.Production.FilmID, scale.Replace(":", "x")))); } Encode(job, cmd); return(true); }