2013-05-26 7 views
4

Я не могу получить Handbrake для работы на меня в C#. Он продолжает бросать ошибку «Значение не может быть пустым». , Как вы можете видеть на скриншоте ниже, я пробовал пару вещей, основываясь на том, что я знаю. Я был бы признателен за любые ваши рекомендации, которые помогут мне получить эту работу.Получение энкодера Handbrake для работы

Handbrake Encoder error

То, что я пытался до сих пор (пункты не относятся к ошибке displayed..Just FYI):

  1. установлен ручной тормоз на моем компьютере
  2. Добавлена ​​ссылка на HandBrakeInterop .dll
  3. Скопировал все остальные необходимые DLL в мою папку отладки и даже попытался добавить их в качестве ссылок
  4. Пробовал изменять версии отладки от x86/x6 4

Где я нахожусь на правильном пути?

Вот мой код:

 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: В соответствии с просьбой, вот больше информации от исключения скопированный в буфер обмена

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:

  1. Переехал handbrakeinstance и экземпляр encodingjob за пределами основной и сделал их статическими
  2. Вызов 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: 

Спасибо заранее.

+1

В этом всплывающем окне есть ссылка: «Скопировать детали исключения в буфер обмена». Вставьте эту информацию в свой вопрос. –

+0

Отредактировано. Надеюсь, что это поможет ... Спасибо. – Josh

ответ

5

Yeah HandBrakeInterop - это не самый простой API, для которого можно просто написать код; теперь он больше ориентирован на полный графический интерфейс кодировщика; он не отступает от дефолтов очень хорошо. У вас была действительно хорошая идея, просто взяв EncodingProfile из XML.

Вот рабочий, минимальный проект, который взаимодействует с 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», которые вы проходили, недействительно.
  • Возможно, вы захотите передать реальное значение для previewCount на StartScan: он использует эти статические превью для того, чтобы делать такие вещи, как автоматическое обнаружение обрезки и расчесывание.
 
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/Blu-ray.
  • Вы должны пройти в обоих RangeType и специфика для диапазона: например, если вы выбираете RangeType из Frames, то вам необходимо указать FramesStart и FramesEnd. RangeType.All проще всего, так как вам не нужно указывать ничего лишнего.
  • Вам необходимо указать список выбранных индексов звуковых дорожек (на основе 1). Обычно не рекомендуется для файлов, но для дисков DVD/Blu-ray, которые имеют несколько языков.
  • Прямо сейчас вы должны дать ему что-то под Субтитрами или он выйдет из строя. Это на самом деле ошибка; было несколько случаев, когда я не был правильно защищен. Я исправлю это в будущем.

Отметьте VidCoder, если вы хотите увидеть полную ссылочную реализацию API. HandBrake начал использовать его, но он не обошел все функции, такие как статические превью и пауза/возобновление.

+0

WOW, Что еще я могу попросить! Спасибо, брат. Я попробовал Vidcoder и заглянул в его исходный код. Infact, для удобства использования, я предпочитаю Vidcoder над ручным тормозом. Реализация системы трубопроводов и очередей слишком хороша. Я хочу, чтобы у VidCoder был API. Спасибо вам за отличную работу. Я также рекомендовал VidCoder на форуме Handbrake. – Josh

+0

@RandomEngy - отличная почта. Я попробовал пример, который вы связали, но я получаю эту ошибку: Не удалось загрузить DLL «hb.dll»: указанный модуль не найден. Есть предположения? Заранее спасибо – steveo40

+0

@ steveo40 hb.dll есть в zip-файле. Возможно, скопируйте его в выходной каталог? – RandomEngy

1

Я быстро просмотрел исходный код here. Похоже, что StartScan фактически является асинхронным вызовом, и вы должны дождаться события ScanCompleted перед вызовом StartEncode.

Что похоже на то, что коллекция Titles является нулевой. Это заполняется частным методом PollScanProgress, который, похоже, запускает таймер, который проверяет ход сканирования. Таймер устанавливается в StartScan.

+0

Спасибо, Майк. Кажется, это заняло еще один шаг. Но, я все еще получаю другое исключение. – Josh

+0

@Josh Я не могу сказать, что именно происходит сейчас, но, возможно, события 'HandBrakeUtils.MessageLogged' и' HandBrakeUtils.ErrorLogged' могут предоставить дополнительную информацию. –

+0

Спасибо за все твои усилия, тоже Майк. Я очень ценю это. – Josh

 Смежные вопросы

  • Нет связанных вопросов^_^