/// <summary> /// sets the GUI to a minimal mode allowing to configure audio track languages, configure subtitles, and chapters /// the rest of the options are deactivated /// </summary> /// <param name="videoInput">the video input</param> /// <param name="framerate">the framerate of the video input</param> /// <param name="audioStreams">the audio streams whose languages have to be assigned</param> /// <param name="output">the output file</param> /// <param name="splitSize">the output split size</param> public void setMinimizedMode(string videoInput, VideoEncoderType videoType, double framerate, MuxStream[] audioStreams, AudioEncoderType[] audioTypes, string output, FileSize? splitSize, ContainerType cft) { base.setConfig(videoInput, (decimal)framerate, audioStreams, new MuxStream[0], null, output, splitSize, null, null); minimizedMode = true; knownVideoType = videoType; knownAudioTypes = audioTypes; // disable everything videoGroupbox.Enabled = false; for (int i = 0; i < audioStreams.Length; ++i) audioTracks[i].Enabled = false; this.output.Filename = output; this.splitting.Value = splitSize; this.muxButton.Text = "Go"; updatePossibleContainers(); if (this.cbContainer.Items.Contains(cft)) cbContainer.SelectedItem = cft; checkIO(); }
private void setConfig(string videoInput, string muxedInput, decimal? framerate, MuxStream[] audioStreams, MuxStream[] subtitleStreams, string chapterFile, string output, FileSize? splitSize, Dar? dar, string deviceType) { base.setConfig(videoInput, framerate, audioStreams, subtitleStreams, chapterFile, output, splitSize, dar, deviceType); this.muxedInput.Filename = muxedInput; this.checkIO(); }
public void getAdditionalStreams(out MuxStream[] audio, out MuxStream[] subtitles, out string chapters, out string output, out ContainerType cot) { cot = (cbContainer.SelectedItem as ContainerType); output = this.output.Filename; base.getAdditionalStreams(out audio, out subtitles, out chapters); }
/// <summary> /// gets the additionally configured stream configuration from this window /// this method is used when the muxwindow is created from the AutoEncodeWindow in order to configure audio languages /// add subtitles and chapters /// </summary> /// <param name="aStreams">the configured audio streams(language assignments)</param> /// <param name="sStreams">the newly added subtitle streams</param> /// <param name="chapterFile">the assigned chapter file</param> public void getAdditionalStreams(out MuxStream[] aStreams, out MuxStream[] sStreams, out string chapterFile) { aStreams = getStreams(audioTracks); sStreams = getStreams(subtitleTracks); chapterFile = chapters.Filename; }
/// <summary> /// sets the configuration of the GUI /// used when a job is loaded (jobs have everything already filled out) /// </summary> /// <param name="videoInput">the video input (raw or mp4)</param> /// <param name="framerate">framerate of the input</param> /// <param name="audioStreams">the audiostreams</param> /// <param name="subtitleStreams">the subtitle streams</param> /// <param name="output">name of the output</param> /// <param name="splitSize">split size of the output</param> public void setConfig(string videoInput, decimal? framerate, MuxStream[] audioStreams, MuxStream[] subtitleStreams, string chapterFile, string output, FileSize? splitSize, Dar? dar, string deviceType) { this.dar = dar; vInput.Filename = videoInput; fps.Value = framerate; int index = 0; foreach (MuxStream stream in audioStreams) { if (audioTracks.Count == index) AudioAddTrack(); audioTracks[index].Stream = stream; index++; } index = 0; foreach (MuxStream stream in subtitleStreams) { if (subtitleTracks.Count == index) SubtitleAddTrack(); subtitleTracks[index].Stream = stream; index++; } chapters.Filename = chapterFile; this.output.Filename = output; this.splitting.Value = splitSize; this.muxButton.Text = "Update"; this.cbType.Text = deviceType; checkIO(); }
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, job.PostprocessingProperties.AutoCrop, job.PostprocessingProperties.KeepInputResolution, job.PostprocessingProperties.UseChaptersMarks); 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(qpfile)) intermediateFiles.Add(qpfile); 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, job.PostprocessingProperties.PrerenderJob, job.PostprocessingProperties.DirectMuxAudio, log, job.PostprocessingProperties.DeviceOutputType); if (c == null) { log.Warn("Job creation aborted"); return log; } c = CleanupJob.AddAfter(c, intermediateFiles); mainForm.Jobs.addJobsWithDependencies(c); } return log; }
/// <summary> /// separates encodable from muxable audio streams /// in addition to returning the two types separately an array of SubStreams is returned /// which is plugged into the muxer.. it contains the names of all the audio files /// that have to be muxed /// </summary> /// <param name="encodable">encodeable audio streams</param> /// <param name="muxable">muxable Audio Streams with the path filled out and a blank language</param> private void separateEncodableAndMuxableAudioStreams(out AudioJob[] encodable, out MuxStream[] muxable, out AudioEncoderType[] muxTypes) { encodable = this.getConfiguredAudioJobs(); // discards improperly configured ones // the rest of the job is all encodeable muxable = new MuxStream[encodable.Length]; muxTypes = new AudioEncoderType[encodable.Length]; int j = 0; foreach (AudioJob stream in encodable) { muxable[j] = stream.ToMuxStream(); muxTypes[j] = stream.Settings.EncoderType; j++; } }
/// <summary> /// Reallocates the audio array so that it only has the files to be muxed and not the files to be encoded, then muxed /// </summary> /// <param name="audio">All files to be muxed (including the ones which will be encoded first)</param> /// <param name="aStreams">All files being encoded (these will be removed from the audio array)</param> private void removeStreamsToBeEncoded(ref MuxStream[] audio, AudioJob[] aStreams) { List<MuxStream> newAudio = new List<MuxStream>(); foreach (MuxStream stream in audio) { bool matchFound = false; foreach (AudioJob a in aStreams) { if (stream.path == a.Output) { matchFound = true; // In this case we have found a file which needs to be encoded break; } } if (!matchFound) // in this case we have not found any files which will be encoded first to produce this file { newAudio.Add(stream); } } audio = newAudio.ToArray(); }
/// <summary> /// handles the go button for automated encoding /// checks if we're in automated 2 pass video mode and that we're not using the snow codec /// then the video and audio configuration is checked, and if it checks out /// the audio job, video jobs and muxing job are generated, audio and video job are linked /// and encoding is started /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void queueButton_Click(object sender, System.EventArgs e) { if (!string.IsNullOrEmpty(this.muxedOutput.Filename)) { FileSize? desiredSize = targetSize.Value; FileSize? splitSize = splitting.Value; if (FileSizeRadio.Checked) log.LogValue("Desired Size ", desiredSize); else if (averageBitrateRadio.Checked) log.LogValue("Projected Bitrate ", string.Format("{0}kbps", projectedBitrateKBits.Text)); log.LogValue("Split Size ", splitSize); MuxStream[] audio; AudioJob[] aStreams; AudioEncoderType[] muxTypes; separateEncodableAndMuxableAudioStreams(out aStreams, out audio, out muxTypes); MuxStream[] subtitles = new MuxStream[0]; string chapters = ""; string videoInput = vInfo.VideoInput; string videoOutput = vInfo.VideoOutput; string muxedOutput = this.muxedOutput.Filename; ContainerType cot = this.container.SelectedItem as ContainerType; if (addSubsNChapters.Checked) { AdaptiveMuxWindow amw = new AdaptiveMuxWindow(mainForm); amw.setMinimizedMode(videoOutput, videoStream.Settings.EncoderType, jobUtil.getFramerate(videoInput), audio, muxTypes, muxedOutput, splitSize, cot); if (amw.ShowDialog() == DialogResult.OK) amw.getAdditionalStreams(out audio, out subtitles, out chapters, out muxedOutput, out cot); else // user aborted, abort the whole process return; } removeStreamsToBeEncoded(ref audio, aStreams); mainForm.Jobs.addJobsWithDependencies(vUtil.GenerateJobSeries(this.videoStream, muxedOutput, aStreams, subtitles, chapters, desiredSize, splitSize, cot, this.prerender, audio, log, this.device.Text)); this.Close(); } }
public JobChain GenerateMuxJobs(VideoStream video, decimal? framerate, MuxStream[] audioStreamsArray, MuxableType[] audioTypes, MuxStream[] subtitleStreamsArray, MuxableType[] subTypes, string chapterFile, MuxableType chapterInputType, ContainerType container, string output, FileSize? splitSize, List<string> inputsToDelete, string deviceType, MuxableType deviceOutputType) { Debug.Assert(splitSize == null || splitSize.Value != FileSize.Empty); MuxProvider prov = mainForm.MuxProvider; List<MuxableType> allTypes = new List<MuxableType>(); allTypes.Add(video.VideoType); allTypes.AddRange(audioTypes); allTypes.AddRange(subTypes); if (chapterInputType != null) allTypes.Add(chapterInputType); if (deviceOutputType != null) allTypes.Add(deviceOutputType); MuxPath muxPath = prov.GetMuxPath(container, splitSize.HasValue, allTypes.ToArray()); List<MuxJob> jobs = new List<MuxJob>(); List<MuxStream> subtitleStreams = new List<MuxStream>(subtitleStreamsArray); List<MuxStream> audioStreams = new List<MuxStream>(audioStreamsArray); int index = 0; int tempNumber = 1; string previousOutput = null; foreach (MuxPathLeg mpl in muxPath) { List<string> filesToDeleteThisJob = new List<string>(); MuxJob mjob = new MuxJob(); if (previousOutput != null) { mjob.Settings.MuxedInput = previousOutput; filesToDeleteThisJob.Add(previousOutput); } mjob.NbOfFrames = video.NumberOfFrames; mjob.NbOfBFrames = video.Settings.NbBframes; mjob.Codec = video.Settings.Codec.ToString(); string fpsFormated = String.Format("{0:##.###}", framerate); // this formating is required for mkvmerge at least to avoid fps rounding error mjob.Settings.Framerate = Convert.ToDecimal(fpsFormated); mjob.Settings.VideoName = video.Settings.VideoName; string tempOutputName = Path.Combine(Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output) + tempNumber + "."); tempNumber++; foreach (MuxableType o in mpl.handledInputTypes) { if (o.outputType is VideoType) { mjob.Settings.VideoInput = video.Output; if (inputsToDelete.Contains(video.Output)) filesToDeleteThisJob.Add(video.Output); mjob.Settings.DAR = video.DAR; } else if (o.outputType is AudioType) { MuxStream stream = audioStreams.Find(delegate(MuxStream m) { return (VideoUtil.guessAudioType(m.path) == o.outputType); }); if (stream != null) { mjob.Settings.AudioStreams.Add(stream); audioStreams.Remove(stream); if (inputsToDelete.Contains(stream.path)) filesToDeleteThisJob.Add(stream.path); } } else if (o.outputType is SubtitleType) { MuxStream stream = subtitleStreams.Find(delegate(MuxStream m) { return (VideoUtil.guessSubtitleType(m.path) == o.outputType); }); if (stream != null) { mjob.Settings.SubtitleStreams.Add(stream); subtitleStreams.Remove(stream); if (inputsToDelete.Contains(stream.path)) filesToDeleteThisJob.Add(stream.path); } } else if (o.outputType is ChapterType) { if ((VideoUtil.guessChapterType(chapterFile) == o.outputType)) mjob.Settings.ChapterFile = chapterFile; if (inputsToDelete.Contains(chapterFile)) filesToDeleteThisJob.Add(chapterFile); } else if (o.outputType is DeviceType) { if ((VideoUtil.guessDeviceType(deviceType) == o.outputType)) mjob.Settings.DeviceType = deviceType; } } foreach (MuxStream s in mjob.Settings.AudioStreams) { audioStreams.Remove(s); } foreach (MuxStream s in mjob.Settings.SubtitleStreams) { subtitleStreams.Remove(s); } mjob.FilesToDelete.AddRange(filesToDeleteThisJob); if (index == muxPath.Length - 1) { mjob.Settings.MuxedOutput = output; mjob.Settings.SplitSize = splitSize; mjob.Settings.DAR = video.DAR; mjob.ContainerType = container; } else { ContainerType cot = mpl.muxerInterface.GetContainersInCommon(muxPath[index + 1].muxerInterface)[0]; mjob.Settings.MuxedOutput = tempOutputName + cot.Extension; mjob.ContainerType = cot; } previousOutput = mjob.Settings.MuxedOutput; index++; jobs.Add(mjob); if (string.IsNullOrEmpty(mjob.Settings.VideoInput)) mjob.Input = mjob.Settings.MuxedInput; else mjob.Input = mjob.Settings.VideoInput; mjob.Output = mjob.Settings.MuxedOutput; mjob.MuxType = mpl.muxerInterface.MuxerType; } return new SequentialChain(jobs.ToArray()); }