public static JobChain AddAfter(JobChain other, string type, List<string> files) { CleanupJob j = new CleanupJob(); j.files = files; j.type = type; return new SequentialChain(other, j); }
private void queueVideoButton_Click(object sender, System.EventArgs e) { fileType_SelectedIndexChanged(sender, e); // to select always correct output file extension string settingsError = verifyVideoSettings(); // basic input, logfile and output file settings are okay if (settingsError != null) { MessageBox.Show(settingsError, "Unsupported configuration", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } VideoCodecSettings vSettings = this.CurrentSettings.Clone(); string videoOutput = info.VideoOutput; if ((MainForm.Instance.Settings.UseExternalMuxerX264 || fileType.Text.Equals("MP4")) && (!fileType.Text.StartsWith("RAW") && vSettings.SettingsID.StartsWith("x26"))) { if (vSettings.SettingsID.Equals("x264")) { videoOutput = Path.ChangeExtension(videoOutput, "264"); } else if (vSettings.SettingsID.Equals("x265")) { videoOutput = Path.ChangeExtension(videoOutput, "hevc"); } } JobChain prepareJobs = mainForm.JobUtil.AddVideoJobs(info.VideoInput, videoOutput, this.CurrentSettings.Clone(), info.IntroEndFrame, info.CreditsStartFrame, info.DAR, PrerenderJob, true, info.Zones); if ((MainForm.Instance.Settings.UseExternalMuxerX264 || fileType.Text.Equals("MP4")) && (!fileType.Text.StartsWith("RAW") && vSettings.SettingsID.StartsWith("x26"))) { // create job MuxJob mJob = new MuxJob(); mJob.Input = videoOutput; if (fileType.Text.Equals("MKV")) { mJob.MuxType = MuxerType.MKVMERGE; mJob.Output = Path.ChangeExtension(videoOutput, "mkv"); } else { mJob.MuxType = MuxerType.MP4BOX; mJob.Output = Path.ChangeExtension(videoOutput, "mp4"); } mJob.Settings.MuxAll = true; mJob.Settings.Framerate = decimal.Round((decimal)FrameRate, 3, MidpointRounding.AwayFromZero); mJob.Settings.MuxedInput = mJob.Input; mJob.Settings.MuxedOutput = mJob.Output; mJob.FilesToDelete.Add(videoOutput); // add job to queue prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(mJob)); } mainForm.Jobs.addJobsWithDependencies(prepareJobs, true); }
public static JobChain AddAfter(JobChain other, List <string> files, string strInput) { CleanupJob j = new CleanupJob(); j.files = files; j.Input = strInput; return(new SequentialChain(other, j)); }
public static JobChain AddAfter(JobChain other, List <string> files, string strInput) { CleanupJob j = new CleanupJob(); j.FilesToDelete.AddRange(files); j.Input = strInput; return(new SequentialChain(other, j)); }
public static JobChain AddAfter(JobChain other, string type, List <string> files) { CleanupJob j = new CleanupJob(); j.files = files; j.type = type; return(new SequentialChain(other, j)); }
public LogItem postprocess() { audioFiles = vUtil.getAllDemuxedAudio(job.AudioTracks, job.Output, 8); fillInAudioInformation(); log.LogValue("Desired size", job.PostprocessingProperties.OutputSize); log.LogValue("Split size", job.PostprocessingProperties.Splitting); VideoCodecSettings videoSettings = job.PostprocessingProperties.VideoSettings; string videoOutput = Path.Combine(Path.GetDirectoryName(job.Output), Path.GetFileNameWithoutExtension(job.Output) + "_Video"); string muxedOutput = job.PostprocessingProperties.FinalOutput; //Open the video Dar? dar; string videoInput = openVideo(job.Output, job.PostprocessingProperties.DAR, job.PostprocessingProperties.HorizontalOutputResolution, job.PostprocessingProperties.SignalAR, log, job.PostprocessingProperties.AvsSettings, job.PostprocessingProperties.AutoDeinterlace, videoSettings, out dar); VideoStream myVideo = new VideoStream(); ulong length; double framerate; JobUtil.getInputProperties(out length, out framerate, videoInput); myVideo.Input = videoInput; myVideo.Output = videoOutput; myVideo.NumberOfFrames = length; myVideo.Framerate = (decimal)framerate; myVideo.DAR = dar; myVideo.VideoType = new MuxableType((new VideoEncoderProvider().GetSupportedOutput(videoSettings.EncoderType))[0], videoSettings.Codec); myVideo.Settings = videoSettings; List <string> intermediateFiles = new List <string>(); intermediateFiles.Add(videoInput); intermediateFiles.Add(job.Output); intermediateFiles.AddRange(audioFiles.Values); if (!string.IsNullOrEmpty(videoInput)) { //Create empty subtitles for muxing (subtitles not supported in one click mode) MuxStream[] subtitles = new MuxStream[0]; JobChain c = vUtil.GenerateJobSeries(myVideo, muxedOutput, job.PostprocessingProperties.AudioJobs, subtitles, job.PostprocessingProperties.ChapterFile, job.PostprocessingProperties.OutputSize, job.PostprocessingProperties.Splitting, job.PostprocessingProperties.Container, false, job.PostprocessingProperties.DirectMuxAudio, log); if (c == null) { log.Warn("Job creation aborted"); return(log); } c = CleanupJob.AddAfter(c, intermediateFiles); mainForm.Jobs.addJobsWithDependencies(c); } return(log); }
public void postprocess() { audioFiles = vUtil.getAllDemuxedAudio(job.Output, 8); fillInAudioInformation(); logBuilder.Append("Desired size of this automated encoding series: " + job.PostprocessingProperties.OutputSize + " split size: " + job.PostprocessingProperties.Splitting + "\r\n"); VideoCodecSettings videoSettings = job.PostprocessingProperties.VideoSettings; string videoOutput = Path.Combine(Path.GetDirectoryName(job.Output), Path.GetFileNameWithoutExtension(job.Output) + "_Video"); string muxedOutput = job.PostprocessingProperties.FinalOutput; //Open the video Dar? dar; string videoInput = openVideo(job.Output, job.PostprocessingProperties.DAR, job.PostprocessingProperties.HorizontalOutputResolution, job.PostprocessingProperties.SignalAR, logBuilder, job.PostprocessingProperties.AvsSettings, job.PostprocessingProperties.AutoDeinterlace, videoSettings, out dar); VideoStream myVideo = new VideoStream(); ulong length; double framerate; JobUtil.getInputProperties(out length, out framerate, videoInput); myVideo.Input = videoInput; myVideo.Output = videoOutput; myVideo.NumberOfFrames = length; myVideo.Framerate = (decimal)framerate; myVideo.DAR = dar; myVideo.VideoType = new MuxableType((new VideoEncoderProvider().GetSupportedOutput(videoSettings.EncoderType))[0], videoSettings.Codec); myVideo.Settings = videoSettings; List <string> intermediateFiles = new List <string>(); intermediateFiles.Add(videoInput); intermediateFiles.Add(job.Output); intermediateFiles.AddRange(audioFiles.Values); if (!string.IsNullOrEmpty(videoInput)) { //Create empty subtitles for muxing (subtitles not supported in one click mode) MuxStream[] subtitles = new MuxStream[0]; JobChain c = vUtil.GenerateJobSeries(myVideo, muxedOutput, job.PostprocessingProperties.AudioJobs, subtitles, job.PostprocessingProperties.ChapterFile, job.PostprocessingProperties.OutputSize, job.PostprocessingProperties.Splitting, job.PostprocessingProperties.Container, false, job.PostprocessingProperties.DirectMuxAudio); /* vUtil.generateJobSeries(videoInput, videoOutput, muxedOutput, videoSettings, * audioStreams, audio, subtitles, job.PostprocessingProperties.ChapterFile, * job.PostprocessingProperties.OutputSize, job.PostprocessingProperties.SplitSize, * containerOverhead, type, new string[] { job.Output, videoInput });*/ c = CleanupJob.AddAfter(c, intermediateFiles); mainForm.Jobs.addJobsWithDependencies(c); } mainForm.addToLog(logBuilder.ToString()); }
protected virtual void muxButton_Click(object sender, System.EventArgs e) { if (minimizedMode) { return; } if (muxButton.DialogResult != DialogResult.OK) { if (string.IsNullOrEmpty(vInput.Filename)) { MessageBox.Show("You must configure a video input file", "Missing input", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } else if (string.IsNullOrEmpty(output.Filename)) { MessageBox.Show("You must configure an output file", "Missing input", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } else if (MainForm.verifyOutputFile(output.Filename) != null) { MessageBox.Show("Invalid output file", "Invalid output", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else if (!fps.Value.HasValue) { MessageBox.Show("You must select a framerate", "Missing input", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } } else { if (this.muxButton.Text.Equals("Update")) { this.Close(); } else { JobChain oJobs = this.Jobs; if (oJobs.Jobs.Length == 0) { MessageBox.Show("No mux job created as input and output are the same", "Nothing to mux", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } mainForm.Jobs.AddJobsWithDependencies(oJobs, true); if (chkCloseOnQueue.Checked) { this.Close(); } else { output.Filename = String.Empty; } } } }
internal static JobChain[] convert(Job[] jobs) { JobChain[] d = new JobChain[jobs.Length]; for (int i = 0; i < jobs.Length; ++i) { d[i] = jobs[i]; } return(d); }
public JobChain AddVideoJobs(string movieInput, string movieOutput, VideoCodecSettings settings, int introEndFrame, int creditsStartFrame, Dar?dar, bool prerender, bool checkVideo, Zone[] zones) { JobChain jobs = null; bool cont = getFinalZoneConfiguration(settings, introEndFrame, creditsStartFrame, ref zones); if (!cont) // abort { return(jobs); } return(prepareVideoJob(movieInput, movieOutput, settings, dar, prerender, checkVideo, zones)); }
public void addJobsWithDependencies(JobChain c) { foreach (TaggedJob j in c.Jobs) { addJob(j); } saveJobs(); if (mainForm.Settings.AutoStartQueue) { StartAll(false); } refresh(); }
public void AddJobsWithDependencies(JobChain c, bool bStartQueue) { if (c == null) { return; } foreach (TaggedJob j in c.Jobs) { AddJob(j); } SaveJobs(); if (mainForm.Settings.WorkerAutoStart && bStartQueue) { StartAll(false); } RefreshStatus(); }
public void addJobsWithDependencies(JobChain c, bool bStartQueue) { if (c == null) { return; } foreach (TaggedJob j in c.Jobs) { addJob(j); } saveJobs(); if (mainForm.Settings.AutoStartQueue && bStartQueue) { StartAll(false); } refresh(); }
public bool AddVideoJobs(string movieInput, string movieOutput, VideoCodecSettings settings, int introEndFrame, int creditsStartFrame, Dar?dar, bool prerender, bool checkVideo, Zone[] zones) { bool cont = getFinalZoneConfiguration(settings, introEndFrame, creditsStartFrame, ref zones); if (!cont) // abort { return(false); } JobChain jobs = prepareVideoJob(movieInput, movieOutput, settings, dar, prerender, checkVideo, zones); if (jobs == null) { return(false); } mainForm.Jobs.addJobsWithDependencies(jobs); return(false); }
public static JobChain AddAfter(JobChain other, List <string> files) { return(AddAfter(other, null, files)); }
protected override void RunInThread() { JobChain c = null; List <string> intermediateFiles = new List <string>(); bool bError = false; try { log.LogEvent("Processing thread started"); su.Status = "Preprocessing... ***PLEASE WAIT***"; su.ResetTime(); List <string> arrAudioFilesDelete = new List <string>(); audioFiles = new Dictionary <int, string>(); List <AudioTrackInfo> arrAudioTracks = new List <AudioTrackInfo>(); List <AudioJob> arrAudioJobs = new List <AudioJob>(); List <MuxStream> arrMuxStreams = new List <MuxStream>(); FileUtil.ensureDirectoryExists(job.PostprocessingProperties.WorkingDirectory); // audio handling foreach (OneClickAudioTrack oAudioTrack in job.PostprocessingProperties.AudioTracks) { if (IsJobStopped()) { return; } if (oAudioTrack.AudioTrackInfo != null) { if (oAudioTrack.AudioTrackInfo.ExtractMKVTrack) { if (job.PostprocessingProperties.ApplyDelayCorrection && File.Exists(job.PostprocessingProperties.IntermediateMKVFile)) { MediaInfoFile oFile = new MediaInfoFile(job.PostprocessingProperties.IntermediateMKVFile, ref log); bool bFound = false; foreach (AudioTrackInfo oAudioInfo in oFile.AudioInfo.Tracks) { if (oAudioInfo.MMGTrackID == oAudioTrack.AudioTrackInfo.MMGTrackID) { bFound = true; } } int mmgTrackID = 0; if (!bFound) { mmgTrackID = oFile.AudioInfo.Tracks[oAudioTrack.AudioTrackInfo.TrackIndex].MMGTrackID; } else { mmgTrackID = oAudioTrack.AudioTrackInfo.MMGTrackID; } foreach (AudioTrackInfo oAudioInfo in oFile.AudioInfo.Tracks) { if (oAudioInfo.MMGTrackID == mmgTrackID) { if (oAudioTrack.DirectMuxAudio != null) { oAudioTrack.DirectMuxAudio.delay = oAudioInfo.Delay; } if (oAudioTrack.AudioJob != null) { oAudioTrack.AudioJob.Delay = oAudioInfo.Delay; } break; } } } if (!audioFiles.ContainsKey(oAudioTrack.AudioTrackInfo.TrackID)) { audioFiles.Add(oAudioTrack.AudioTrackInfo.TrackID, job.PostprocessingProperties.WorkingDirectory + "\\" + oAudioTrack.AudioTrackInfo.DemuxFileName); arrAudioFilesDelete.Add(job.PostprocessingProperties.WorkingDirectory + "\\" + oAudioTrack.AudioTrackInfo.DemuxFileName); } } else { arrAudioTracks.Add(oAudioTrack.AudioTrackInfo); } } if (oAudioTrack.AudioJob != null) { if (job.PostprocessingProperties.IndexType == FileIndexerWindow.IndexType.NONE && String.IsNullOrEmpty(oAudioTrack.AudioJob.Input)) { oAudioTrack.AudioJob.Input = job.Input; } arrAudioJobs.Add(oAudioTrack.AudioJob); } if (oAudioTrack.DirectMuxAudio != null) { arrMuxStreams.Add(oAudioTrack.DirectMuxAudio); } } if (audioFiles.Count == 0 && !job.PostprocessingProperties.Eac3toDemux && job.PostprocessingProperties.IndexType != FileIndexerWindow.IndexType.NONE && job.PostprocessingProperties.IndexType != FileIndexerWindow.IndexType.AVISOURCE) { if ((job.PostprocessingProperties.IndexType == FileIndexerWindow.IndexType.DGI || job.PostprocessingProperties.IndexType == FileIndexerWindow.IndexType.DGM) && File.Exists(Path.ChangeExtension(job.IndexFile, ".log"))) { job.PostprocessingProperties.FilesToDelete.Add(Path.ChangeExtension(job.IndexFile, ".log")); audioFiles = AudioUtil.GetAllDemuxedAudioFromDGI(arrAudioTracks, out arrAudioFilesDelete, job.IndexFile, log); } else { audioFiles = VideoUtil.getAllDemuxedAudio(arrAudioTracks, new List <AudioTrackInfo>(), out arrAudioFilesDelete, job.IndexFile, log); } } FillInAudioInformation(ref arrAudioJobs, arrMuxStreams); if (!String.IsNullOrEmpty(job.PostprocessingProperties.VideoFileToMux)) { log.LogEvent("Don't encode video: True"); } else { log.LogEvent("Desired size: " + job.PostprocessingProperties.OutputSize); } log.LogEvent("Split size: " + job.PostprocessingProperties.Splitting); if (IsJobStopped()) { return; } // video file handling string avsFile = String.Empty; VideoStream myVideo = new VideoStream(); VideoCodecSettings videoSettings = job.PostprocessingProperties.VideoSettings; if (String.IsNullOrEmpty(job.PostprocessingProperties.VideoFileToMux)) { //Open the video try { avsFile = CreateAVSFile(job.IndexFile, job.Input, job.PostprocessingProperties.DAR, job.PostprocessingProperties.HorizontalOutputResolution, log, job.PostprocessingProperties.AvsSettings, job.PostprocessingProperties.AutoDeinterlace, videoSettings, job.PostprocessingProperties.AutoCrop, job.PostprocessingProperties.KeepInputResolution, job.PostprocessingProperties.UseChaptersMarks); } catch (Exception ex) { log.LogValue("An error occurred creating the AVS file", ex, ImageType.Error); } if (IsJobStopped()) { return; } if (!String.IsNullOrEmpty(avsFile)) { // check AVS file JobUtil.GetInputProperties(avsFile, out ulong frameCount, out double frameRate); myVideo.Input = avsFile; myVideo.Output = Path.Combine(job.PostprocessingProperties.WorkingDirectory, Path.GetFileNameWithoutExtension(job.Input) + "_Video"); myVideo.NumberOfFrames = frameCount; myVideo.Framerate = (decimal)frameRate; myVideo.VideoType = new MuxableType((new VideoEncoderProvider().GetSupportedOutput(videoSettings.EncoderType))[0], videoSettings.Codec); myVideo.Settings = videoSettings; } else { bError = true; } } else { myVideo.DAR = job.PostprocessingProperties.ForcedDAR; myVideo.Output = job.PostprocessingProperties.VideoFileToMux; MediaInfoFile oInfo = new MediaInfoFile(myVideo.Output, ref log); if (Path.GetExtension(job.PostprocessingProperties.VideoFileToMux).Equals(".unknown") && !String.IsNullOrEmpty(oInfo.ContainerFileTypeString)) { job.PostprocessingProperties.VideoFileToMux = Path.ChangeExtension(job.PostprocessingProperties.VideoFileToMux, oInfo.ContainerFileTypeString.ToLowerInvariant()); File.Move(myVideo.Output, job.PostprocessingProperties.VideoFileToMux); myVideo.Output = job.PostprocessingProperties.VideoFileToMux; job.PostprocessingProperties.FilesToDelete.Add(myVideo.Output); } myVideo.Settings = videoSettings; myVideo.Framerate = (decimal)oInfo.VideoInfo.FPS; myVideo.NumberOfFrames = oInfo.VideoInfo.FrameCount; } if (IsJobStopped()) { return; } intermediateFiles.Add(avsFile); intermediateFiles.Add(job.IndexFile); intermediateFiles.AddRange(audioFiles.Values); foreach (string file in arrAudioFilesDelete) { intermediateFiles.Add(file); } intermediateFiles.Add(Path.ChangeExtension(job.Input, ".log")); foreach (string file in job.PostprocessingProperties.FilesToDelete) { intermediateFiles.Add(file); } // subtitle handling List <MuxStream> subtitles = new List <MuxStream>(); if (job.PostprocessingProperties.SubtitleTracks.Count > 0) { foreach (OneClickStream oTrack in job.PostprocessingProperties.SubtitleTracks) { if (oTrack.TrackInfo.ExtractMKVTrack) { //demuxed MKV string trackFile = Path.GetDirectoryName(job.IndexFile) + "\\" + oTrack.TrackInfo.DemuxFileName; if (File.Exists(trackFile)) { intermediateFiles.Add(trackFile); if (Path.GetExtension(trackFile).ToLowerInvariant().Equals(".idx")) { intermediateFiles.Add(FileUtil.GetPathWithoutExtension(trackFile) + ".sub"); } subtitles.Add(new MuxStream(trackFile, oTrack.Language, oTrack.Name, oTrack.Delay, oTrack.DefaultStream, oTrack.ForcedStream, null)); } else { log.LogEvent("Ignoring subtitle as the it cannot be found: " + trackFile, ImageType.Warning); } } else { // sometimes the language is detected differently by vsrip and the IFO parser. Therefore search also for other files string strDemuxFile = oTrack.DemuxFilePath; if (!File.Exists(strDemuxFile) && Path.GetFileNameWithoutExtension(strDemuxFile).Contains("_")) { string strDemuxFileName = Path.GetFileNameWithoutExtension(strDemuxFile); strDemuxFileName = strDemuxFileName.Substring(0, strDemuxFileName.LastIndexOf("_")) + "_*" + Path.GetExtension(strDemuxFile); foreach (string strFileName in Directory.GetFiles(Path.GetDirectoryName(strDemuxFile), strDemuxFileName)) { strDemuxFile = Path.Combine(Path.GetDirectoryName(strDemuxFile), strFileName); intermediateFiles.Add(strDemuxFile); intermediateFiles.Add(Path.ChangeExtension(strDemuxFile, ".sub")); log.LogEvent("Subtitle + " + oTrack.DemuxFilePath + " cannot be found. " + strFileName + " will be used instead", ImageType.Information); break; } } if (File.Exists(strDemuxFile)) { string strTrackName = oTrack.Name; // check if a forced stream is available string strForcedFile = Path.Combine(Path.GetDirectoryName(strDemuxFile), Path.GetFileNameWithoutExtension(strDemuxFile) + "_forced.idx"); if (File.Exists(strForcedFile)) { subtitles.Add(new MuxStream(strForcedFile, oTrack.Language, SubtitleUtil.ApplyForcedStringToTrackName(true, oTrack.Name), oTrack.Delay, oTrack.DefaultStream, true, null)); intermediateFiles.Add(strForcedFile); intermediateFiles.Add(Path.ChangeExtension(strForcedFile, ".sub")); } subtitles.Add(new MuxStream(strDemuxFile, oTrack.Language, SubtitleUtil.ApplyForcedStringToTrackName(false, oTrack.Name), oTrack.Delay, oTrack.DefaultStream, (File.Exists(strForcedFile) ? false : oTrack.ForcedStream), null)); } else { log.LogEvent("Ignoring subtitle as the it cannot be found: " + oTrack.DemuxFilePath, ImageType.Warning); } } } } if (IsJobStopped()) { return; } if (!bError) { c = VideoUtil.GenerateJobSeries(myVideo, job.PostprocessingProperties.FinalOutput, arrAudioJobs.ToArray(), subtitles.ToArray(), job.PostprocessingProperties.Attachments, job.PostprocessingProperties.TimeStampFile, job.PostprocessingProperties.ChapterInfo, job.PostprocessingProperties.OutputSize, job.PostprocessingProperties.Splitting, job.PostprocessingProperties.Container, job.PostprocessingProperties.PrerenderJob, arrMuxStreams.ToArray(), log, job.PostprocessingProperties.DeviceOutputType, null, job.PostprocessingProperties.VideoFileToMux, job.PostprocessingProperties.AudioTracks.ToArray(), true); } if (c != null && !String.IsNullOrEmpty(job.PostprocessingProperties.TimeStampFile) && c.Jobs[c.Jobs.Length - 1].Job is MuxJob && (c.Jobs[c.Jobs.Length - 1].Job as MuxJob).MuxType == MuxerType.MP4BOX) { // last job is a mp4box job and vfr timecode data has to be applied MP4FpsModJob mp4FpsMod = new MP4FpsModJob(((MuxJob)c.Jobs[c.Jobs.Length - 1].Job).Output, job.PostprocessingProperties.TimeStampFile); c = new SequentialChain(c, new SequentialChain(mp4FpsMod)); } } catch (Exception e) { log.LogValue("An error occurred", e, ImageType.Error); bError = true; } if (c == null || bError) { log.Error("Job creation aborted"); su.HasError = true; } // add cleanup job also in case of an error c = CleanupJob.AddAfter(c, intermediateFiles, job.PostprocessingProperties.FinalOutput); MainForm.Instance.Jobs.AddJobsWithDependencies(c, false); // batch processing other input files if necessary if (job.PostprocessingProperties.FilesToProcess.Count > 0) { OneClickWindow ocw = new OneClickWindow(); ocw.setBatchProcessing(job.PostprocessingProperties.FilesToProcess, job.PostprocessingProperties.OneClickSetting); } su.IsComplete = true; }
public JobChain GenerateJobSeries(VideoStream video, string muxedOutput, AudioJob[] audioStreams, MuxStream[] subtitles, string chapters, FileSize?desiredSize, FileSize?splitSize, ContainerType container, bool prerender, MuxStream[] muxOnlyAudio) { StringBuilder logBuilder = new StringBuilder(); if (desiredSize.HasValue) { logBuilder.Append("Generating jobs. Desired size: " + desiredSize.Value.ToString() + "\r\n"); if (video.Settings.EncodingMode != 4 && video.Settings.EncodingMode != 8) // no automated 2/3 pass { if (this.mainForm.Settings.NbPasses == 2) { video.Settings.EncodingMode = 4; // automated 2 pass } else if (video.Settings.MaxNumberOfPasses == 3) { video.Settings.EncodingMode = 8; } } } else { logBuilder.Append("Generating jobs. No desired size.\r\n"); } fixFileNameExtensions(video, audioStreams, container); string videoOutput = video.Output; logBuilder.Append(eliminatedDuplicateFilenames(ref videoOutput, ref muxedOutput, audioStreams)); video.Output = videoOutput; JobChain vjobs = jobUtil.prepareVideoJob(video.Input, video.Output, video.Settings, video.DAR, prerender, true); if (vjobs == null) { return(null); } /* Here, we guess the types of the files based on extension. * This is guaranteed to work with MeGUI-encoded files, because * the extension will always be recognised. For non-MeGUI files, * we can only ever hope.*/ List <MuxStream> allAudioToMux = new List <MuxStream>(); List <MuxableType> allInputAudioTypes = new List <MuxableType>(); foreach (MuxStream muxStream in muxOnlyAudio) { if (VideoUtil.guessAudioMuxableType(muxStream.path, true) != null) { allInputAudioTypes.Add(VideoUtil.guessAudioMuxableType(muxStream.path, true)); allAudioToMux.Add(muxStream); } } foreach (AudioJob stream in audioStreams) { allAudioToMux.Add(stream.ToMuxStream()); allInputAudioTypes.Add(stream.ToMuxableType()); } List <MuxableType> allInputSubtitleTypes = new List <MuxableType>(); foreach (MuxStream muxStream in subtitles) { if (VideoUtil.guessSubtitleType(muxStream.path) != null) { allInputSubtitleTypes.Add(new MuxableType(VideoUtil.guessSubtitleType(muxStream.path), null)); } } MuxableType chapterInputType = null; if (!String.IsNullOrEmpty(chapters)) { ChapterType type = VideoUtil.guessChapterType(chapters); if (type != null) { chapterInputType = new MuxableType(type, null); } } JobChain muxJobs = this.jobUtil.GenerateMuxJobs(video, video.Framerate, allAudioToMux.ToArray(), allInputAudioTypes.ToArray(), subtitles, allInputSubtitleTypes.ToArray(), chapters, chapterInputType, container, muxedOutput, splitSize, true); /* foreach (Job mJob in muxJobs) * foreach (Job job in jobs) * mJob.AddDependency(job);*/ /* * foreach (VideoJob job in vjobs) * { * jobs.Add(job); * } * foreach (MuxJob job in muxJobs) * { * jobs.Add(job); * } */ if (desiredSize.HasValue) { /* if (encodedAudioPresent) // no audio encoding, we can calculate the video bitrate directly * { * logBuilder.Append("No audio encoding. Calculating desired video bitrate directly.\r\n"); * List<AudioStream> calculationAudioStreams = new List<AudioStream>(); * foreach (SubStream stream in muxOnlyAudio) * { * FileInfo fi = new FileInfo(stream.path); * AudioStream newStream = new AudioStream(); * newStream.SizeBytes = fi.Length; * newStream.Type = guessAudioType(stream.path); * newStream.BitrateMode = BitrateManagementMode.VBR; * calculationAudioStreams.Add(newStream); * logBuilder.Append("Encoded audio file is present: " + stream.path + * " It has a size of " + fi.Length + " bytes. \r\n"); * } * * long videoSizeKB; * bool useBframes = false; * if (video.Settings.NbBframes > 0) * useBframes = true; * * bitrateKBits = calc.CalculateBitrateKBits(video.Settings.Codec, useBframes, container, calculationAudioStreams.ToArray(), * desiredSizeBytes, video.NumberOfFrames, video.Framerate, out videoSizeKB); * desiredSizeBytes = (long)videoSizeKB * 1024L; // convert kb back to bytes * logBuilder.Append("Setting video bitrate for the video jobs to " + bitrateKBits + " kbit/s\r\n"); * foreach (VideoJob vJob in vjobs) * { * jobUtil.updateVideoBitrate(vJob, bitrateKBits); * } * }*/ BitrateCalculationInfo b = new BitrateCalculationInfo(); List <string> audiofiles = new List <string>(); foreach (MuxStream s in allAudioToMux) { audiofiles.Add(s.path); } b.AudioFiles = audiofiles; b.Container = container; b.VideoJobs = new List <TaggedJob>(vjobs.Jobs); b.DesiredSize = desiredSize.Value; ((VideoJob)vjobs.Jobs[0].Job).BitrateCalculationInfo = b; } mainForm.addToLog(logBuilder.ToString()); return (new SequentialChain( new ParallelChain((Job[])audioStreams), new SequentialChain(vjobs), new SequentialChain(muxJobs))); }
private void queueVideoButton_Click(object sender, System.EventArgs e) { fileType_SelectedIndexChanged(sender, e); // to select always correct output file extension string settingsError = verifyVideoSettings(); // basic input, logfile and output file settings are okay if (settingsError != null) { MessageBox.Show(settingsError, "Unsupported configuration", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } VideoCodecSettings vSettings = this.CurrentSettings.Clone(); string videoOutput = info.VideoOutput; // special handling as the encoders cannot output all desired container types if (!fileType.Text.StartsWith("RAW") && (!vSettings.SettingsID.Equals("x264") || !fileType.Text.Equals("MKV") || MainForm.Instance.Settings.UseExternalMuxerX264)) { if (vSettings.SettingsID.Equals("x264")) { videoOutput = Path.ChangeExtension(videoOutput, "264"); } else if (vSettings.SettingsID.Equals("x265")) { videoOutput = Path.ChangeExtension(videoOutput, "hevc"); } else if (vSettings.SettingsID.Equals("XviD")) { videoOutput = Path.ChangeExtension(videoOutput, "m4v"); } } JobUtil.GetInputProperties(info.VideoInput, out ulong frameCount, out double frameRate); JobChain prepareJobs = JobUtil.AddVideoJobs(info.VideoInput, videoOutput, this.CurrentSettings.Clone(), info.IntroEndFrame, info.CreditsStartFrame, info.DAR, PrerenderJob, info.Zones, (int)frameCount); if (!fileType.Text.StartsWith("RAW") && vSettings.VideoEncodingType != MeGUI.VideoCodecSettings.VideoEncodingMode.twopass1 && vSettings.VideoEncodingType != MeGUI.VideoCodecSettings.VideoEncodingMode.threepass1 && (!vSettings.SettingsID.Equals("x264") || !fileType.Text.Equals("MKV") || MainForm.Instance.Settings.UseExternalMuxerX264)) { // create mux job MuxJob mJob = new MuxJob(); mJob.Input = videoOutput; if (vSettings.SettingsID.Equals("XviD")) { mJob.MuxType = MuxerType.FFMPEG; mJob.Output = Path.ChangeExtension(videoOutput, "avi"); if (fileType.Text.Equals("MKV")) { mJob.Output = Path.ChangeExtension(videoOutput, "mkv"); } } else if (fileType.Text.Equals("MKV")) { mJob.MuxType = MuxerType.MKVMERGE; mJob.Output = Path.ChangeExtension(videoOutput, "mkv"); } else { mJob.MuxType = MuxerType.MP4BOX; mJob.Output = Path.ChangeExtension(videoOutput, "mp4"); } mJob.Settings.MuxAll = true; mJob.Settings.MuxedInput = mJob.Input; mJob.Settings.MuxedOutput = mJob.Output; mJob.FilesToDelete.Add(videoOutput); // add job to queue prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(mJob)); } MainForm.Instance.Jobs.AddJobsWithDependencies(prepareJobs, true); }
/// <summary> /// creates a project /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void queueButton_Click(object sender, System.EventArgs e) { if (dialogMode) { return; } if (!configured) { MessageBox.Show("You must select the input and output file to continue", "Configuration incomplete", MessageBoxButtons.OK); return; } if (!Drives.ableToWriteOnThisDrive(Path.GetPathRoot(output.Text))) { MessageBox.Show("MeGUI cannot write on the disc " + Path.GetPathRoot(output.Text) + "\n" + "Please, select another output path to save your project...", "Configuration Incomplete", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } JobChain prepareJobs = null; string videoInput = input.Filename; // create pgcdemux job if needed if (cbPGC.SelectedIndex > 0 && Path.GetExtension(input.Filename.ToUpper(System.Globalization.CultureInfo.InvariantCulture)) == ".VOB") { string videoIFO; // PGC numbers are not present in VOB, so we check the main IFO if (Path.GetFileName(input.Filename).ToUpper(System.Globalization.CultureInfo.InvariantCulture).Substring(0, 4) == "VTS_") { videoIFO = input.Filename.Substring(0, input.Filename.LastIndexOf("_")) + "_0.IFO"; } else { videoIFO = Path.ChangeExtension(input.Filename, ".IFO"); } if (File.Exists(videoIFO)) { prepareJobs = new SequentialChain(new PgcDemuxJob(videoIFO, Path.GetDirectoryName(output.Text), cbPGC.SelectedIndex)); videoInput = Path.Combine(Path.GetDirectoryName(output.Text), "VTS_01_1.VOB"); for (int i = 1; i < 10; i++) { string file = Path.Combine(Path.GetDirectoryName(output.Text), "VTS_01_" + i + ".VOB"); if (File.Exists(file)) { MessageBox.Show("The pgc demux file already exists: \n" + file + "\n\n" + "Please select another output path to save your project.", "Configuration Incomplete", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } } } switch (IndexerUsed) { case IndexType.D2V: { prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(generateD2VIndexJob(videoInput))); mainForm.Jobs.addJobsWithDependencies(prepareJobs); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.DGI: { prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(generateDGNVIndexJob(videoInput))); mainForm.Jobs.addJobsWithDependencies(prepareJobs); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.DGA: { prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(generateDGAIndexJob(videoInput))); mainForm.Jobs.addJobsWithDependencies(prepareJobs); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.FFMS: { FFMSIndexJob job = generateFFMSIndexJob(videoInput); if (txtContainerInformation.Text.Trim().ToUpper(System.Globalization.CultureInfo.InvariantCulture).Equals("MATROSKA") && job.DemuxMode > 0 && job.AudioTracks.Count > 0) { job.AudioTracksDemux = job.AudioTracks; job.AudioTracks = new List <AudioTrackInfo>(); MkvExtractJob extractJob = new MkvExtractJob(videoInput, Path.GetDirectoryName(this.output.Text), job.AudioTracksDemux); prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(extractJob)); } prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(job)); mainForm.Jobs.addJobsWithDependencies(prepareJobs); if (this.closeOnQueue.Checked) { this.Close(); } break; } } }
internal static JobChain[] convert(Job[] jobs) { JobChain[] d = new JobChain[jobs.Length]; for (int i = 0; i < jobs.Length; ++i) d[i] = jobs[i]; return d; }
/// <summary> /// creates a project /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void queueButton_Click(object sender, System.EventArgs e) { if (dialogMode) { return; } if (!configured) { MessageBox.Show("You must select the input and output file to continue", "Configuration incomplete", MessageBoxButtons.OK); return; } if (!Drives.ableToWriteOnThisDrive(Path.GetPathRoot(output.Filename))) { MessageBox.Show("MeGUI cannot write on the disc " + Path.GetPathRoot(output.Filename) + "\n" + "Please, select another output path to save your project...", "Configuration Incomplete", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } JobChain prepareJobs = null; string videoInput = input.Filename; // create pgcdemux job if needed if (Path.GetExtension(input.Filename).ToUpperInvariant().Equals(".IFO")) { if (iFile.VideoInfo.PGCCount > 1 || iFile.VideoInfo.AngleCount > 0) { // pgcdemux must be used as either multiple PGCs or a multi-angle disc are found string tempFile = Path.Combine(Path.GetDirectoryName(output.Filename), Path.GetFileNameWithoutExtension(output.Filename) + "_1.VOB"); prepareJobs = new SequentialChain(new PgcDemuxJob(videoInput, tempFile, iFile.VideoInfo.PGCNumber, iFile.VideoInfo.AngleNumber)); videoInput = tempFile; string filesToOverwrite = string.Empty; for (int i = 1; i < 10; i++) { string file = Path.Combine(Path.GetDirectoryName(output.Filename), Path.GetFileNameWithoutExtension(output.Filename) + "_" + i + ".VOB"); if (File.Exists(file)) { filesToOverwrite += file + "\n"; } } if (!String.IsNullOrEmpty(filesToOverwrite)) { DialogResult dr = MessageBox.Show("The pgc demux files already exist: \n" + filesToOverwrite + "\n" + "Do you want to overwrite these files?", "Configuration Incomplete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (dr == DialogResult.No) { return; } } } else { // change from _0.IFO to _1.VOB for the indexer videoInput = input.Filename.Substring(0, input.Filename.Length - 5) + "1.VOB"; if (!File.Exists(videoInput)) { MessageBox.Show("The file following file cannot be found: \n" + videoInput, "Configuration Incomplete", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } } else if (Path.GetExtension(input.Filename).ToUpperInvariant().Equals(".MPLS") && IndexerUsed != IndexType.DGI && IndexerUsed != IndexType.DGM) { // blu-ray playlist without DGI/DGM used - therefore eac3to must be used first string strTempMKVFile = Path.Combine(Path.GetDirectoryName(output.Filename), Path.GetFileNameWithoutExtension(output.Filename) + ".mkv"); if (File.Exists(strTempMKVFile)) { DialogResult dr = MessageBox.Show("The demux file already exist: \n" + strTempMKVFile + "\n" + "Do you want to overwrite this file?", "Configuration Incomplete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (dr == DialogResult.No) { return; } } StringBuilder sb = new StringBuilder(); sb.Append(string.Format("{0}:\"{1}\" ", iFile.VideoInfo.Track.TrackID, strTempMKVFile)); foreach (AudioTrackInfo oStreamControl in AudioTracks.CheckedItems) { bool bCoreOnly = false; AudioCodec audioCodec = oStreamControl.AudioCodec; if (oStreamControl.HasCore && !MainForm.Instance.Settings.Eac3toDefaultToHD) { // audio file can be demuxed && should be touched (core needed) if (audioCodec == AudioCodec.THDAC3) { oStreamControl.Codec = "AC-3"; oStreamControl.AudioType = AudioType.AC3; oStreamControl.AudioCodec = AudioCodec.AC3; bCoreOnly = true; oStreamControl.HasCore = false; } else if (audioCodec == AudioCodec.DTS) { oStreamControl.Codec = "DTS"; oStreamControl.AudioType = AudioType.DTS; oStreamControl.AudioCodec = AudioCodec.DTS; oStreamControl.HasCore = false; bCoreOnly = true; } } // core must be extracted (workaround for an eac3to issue) // http://bugs.madshi.net/view.php?id=450 if (audioCodec == AudioCodec.EAC3) { bCoreOnly = true; } string strSourceFileName = Path.Combine(Path.GetDirectoryName(input.Filename), Path.GetFileNameWithoutExtension(strTempMKVFile)); oStreamControl.SourceFileName = strSourceFileName; sb.Append(string.Format("{0}:\"{1}\" ", oStreamControl.TrackID, Path.Combine(Path.GetDirectoryName(output.Filename), oStreamControl.DemuxFileName))); if (bCoreOnly) { sb.Append("-core "); } } HDStreamsExJob oJob = new HDStreamsExJob(new List <string>() { input.Filename }, Path.GetDirectoryName(output.Filename), null, sb.ToString(), 2); prepareJobs = new SequentialChain(oJob); videoInput = strTempMKVFile; } switch (IndexerUsed) { case IndexType.D2V: { prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(generateD2VIndexJob(videoInput))); MainForm.Instance.Jobs.AddJobsWithDependencies(prepareJobs, true); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.DGI: { prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(generateDGNVIndexJob(videoInput))); MainForm.Instance.Jobs.AddJobsWithDependencies(prepareJobs, true); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.DGM: { prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(generateDGMIndexJob(videoInput))); MainForm.Instance.Jobs.AddJobsWithDependencies(prepareJobs, true); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.FFMS: { FFMSIndexJob job = generateFFMSIndexJob(videoInput); if (job.DemuxMode > 0 && job.AudioTracks.Count > 0 && (txtContainerInformation.Text.Trim().ToUpperInvariant().Equals("MATROSKA") || txtContainerInformation.Text.Trim().ToUpperInvariant().Equals("BLU-RAY PLAYLIST"))) { job.DemuxMode = 0; job.AudioTracksDemux = job.AudioTracks; job.AudioTracks = new List <AudioTrackInfo>(); if (txtContainerInformation.Text.Trim().ToUpperInvariant().Equals("MATROSKA")) { MkvExtractJob extractJob = new MkvExtractJob(videoInput, Path.GetDirectoryName(this.output.Filename), job.AudioTracksDemux); prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(extractJob)); } } prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(job)); MainForm.Instance.Jobs.AddJobsWithDependencies(prepareJobs, true); if (this.closeOnQueue.Checked) { this.Close(); } break; } case IndexType.LSMASH: { LSMASHIndexJob job = generateLSMASHIndexJob(videoInput); if (job.DemuxMode > 0 && job.AudioTracks.Count > 0 && (txtContainerInformation.Text.Trim().ToUpperInvariant().Equals("MATROSKA") || txtContainerInformation.Text.Trim().ToUpperInvariant().Equals("BLU-RAY PLAYLIST"))) { job.DemuxMode = 0; job.AudioTracksDemux = job.AudioTracks; job.AudioTracks = new List <AudioTrackInfo>(); if (txtContainerInformation.Text.Trim().ToUpperInvariant().Equals("MATROSKA")) { MkvExtractJob extractJob = new MkvExtractJob(videoInput, Path.GetDirectoryName(this.output.Filename), job.AudioTracksDemux); prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(extractJob)); } } prepareJobs = new SequentialChain(prepareJobs, new SequentialChain(job)); MainForm.Instance.Jobs.AddJobsWithDependencies(prepareJobs, true); if (this.closeOnQueue.Checked) { this.Close(); } break; } } }
public JobChain GenerateJobSeries(VideoStream video, string muxedOutput, AudioJob[] audioStreams, MuxStream[] subtitles, string chapters, FileSize?desiredSize, FileSize?splitSize, ContainerType container, bool prerender, MuxStream[] muxOnlyAudio, LogItem log, string deviceType, Zone[] zones, string videoFileToMux, OneClickAudioTrack[] audioTracks) { if (desiredSize.HasValue && String.IsNullOrEmpty(videoFileToMux)) { if (video.Settings.EncodingMode != 4 && video.Settings.EncodingMode != 8) // no automated 2/3 pass { if (this.mainForm.Settings.NbPasses == 2) { video.Settings.EncodingMode = 4; // automated 2 pass } else if (video.Settings.MaxNumberOfPasses == 3) { video.Settings.EncodingMode = 8; } } } fixFileNameExtensions(video, audioStreams, container); string videoOutput = video.Output; log.Add(eliminatedDuplicateFilenames(ref videoOutput, ref muxedOutput, audioStreams)); JobChain vjobs = null; if (!String.IsNullOrEmpty(videoFileToMux)) { video.Output = videoFileToMux; } else { video.Output = videoOutput; vjobs = jobUtil.prepareVideoJob(video.Input, video.Output, video.Settings, video.DAR, prerender, true, zones); if (vjobs == null) { return(null); } } /* Here, we guess the types of the files based on extension. * This is guaranteed to work with MeGUI-encoded files, because * the extension will always be recognised. For non-MeGUI files, * we can only ever hope.*/ List <MuxStream> allAudioToMux = new List <MuxStream>(); List <MuxableType> allInputAudioTypes = new List <MuxableType>(); if (audioTracks != null) { // OneClick mode foreach (OneClickAudioTrack ocAudioTrack in audioTracks) { if (ocAudioTrack.DirectMuxAudio != null) { if (VideoUtil.guessAudioMuxableType(ocAudioTrack.DirectMuxAudio.path, true) != null) { allInputAudioTypes.Add(VideoUtil.guessAudioMuxableType(ocAudioTrack.DirectMuxAudio.path, true)); allAudioToMux.Add(ocAudioTrack.DirectMuxAudio); } } if (ocAudioTrack.AudioJob != null) { allAudioToMux.Add(ocAudioTrack.AudioJob.ToMuxStream()); allInputAudioTypes.Add(ocAudioTrack.AudioJob.ToMuxableType()); } } } else { // AutoEncode mode foreach (AudioJob stream in audioStreams) { allAudioToMux.Add(stream.ToMuxStream()); allInputAudioTypes.Add(stream.ToMuxableType()); } foreach (MuxStream muxStream in muxOnlyAudio) { if (VideoUtil.guessAudioMuxableType(muxStream.path, true) != null) { allInputAudioTypes.Add(VideoUtil.guessAudioMuxableType(muxStream.path, true)); allAudioToMux.Add(muxStream); } } } List <MuxableType> allInputSubtitleTypes = new List <MuxableType>(); foreach (MuxStream muxStream in subtitles) { if (VideoUtil.guessSubtitleType(muxStream.path) != null) { allInputSubtitleTypes.Add(new MuxableType(VideoUtil.guessSubtitleType(muxStream.path), null)); } } MuxableType chapterInputType = null; if (!String.IsNullOrEmpty(chapters)) { ChapterType type = VideoUtil.guessChapterType(chapters); if (type != null) { chapterInputType = new MuxableType(type, null); } } MuxableType deviceOutputType = null; if (!String.IsNullOrEmpty(deviceType)) { DeviceType type = VideoUtil.guessDeviceType(deviceType); if (type != null) { deviceOutputType = new MuxableType(type, null); } } List <string> inputsToDelete = new List <string>(); if (String.IsNullOrEmpty(videoFileToMux)) { inputsToDelete.Add(video.Output); } inputsToDelete.AddRange(Array.ConvertAll <AudioJob, string>(audioStreams, delegate(AudioJob a) { return(a.Output); })); JobChain muxJobs = jobUtil.GenerateMuxJobs(video, video.Framerate, allAudioToMux.ToArray(), allInputAudioTypes.ToArray(), subtitles, allInputSubtitleTypes.ToArray(), chapters, chapterInputType, container, muxedOutput, splitSize, inputsToDelete, deviceType, deviceOutputType); if (desiredSize.HasValue && String.IsNullOrEmpty(videoFileToMux)) { BitrateCalculationInfo b = new BitrateCalculationInfo(); List <string> audiofiles = new List <string>(); foreach (MuxStream s in allAudioToMux) { audiofiles.Add(s.path); } b.AudioFiles = audiofiles; b.Container = container; b.VideoJobs = new List <TaggedJob>(vjobs.Jobs); b.DesiredSize = desiredSize.Value; ((VideoJob)vjobs.Jobs[0].Job).BitrateCalculationInfo = b; } if (!String.IsNullOrEmpty(videoFileToMux)) { return(new SequentialChain(new SequentialChain((Job[])audioStreams), new SequentialChain(muxJobs))); } else { return(new SequentialChain( new SequentialChain((Job[])audioStreams), new SequentialChain(vjobs), new SequentialChain(muxJobs))); } }
private void StartPostProcessing() { Thread t = null; try { _log.LogEvent("Processing thread started"); raiseEvent("Preprocessing... ***PLEASE WAIT***"); _start = DateTime.Now; t = new Thread(new ThreadStart(delegate { while (true) { updateTime(); Thread.Sleep(1000); } })); t.Start(); List <string> arrAudioFilesDelete = new List <string>(); audioFiles = new Dictionary <int, string>(); List <AudioTrackInfo> arrAudioTracks = new List <AudioTrackInfo>(); List <AudioJob> arrAudioJobs = new List <AudioJob>(); List <MuxStream> arrMuxStreams = new List <MuxStream>(); List <string> intermediateFiles = new List <string>(); FileUtil.ensureDirectoryExists(job.PostprocessingProperties.WorkingDirectory); foreach (OneClickAudioTrack oAudioTrack in job.PostprocessingProperties.AudioTracks) { if (oAudioTrack.ExtractMKVTrack) { audioFiles.Add(oAudioTrack.AudioTrackInfo.TrackID, job.PostprocessingProperties.WorkingDirectory + "\\" + oAudioTrack.AudioTrackInfo.DemuxFileName); arrAudioFilesDelete.Add(job.PostprocessingProperties.WorkingDirectory + "\\" + oAudioTrack.AudioTrackInfo.DemuxFileName); } else if (oAudioTrack.AudioTrackInfo != null) { arrAudioTracks.Add(oAudioTrack.AudioTrackInfo); } if (oAudioTrack.AudioJob != null) { if (job.PostprocessingProperties.IndexType == FileIndexerWindow.IndexType.NONE && String.IsNullOrEmpty(oAudioTrack.AudioJob.Input)) { oAudioTrack.AudioJob.Input = job.Input; } arrAudioJobs.Add(oAudioTrack.AudioJob); } if (oAudioTrack.DirectMuxAudio != null) { arrMuxStreams.Add(oAudioTrack.DirectMuxAudio); } } if (audioFiles.Count == 0 && job.PostprocessingProperties.IndexType != FileIndexerWindow.IndexType.NONE && !job.PostprocessingProperties.Eac3toDemux) { audioFiles = vUtil.getAllDemuxedAudio(arrAudioTracks, new List <AudioTrackInfo>(), out arrAudioFilesDelete, job.IndexFile, _log); } fillInAudioInformation(arrAudioJobs, arrMuxStreams); if (!String.IsNullOrEmpty(job.PostprocessingProperties.VideoFileToMux)) { _log.LogEvent("Don't encode video: True"); } else { _log.LogEvent("Desired size: " + job.PostprocessingProperties.OutputSize); } _log.LogEvent("Split size: " + job.PostprocessingProperties.Splitting); // chapter file handling if (String.IsNullOrEmpty(job.PostprocessingProperties.ChapterFile)) { job.PostprocessingProperties.ChapterFile = null; } else if (job.PostprocessingProperties.Container == ContainerType.AVI) { _log.LogEvent("Chapter handling disabled because of the AVI target container"); job.PostprocessingProperties.ChapterFile = null; } else if (!File.Exists(job.PostprocessingProperties.ChapterFile)) { if (job.PostprocessingProperties.ChapterFile.StartsWith("<") || job.PostprocessingProperties.ChapterExtracted) { // internal chapter file string strTempFile = job.PostprocessingProperties.ChapterFile; if (Path.GetExtension(job.PostprocessingProperties.VideoInput).ToLower(System.Globalization.CultureInfo.InvariantCulture).Equals(".mkv")) { MediaInfoFile oInfo = new MediaInfoFile(job.PostprocessingProperties.VideoInput, ref _log); if (oInfo.hasMKVChapters()) { job.PostprocessingProperties.ChapterFile = Path.Combine(job.PostprocessingProperties.WorkingDirectory, Path.GetFileNameWithoutExtension(job.IndexFile) + " - Chapter Information.txt"); if (oInfo.extractMKVChapters(job.PostprocessingProperties.ChapterFile)) { intermediateFiles.Add(job.PostprocessingProperties.ChapterFile); job.PostprocessingProperties.ChapterExtracted = true; } else { job.PostprocessingProperties.ChapterFile = strTempFile; } } } else if (File.Exists(job.PostprocessingProperties.IFOInput)) { job.PostprocessingProperties.ChapterFile = VideoUtil.getChaptersFromIFO(job.PostprocessingProperties.IFOInput, false, job.PostprocessingProperties.WorkingDirectory, job.PostprocessingProperties.TitleNumberToProcess); if (!String.IsNullOrEmpty(job.PostprocessingProperties.ChapterFile)) { intermediateFiles.Add(job.PostprocessingProperties.ChapterFile); job.PostprocessingProperties.ChapterExtracted = true; } else { job.PostprocessingProperties.ChapterFile = strTempFile; } } } if (!File.Exists(job.PostprocessingProperties.ChapterFile)) { _log.LogEvent("File not found: " + job.PostprocessingProperties.ChapterFile, ImageType.Error); job.PostprocessingProperties.ChapterFile = null; } } else if (job.PostprocessingProperties.ChapterExtracted) { intermediateFiles.Add(job.PostprocessingProperties.ChapterFile); } string avsFile = String.Empty; VideoStream myVideo = new VideoStream(); VideoCodecSettings videoSettings = job.PostprocessingProperties.VideoSettings; if (String.IsNullOrEmpty(job.PostprocessingProperties.VideoFileToMux)) { //Open the video Dar?dar; avsFile = createAVSFile(job.IndexFile, job.Input, job.PostprocessingProperties.DAR, job.PostprocessingProperties.HorizontalOutputResolution, job.PostprocessingProperties.SignalAR, _log, job.PostprocessingProperties.AvsSettings, job.PostprocessingProperties.AutoDeinterlace, videoSettings, out dar, job.PostprocessingProperties.AutoCrop, job.PostprocessingProperties.KeepInputResolution, job.PostprocessingProperties.UseChaptersMarks); ulong length; double framerate; JobUtil.getInputProperties(out length, out framerate, avsFile); myVideo.Input = avsFile; myVideo.Output = Path.Combine(job.PostprocessingProperties.WorkingDirectory, Path.GetFileNameWithoutExtension(job.Input) + "_Video"); myVideo.NumberOfFrames = length; myVideo.Framerate = (decimal)framerate; myVideo.DAR = dar; myVideo.VideoType = new MuxableType((new VideoEncoderProvider().GetSupportedOutput(videoSettings.EncoderType))[0], videoSettings.Codec); myVideo.Settings = videoSettings; } else { myVideo.Output = job.PostprocessingProperties.VideoFileToMux; myVideo.Settings = videoSettings; MediaInfoFile oInfo = new MediaInfoFile(myVideo.Output, ref _log); videoSettings.VideoName = oInfo.VideoInfo.Track.Name; myVideo.Framerate = (decimal)oInfo.VideoInfo.FPS; } intermediateFiles.Add(avsFile); intermediateFiles.Add(job.IndexFile); intermediateFiles.AddRange(audioFiles.Values); if (!string.IsNullOrEmpty(qpfile)) { intermediateFiles.Add(qpfile); } foreach (string file in arrAudioFilesDelete) { intermediateFiles.Add(file); } if (File.Exists(Path.Combine(Path.GetDirectoryName(job.Input), Path.GetFileNameWithoutExtension(job.Input) + "._log"))) { intermediateFiles.Add(Path.Combine(Path.GetDirectoryName(job.Input), Path.GetFileNameWithoutExtension(job.Input) + "._log")); } foreach (string file in job.PostprocessingProperties.FilesToDelete) { intermediateFiles.Add(file); } if (!string.IsNullOrEmpty(avsFile) || !String.IsNullOrEmpty(job.PostprocessingProperties.VideoFileToMux)) { MuxStream[] subtitles; if (job.PostprocessingProperties.SubtitleTracks.Count == 0) { //Create empty subtitles for muxing subtitles = new MuxStream[0]; } else { subtitles = new MuxStream[job.PostprocessingProperties.SubtitleTracks.Count]; int i = 0; foreach (OneClickStream oTrack in job.PostprocessingProperties.SubtitleTracks) { if (oTrack.TrackInfo.IsMKVContainer()) { //demuxed MKV string trackFile = Path.GetDirectoryName(job.IndexFile) + "\\" + oTrack.TrackInfo.DemuxFileName; if (File.Exists(trackFile)) { intermediateFiles.Add(trackFile); if (Path.GetExtension(trackFile).ToLower(System.Globalization.CultureInfo.InvariantCulture).Equals(".idx")) { intermediateFiles.Add(FileUtil.GetPathWithoutExtension(trackFile) + ".sub"); } subtitles[i] = new MuxStream(trackFile, oTrack.Language, oTrack.Name, oTrack.Delay, oTrack.DefaultStream, oTrack.ForcedStream, null); } else { _log.LogEvent("File not found: " + trackFile, ImageType.Error); } } else { subtitles[i] = new MuxStream(oTrack.DemuxFilePath, oTrack.Language, oTrack.Name, oTrack.Delay, oTrack.DefaultStream, oTrack.ForcedStream, null); } i++; } } JobChain c = vUtil.GenerateJobSeries(myVideo, job.PostprocessingProperties.FinalOutput, arrAudioJobs.ToArray(), subtitles, job.PostprocessingProperties.ChapterFile, job.PostprocessingProperties.OutputSize, job.PostprocessingProperties.Splitting, job.PostprocessingProperties.Container, job.PostprocessingProperties.PrerenderJob, arrMuxStreams.ToArray(), _log, job.PostprocessingProperties.DeviceOutputType, null, job.PostprocessingProperties.VideoFileToMux, job.PostprocessingProperties.AudioTracks.ToArray()); if (c == null) { _log.Warn("Job creation aborted"); return; } c = CleanupJob.AddAfter(c, intermediateFiles, job.PostprocessingProperties.FinalOutput); mainForm.Jobs.addJobsWithDependencies(c); // batch processing other input files if necessary if (job.PostprocessingProperties.FilesToProcess.Count > 0) { OneClickWindow ocw = new OneClickWindow(mainForm); ocw.setBatchProcessing(job.PostprocessingProperties.FilesToProcess, job.PostprocessingProperties.OneClickSetting); } } } catch (Exception e) { t.Abort(); if (e is ThreadAbortException) { _log.LogEvent("Aborting..."); su.WasAborted = true; su.IsComplete = true; raiseEvent(); } else { _log.LogValue("An error occurred", e, ImageType.Error); su.HasError = true; su.IsComplete = true; raiseEvent(); } return; } t.Abort(); su.IsComplete = true; raiseEvent(); }
public static JobChain AddAfter(JobChain other, List<string> files) { return AddAfter(other, null, files); }