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);
        }
Пример #3
0
        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();
        }
Пример #17
0
        //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);
        }