Getting a Handbrake Encoder to Work

I can't get Handbrake to work for me in C #. He continues to throw the error β€œThe value cannot be empty.” As you can see in the screenshot below, I tried a couple of things based on what I know. I would appreciate any of your guidance to help me get this job.

Handbrake Encoder error

What I have tried so far (the dots do not refer to the error displayed ... Just FYI):

  • Installed hand brake on my computer
  • Added link to HandBrakeInterop.dll
  • I copied all the other necessary DLL files to the debug folder and even tried to add them as links
  • Tried changing debug versions from x86 / x64

Where am I not on the right track?

Here is my code:

HandBrake.Interop.HandBrakeInstance objHb = new HandBrake.Interop.HandBrakeInstance(); HandBrake.Interop.Model.EncodeJob objJob = new HandBrake.Interop.Model.EncodeJob(); objJob.SourceType = HandBrake.Interop.Model.SourceType.File; EncodingProfile objProfile = new EncodingProfile(); objProfile.OutputFormat = Container.Mp4; objProfile.VideoEncodeRateType = VideoEncodeRateType.ConstantQuality; objProfile.IPod5GSupport = true; objProfile.PreferredExtension = OutputExtension.Mp4; // objJob.EncodingProfile = objProfile; objJob.SourcePath = AppDomain.CurrentDomain.BaseDirectory + "1.flv"; objJob.OutputPath = AppDomain.CurrentDomain.BaseDirectory + "1.mp4"; //objHb.Titles.Add(new HandBrake.Interop.SourceData.Title()); XmlSerializer objSerializer = new XmlSerializer(typeof(EncodingProfile)); MemoryStream mem=new MemoryStream(File.ReadAllBytes(AppDomain.CurrentDomain.BaseDirectory + "normal.xml")); var objPresetFromFile = objSerializer.Deserialize(mem) as EncodingProfile; objJob.EncodingProfile = objPresetFromFile; objJob.UseDefaultChapterNames = true; // objJob.Title = 1; //HandBrake.Interop.Model.Encoders objHb.EncodeProgress += objHb_EncodeProgress; objHb.EncodeCompleted += objHb_EncodeCompleted; HandBrake.ApplicationServices.Parsing.Title title = new HandBrake.ApplicationServices.Parsing.Title();// new HandBrake.Interop.SourceData.Title(); objHb.Initialize(5); //objHb.Titles = new System.Collections.Generic.List<HandBrake.Interop.SourceData.Title>(); objHb.StartScan(AppDomain.CurrentDomain.BaseDirectory + "1.flv", 0); objJob.SourceType = HandBrake.Interop.Model.SourceType.File; objJob.RangeType = HandBrake.Interop.Model.VideoRangeType.Frames; objHb.StartEncode(objJob); Console.ReadLine(); 

EDIT: as requested here is more information from the exception copied to the clipboard

 System.ArgumentNullException was unhandled HResult=-2147467261 Message=Value cannot be null. Parameter name: source Source=System.Core ParamName=source StackTrace: at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate) at HandBrake.Interop.HandBrakeInstance.GetTitle(Int32 titleNumber) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 1604 at HandBrake.Interop.HandBrakeInstance.GetTitleIndex(Int32 titleNumber) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 1614 at HandBrake.Interop.HandBrakeInstance.StartEncode(EncodeJob job, Boolean preview, Int32 previewNumber, Int32 previewSeconds, Double overallSelectedLengthSeconds) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 411 at HandBrake.Interop.HandBrakeInstance.StartEncode(EncodeJob jobToStart) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 395 at HandBrakeTest.Program.Main(String[] args) in c:\Users\user\Documents\Visual Studio 2012\Projects\HandBrakeTest\HandBrakeTest\Program.cs:line 53 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: 

Edit:

  • The moved instance of handbrakeinstance and encodingjob is outside the main and made them static
  • Call StartEncode in a completed event scan

