static void Main(string[] args) { instance = new HandBrakeInstance(); instance.Initialize(verbosity: 1); instance.ScanCompleted += instance_ScanCompleted; instance.StartScan(SourceFile, previewCount: 10); Console.ReadLine(); }
/// <summary> /// Initializes a new instance of the <see cref="LibScan"/> class. /// </summary> public LibScan() { logging = new StringBuilder(); instance = ServiceManager.HandBrakeInstance; instance.Initialize(1); instance.ScanProgress += this.InstanceScanProgress; instance.ScanCompleted += this.InstanceScanCompleted; HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged; HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged; }
/// <summary> /// Initializes a new instance of the <see cref="LibEncode"/> class. /// </summary> public LibEncode() { // Setup the HandBrake Instance this.instance = new HandBrakeInstance(); this.instance.EncodeCompleted += this.InstanceEncodeCompleted; this.instance.EncodeProgress += this.InstanceEncodeProgress; HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged; HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged; GrowlCommunicator.Register(); }
private void RunJob(string jobName) { this.resetEvent.Reset(); EncodeJob job = EncodeJobsPersist.GetJob("Normal"); if (job.SourceType == SourceType.VideoFolder) { job.SourcePath = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(job.SourcePath)); } if (job.SourceType == SourceType.File) { job.SourcePath = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(job.SourcePath)); } string extension; if (job.EncodingProfile.OutputFormat == OutputFormat.Mkv) { extension = ".mkv"; } else { extension = ".mp4"; } job.OutputPath = Path.Combine(OutputVideoDirectory, jobName + extension); var instance = new HandBrakeInstance(); instance.Initialize(0); instance.ScanCompleted += (sender, e) => { this.resetEvent.Set(); }; instance.StartScan(job.SourcePath, 10); this.resetEvent.WaitOne(); this.resetEvent.Reset(); instance.EncodeCompleted += (sender, e) => { Assert.IsFalse(e.Error); this.resetEvent.Set(); }; instance.StartEncode(job); this.resetEvent.WaitOne(); Assert.IsTrue(File.Exists(job.OutputPath)); var fileInfo = new FileInfo(job.OutputPath); Assert.IsTrue(fileInfo.Length > 1024); }
public void ScanNextJob() { EncodeJobViewModel jobVM = itemsToScan[currentJobIndex]; var onDemandInstance = new HandBrakeInstance(); onDemandInstance.Initialize(Config.LogVerbosity); onDemandInstance.ScanProgress += (o, e) => { lock (this.currentJobIndexLock) { this.currentJobProgress = e.Progress; this.RaisePropertyChanged(() => this.Progress); } }; onDemandInstance.ScanCompleted += (o, e) => { jobVM.HandBrakeInstance = onDemandInstance; if (onDemandInstance.Titles.Count > 0) { Title titleToEncode = Utilities.GetFeatureTitle(onDemandInstance.Titles, onDemandInstance.FeatureTitle); jobVM.Job.Title = titleToEncode.TitleNumber; jobVM.Job.Length = titleToEncode.Duration; jobVM.Job.ChapterStart = 1; jobVM.Job.ChapterEnd = titleToEncode.Chapters.Count; } lock (this.currentJobIndexLock) { this.currentJobIndex++; this.currentJobProgress = 0; this.RaisePropertyChanged(() => this.Progress); if (this.ScanFinished) { DispatchService.BeginInvoke(() => { this.CancelCommand.Execute(null); }); } else { this.ScanNextJob(); } } }; onDemandInstance.StartScan(jobVM.Job.SourcePath, Config.PreviewCount, 0); }
/// <summary> /// The get encode instance. /// </summary> /// <param name="verbosity"> /// The verbosity. /// </param> /// <returns> /// The <see cref="IHandBrakeInstance"/>. /// </returns> public static IHandBrakeInstance GetEncodeInstance(int verbosity) { if (encodeInstance != null) { encodeInstance.Dispose(); encodeInstance = null; } HandBrakeInstance newInstance = new HandBrakeInstance(); newInstance.Initialize(verbosity); encodeInstance = newInstance; return(encodeInstance); }
/// <summary> /// Gets the scanInstance. /// </summary> /// <param name="verbosity"> /// The verbosity. /// </param> /// <returns> /// The <see cref="IHandBrakeInstance"/>. /// </returns> public static IHandBrakeInstance GetScanInstance(int verbosity) { if (scanInstance != null) { scanInstance.Dispose(); scanInstance = null; } HandBrakeInstance newInstance = new HandBrakeInstance(); newInstance.Initialize(verbosity); scanInstance = newInstance; return(scanInstance); }
private void RefreshPreviews() { this.originalScanInstance = this.ScanInstance; this.job = this.mainViewModel.EncodeJob; VCProfile profile = this.job.EncodingProfile; int width, height, parWidth, parHeight; this.ScanInstance.GetSize(this.job.HbJob, out width, out height, out parWidth, out parHeight); // If we're rotating by 90 degrees, swap width and height for sizing purposes. if (profile.Rotation == VCPictureRotation.Clockwise90 || profile.Rotation == VCPictureRotation.Clockwise270) { int temp = width; width = height; height = temp; temp = parWidth; parWidth = parHeight; parHeight = temp; } if (parWidth <= 0 || parHeight <= 0) { this.HasPreview = false; this.Title = PreviewRes.NoVideoSourceTitle; Ioc.Container.GetInstance<ILogger>().LogError("HandBrake returned a negative pixel aspect ratio. Cannot show preview."); return; } this.PreviewDisplayHeight = height; this.PreviewDisplayWidth = width * ((double)parWidth / parHeight); // Update the number of previews. this.previewCount = this.ScanInstance.PreviewCount; if (this.selectedPreview >= this.previewCount) { this.selectedPreview = this.previewCount - 1; this.RaisePropertyChanged(() => this.SelectedPreview); } this.RaisePropertyChanged(() => this.PreviewCount); this.HasPreview = true; lock (this.imageSync) { this.previewImageCache = new BitmapSource[this.previewCount]; updateVersion++; // Clear main work queue. this.previewImageWorkQueue.Clear(); this.imageFileCacheFolder = Path.Combine(Utilities.ImageCacheFolder, Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture), updateVersion.ToString(CultureInfo.InvariantCulture)); if (!Directory.Exists(this.imageFileCacheFolder)) { Directory.CreateDirectory(this.imageFileCacheFolder); } // Clear old images out of the file cache. this.ClearImageFileCache(); this.imageFileSync = new List<object>(this.previewCount); for (int i = 0; i < this.previewCount; i++) { this.imageFileSync.Add(new object()); } this.BeginBackgroundImageLoad(); } if (parWidth == parHeight) { this.Title = string.Format(PreviewRes.PreviewWindowTitleSimple, width, height); } else { this.Title = string.Format( PreviewRes.PreviewWindowTitleComplex, Math.Round(this.PreviewDisplayWidth), Math.Round(this.PreviewDisplayHeight), width, height); } }
/// <summary> /// Starts a scan of a video source /// </summary> /// <param name="path">The path to scan.</param> /// <param name="jobVM">The encode job choice to apply after the scan is finished.</param> private void StartScan(string path, EncodeJobViewModel jobVM = null) { this.ClearVideoSource(); this.ScanProgress = 0; HandBrakeInstance oldInstance = this.scanInstance; this.logger.Log("Starting scan: " + path); this.scanInstance = new HandBrakeInstance(); this.scanInstance.Initialize(Config.LogVerbosity); this.scanInstance.ScanProgress += (o, e) => { this.ScanProgress = e.Progress * 100; }; this.scanInstance.ScanCompleted += (o, e) => { DispatchService.Invoke(() => { this.ScanningSource = false; if (this.scanCancelledFlag) { this.SelectedSource = null; this.RaisePropertyChanged(() => this.SourcePicked); if (this.ScanCancelled != null) { this.ScanCancelled(this, new EventArgs()); } this.logger.Log("Scan cancelled"); if (this.pendingScan != null) { this.SetSource(this.pendingScan); this.pendingScan = null; } } else { this.SourceData = new VideoSource { Titles = this.scanInstance.Titles, FeatureTitle = this.scanInstance.FeatureTitle }; // If scan failed source data will be null. if (this.sourceData != null) { if (jobVM != null) { this.ApplyEncodeJobChoices(jobVM); } if (jobVM == null && this.SelectedSource != null && (this.SelectedSource.Type == SourceType.File || this.SelectedSource.Type == SourceType.VideoFolder)) { SourceHistory.AddToHistory(this.SourcePath); } } this.logger.Log("Scan completed"); } this.logger.Log(""); }); }; this.ScanError = false; this.ScanningSource = true; this.scanCancelledFlag = false; this.scanInstance.StartScan(path, Config.PreviewCount, TimeSpan.FromSeconds(Config.MinimumTitleLengthSeconds)); if (oldInstance != null) { this.ProcessingVM.CleanupHandBrakeInstanceIfUnused(oldInstance); } }
// Brings up specified job for editing, doing a scan if necessary. public void EditJob(EncodeJobViewModel jobVM, bool isQueueItem = true) { VCJob job = jobVM.Job; if (this.PresetsVM.SelectedPreset.IsModified) { MessageBoxResult dialogResult = Utilities.MessageBox.Show(this, MainRes.SaveChangesPresetMessage, MainRes.SaveChangesPresetTitle, MessageBoxButton.YesNoCancel); if (dialogResult == MessageBoxResult.Yes) { this.PresetsVM.SavePreset(); } else if (dialogResult == MessageBoxResult.No) { this.PresetsVM.RevertPreset(userInitiated: false); } else if (dialogResult == MessageBoxResult.Cancel) { return; } } if (jobVM.HandBrakeInstance != null && jobVM.HandBrakeInstance == this.ScanInstance) { this.ApplyEncodeJobChoices(jobVM); Messenger.Default.Send(new RefreshPreviewMessage()); } else if (jobVM.VideoSource != null) { // Set current scan to cached scan this.scanInstance = jobVM.HandBrakeInstance; this.SourceData = jobVM.VideoSource; this.LoadVideoSourceMetadata(job, jobVM.VideoSourceMetadata); this.ApplyEncodeJobChoices(jobVM); } else { string jobPath = job.SourcePath; string jobRoot = Path.GetPathRoot(jobPath); // We need to reconstruct the source metadata since the program has shut down since the job // was created. var videoSourceMetadata = new VideoSourceMetadata(); switch (job.SourceType) { case SourceType.Dvd: DriveInformation driveInfo = this.DriveCollection.FirstOrDefault(d => string.Compare(d.RootDirectory, jobRoot, StringComparison.OrdinalIgnoreCase) == 0); if (driveInfo == null) { Ioc.Container.GetInstance<IMessageBoxService>().Show(MainRes.DiscNotInDriveError); return; } videoSourceMetadata.Name = driveInfo.VolumeLabel; videoSourceMetadata.DriveInfo = driveInfo; break; case SourceType.File: videoSourceMetadata.Name = Utilities.GetSourceNameFile(job.SourcePath); break; case SourceType.VideoFolder: videoSourceMetadata.Name = Utilities.GetSourceNameFolder(job.SourcePath); break; } this.LoadVideoSourceMetadata(job, videoSourceMetadata); this.StartScan(job.SourcePath, jobVM); } string presetName = isQueueItem ? MainRes.PresetNameRestoredFromQueue : MainRes.PresetNameRestoredFromCompleted; var queuePreset = new PresetViewModel( new Preset { IsBuiltIn = false, IsModified = false, IsQueue = true, Name = presetName, EncodingProfile = jobVM.Job.EncodingProfile.Clone() }); this.PresetsVM.InsertQueuePreset(queuePreset); if (isQueueItem) { // Since it's been sent back for editing, remove the queue item this.ProcessingVM.EncodeQueue.Remove(jobVM); } this.PresetsVM.SaveUserPresets(); }
/// <summary> /// Cleans up the given HandBrake instance if it's not being used anymore. /// </summary> /// <param name="instance">The instance to clean up.</param> public void CleanupHandBrakeInstanceIfUnused(HandBrakeInstance instance) { foreach (EncodeJobViewModel encodeJobVM in this.EncodeQueue) { if (instance == encodeJobVM.HandBrakeInstance) { return; } } foreach (EncodeResultViewModel resultVM in this.CompletedJobs) { if (instance == resultVM.Job.HandBrakeInstance) { return; } } if (instance == this.main.ScanInstance) { return; } instance.Dispose(); }
public void StartEncode(VCJob job, ILogger logger, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds) { this.logger = logger; this.logger.Log("Starting encode in-process"); this.encoding = true; this.encodeStartEvent = new ManualResetEventSlim(false); this.encodeEndEvent = new ManualResetEventSlim(false); this.instance = new HandBrakeInstance(); this.instance.Initialize(Config.LogVerbosity); this.instance.ScanCompleted += (o, e) => { try { Title encodeTitle = this.instance.Titles.FirstOrDefault(title => title.TitleNumber == job.Title); if (encodeTitle != null) { lock (this.encoderLock) { this.instance.StartEncode(job.HbJob, preview, previewNumber, previewSeconds, overallSelectedLengthSeconds, Config.PreviewCount); this.IsEncodeStarted = true; if (this.EncodeStarted != null) { this.EncodeStarted(this, new EventArgs()); } this.encodeStartEvent.Set(); } } else { if (this.EncodeCompleted != null) { this.EncodeCompleted(this, new EncodeCompletedEventArgs { Error = true }); } this.encodeStartEvent.Set(); this.encodeEndEvent.Set(); } } catch (Exception exception) { this.logger.LogError("Encoding failed. Please report this error so it can be fixed in the future:" + Environment.NewLine + exception); } }; this.instance.EncodeProgress += (o, e) => { // Dispatch to avoid deadlocks on callbacks DispatchService.BeginInvoke(() => { lock (this.encoderLock) { if (this.encoding && this.EncodeProgress != null) { this.EncodeProgress(this, e); } } }); }; this.instance.EncodeCompleted += (o, e) => { if (this.encoding) { if (this.EncodeCompleted != null) { this.EncodeCompleted(this, e); } this.encoding = false; } this.encodeEndEvent.Set(); this.instance.Dispose(); }; this.instance.StartScan(job.SourcePath, Config.PreviewCount, job.Title); this.encoding = true; }
/// <summary> /// Start the service /// </summary> /// <param name="port"> /// The port. /// </param> public void Start(string port) { using (host = new ServiceHost(typeof(ServerService), new Uri(string.Format("net.tcp://127.0.0.1:{0}", port)))) { // Setup a listener host.AddServiceEndpoint(typeof(IServerService), new NetTcpBinding(), "IHbService"); host.Open(); Console.WriteLine("::: HandBrake Isolation Server - Debug Console:::"); Console.WriteLine("Service Started. Waiting for Clients..."); // Setup the services we are going to use. IHandBrakeInstance instance = new HandBrakeInstance(); scanService = new LibScan(instance); encodeService = new LibEncode(new UserSettingService(), instance); // TODO this needs wired up with castle shutdownFlag = new ManualResetEvent(false); shutdownFlag.WaitOne(); } }
public void StartEncode(EncodeJob job, bool preview, int previewNumber, int previewSeconds, double overallSelectedLengthSeconds, int verbosity, int previewCount, bool useDvdNav) { CurrentEncoder = this; this.callback = OperationContext.Current.GetCallbackChannel<IHandBrakeEncoderCallback>(); try { if (this.callback == null) { throw new ArgumentException("Could not get callback channel."); } HandBrakeUtils.MessageLogged += (o, e) => { this.StopOnException(() => { this.callback.OnMessageLogged(e.Message); }); }; HandBrakeUtils.ErrorLogged += (o, e) => { this.StopOnException(() => { this.callback.OnErrorLogged(e.Message); }); }; HandBrakeUtils.SetDvdNav(useDvdNav); this.instance = new HandBrakeInstance(); this.instance.Initialize(verbosity); this.instance.ScanCompleted += (o, e) => { try { Title encodeTitle = this.instance.Titles.FirstOrDefault(title => title.TitleNumber == job.Title); if (encodeTitle != null) { lock (this.encodeLock) { this.instance.StartEncode(job, preview, previewNumber, previewSeconds, overallSelectedLengthSeconds, previewCount); this.callback.OnEncodeStarted(); this.state = EncodeState.Encoding; } } else { this.callback.OnEncodeComplete(true); this.CleanUpAndSignalCompletion(); } } catch (Exception exception) { this.callback.OnException(exception.ToString()); this.CleanUpAndSignalCompletion(); } }; this.instance.EncodeProgress += (o, e) => { this.StopOnException(() => { this.callback.OnEncodeProgress(e.AverageFrameRate, e.CurrentFrameRate, e.EstimatedTimeLeft, e.FractionComplete, e.Pass); }); }; this.instance.EncodeCompleted += (o, e) => { this.state = EncodeState.Finished; try { this.callback.OnEncodeComplete(e.Error); } catch (CommunicationException exception) { WorkerLogger.Log("Got exception when reporting completion: " + exception, isError: true); } finally { this.CleanUpAndSignalCompletion(); } }; this.instance.StartScan(job.SourcePath, previewCount, job.Title); this.state = EncodeState.Scanning; } catch (Exception exception) { this.callback.OnException(exception.ToString()); throw; } }