我无法获得 Handbrake在 C# 中为我工作。它不断抛出错误“值不能为空”。 .正如您在下面的屏幕截图中看到的,我已经根据我所知道的进行了一些尝试。如果您能提供任何指导以帮助我完成这项工作,我将不胜感激。
到目前为止我已经尝试过的(分数与显示的错误无关..仅供引用):
- 在我的电脑上安装了手刹
- 添加了对 HandBrakeInterop.dll 的引用
- 将所有其他所需的 dll 复制到我的调试文件夹,甚至尝试将它们添加为引用
- 尝试从 x86/x64 更改调试版本
我哪里不对?
这是我的代码:
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();
编辑:根据要求,这里是复制到剪贴板的异常的更多信息
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:
编辑:
- 将 handbrakeinstance 和 encodingjob 的实例移到 main 之外并使它们静态化
- 在扫描完成事件中调用 StartEncode
现在,异常是 Nullreferenceexception,详细信息如下:
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:
提前致谢。
最佳答案
是的,HandBrakeInterop 并不是最容易为其编写代码的 API;它现在更适合完整的编码器 GUI;它不能很好地依赖默认值。您从 XML 中获取 EncodingProfile 真是个好主意。
这是一个与 HandBrakeInterop 交互的最小工作项目: http://engy.us/misc/HandBrakeInteropExample.zip
一些相关位:
instance = new HandBrakeInstance();
instance.Initialize(verbosity: 1);
instance.ScanCompleted += instance_ScanCompleted;
instance.StartScan(SourceFile, previewCount: 10);
- 1 是默认的详细程度。您传入的“5”无效。
- 您可能希望为 StartScan 上的 previewCount 传递一个实际值:它使用这些静态预览来执行自动裁剪检测和组合检测等操作。
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() } };
- 您需要传入要编码的标题(从 1 开始的索引)。对于文件,这很少相关;该功能专为 DVD/蓝光扫描而设计。
- 您必须同时传递
RangeType
和范围的具体信息:例如,如果您选择Frames
的RangeType
,那么您需要指定FramesStart
和FramesEnd
。RangeType.All
最简单,因为您不需要指定任何额外的内容。 - 您需要指定所选音轨索引的列表(从 1 开始)。通常对文件没有用,但对具有多种语言的 DVD/蓝光光盘有用。
- 现在你必须在字幕下给它一些东西,否则它会崩溃。这实际上是一个错误;有一些情况我没有正确防守。我会在未来解决这个问题。
查看 VidCoder如果您想查看 API 的完整引用实现。 HandBrake 已经开始使用它,但还没有使用到静态预览和暂停/恢复等所有功能。
更新:现在所需的代码看起来完全不同并且以 HandBrake.ApplicationServices.dll 为目标。新的最小项目:http://engy.us/misc/HBInteropExampleV3.zip
一个显着的区别是编码作业现在是在 JSON 中指定的。这与 HandBrake/VidCoder 的编码日志中吐出的 JSON blob 完全相同,因此您可以从那里窃取它并进行调整。
关于c# - 让手刹编码器工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16762527/