Now exception: Nullreferenceexception with this in detail:

 System.NullReferenceException was unhandled by user code HResult=-2147467261 Message=Object reference not set to an instance of an object. Source=HandBrakeInterop StackTrace: at HandBrake.Interop.InteropUtilities.ReadStructure[T](IntPtr structPtr) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\InteropUtilities.cs:line 31 at HandBrake.Interop.HandBrakeInstance.StartEncode(EncodeJob job, Boolean preview, Int32 previewNumber, Int32 previewSeconds, Double overallSelectedLengthSeconds) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 412 at HandBrake.Interop.HandBrakeInstance.StartEncode(EncodeJob jobToStart) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 395 at HandBrakeTest.Program.objHb_ScanCompleted(Object sender, EventArgs e) in c:\Users\user\Documents\Visual Studio 2012\Projects\HandBrakeTest\HandBrakeTest\Program.cs:line 65 at HandBrake.Interop.HandBrakeInstance.PollScanProgress() in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 811 at HandBrake.Interop.HandBrakeInstance.<StartScan>b__2(Object o, ElapsedEventArgs e) in c:\HandBrake\Hudson\workspace\Release_WindowsGui64\0.9.9\win\CS\HandBrake.Interop\HandBrakeInterop\HandBrakeInstance.cs:line 752 at System.Timers.Timer.MyTimerCallback(Object state) InnerException: 

Thanks in advance.

+4
source share
2 answers

Yeah HandBrakeInterop is not the easiest API to just write code; now it is more focused on the full graphical interface of the encoder; he does not recede from defaults very well. You had a really good idea just to take EncodingProfile from XML.

The minimal project that works with HandBrakeInterop works here: http://engy.us/misc/HandBrakeInteropExample.zip

Some relevant bits:

 instance = new HandBrakeInstance(); instance.Initialize(verbosity: 1); instance.ScanCompleted += instance_ScanCompleted; instance.StartScan(SourceFile, previewCount: 10); 
  • 1 - default verbosity. The "5" that you passed is not valid.
  • You will probably want to pass the real value for the previewCount to StartScan: it uses these static previews to do things like automatic crop detection and combing.
  var job = new EncodeJob
     {
         EncodingProfile = profile,
         RangeType = VideoRangeType.All,
         Title = 1,
         SourcePath = SourceFile,
         OutputPath = AppDomain.CurrentDomain.BaseDirectory + "Output.mp4",
         ChosenAudioTracks = new List {1},
         Subtitles = new Subtitles
             {
                 SourceSubtitles = new List (),
                 SrtSubtitles = new List ()
             }
     };
  • You need to pass the header for encoding (index based on 1). For files, this is rarely true; This function is for DVD / Blu-ray scan.
  • You must pass both RangeType and the specifics of the range: for example, if you select RangeType of Frames , then you need to specify FramesStart and FramesEnd . RangeType.All easiest since you do not need to specify anything extra.
  • You need to specify a list of selected audio track indices (based on 1). Not recommended for files, but for DVD / Blu-ray discs that have multiple languages.
  • Right now you have to give him something under the subtitles, otherwise he will fail. This is actually a mistake; there were several cases when I was not properly protected. I will fix this in the future.

Check VidCoder if you want to see the full reference implementation of the API. HandBrake started using it, but it did not bypass all the features like static previews and pause / resume.

Refresh . The required code now looks completely different and targets HandBrake.ApplicationServices.dll. New minimal project: http://engy.us/misc/HBInteropExampleV3.zip

The big difference is that the encoding job is now specified in JSON. This is the same JSON blob that spits out in the encoding log in HandBrake / VidCoder, so you can steal it and configure it.

+6
source

I quickly looked through the source code here . It looks like StartScan is actually an asynchronous call, and you should wait for the ScanCompleted event before calling StartEncode .

What seems to be happening is that the Titles collection is null. This is populated with the private PollScanProgress method, which seems to start a timer that checks the progress of the scan. The timer is set to StartScan .

+1
source

Source: https://habr.com/ru/post/1482847/


All Articles