I am unable to get Handbrake to work for me in C#. It keeps throwing the error "Value cannot be null." . As you can see in the screenshot below, I've tried a couple of things based on what I know. I would appreciate any of your guidance to help me get this work.
What I've tried so far (points are not relevant to the error displayed..Just FYI) :
Where am I not on the right track?
Here's 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's more info from the exception copied to 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 :
Now, the exception is Nullreferenceexception with this in the details :
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.
Video encoding is one of the most resource intensive activities for computers. HandBrake's software video encoders, video filters, audio encoders, and other processes benefit from fast CPU and memory. HandBrake's hardware video encoders also benefit from modern GPU hardware.
The x264 software encoder presents an excellent balance between speed and quality, and the H. 264/AVC video it creates is widely compatible with all modern devices. It is the default video encoder in most of HandBrake's official Presets .
Starting the encodeThe Toolbar provides easy access to HandBrake's most common functions. Video encoding requires a lot of computer resources and can take awhile to complete. Some videos may take minutes to create; others may take hours. HandBrake reports its progress during encoding.
Yeah HandBrakeInterop isn't the easiest API to just write some code for; it's more geared toward full encoder GUIs right now; it doesn't fall back on defaults very well. You had a really good idea in just taking the EncodingProfile from the XML.
Here's a working, minimal project that interacts with HandBrakeInterop: 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);
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() } };
RangeType
and the specifics for the range: for example if you pick a RangeType
of Frames
then you need to specify FramesStart
and FramesEnd
. RangeType.All
is easiest since you don't need to specify anything extra.Check out VidCoder if you want to see a full reference implementation of the API. HandBrake has started to use it some but it hasn't gotten around to all the features like static previews and pause/resume.
Update: The code required now looks completely different and targets HandBrake.ApplicationServices.dll. New minimal project: http://engy.us/misc/HBInteropExampleV3.zip
A notable difference is that the encode job is now specified in JSON. This is the exact same JSON blob that is spit out in the encode log in HandBrake/VidCoder, so you can steal it from there and tweak it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With