【问题标题】:Can you use Elgato's HDMIComponent Game Capture HD as a video-in device in C#?你可以在 C# 中使用 Elgato 的 HDMIComponent Game Capture HD 作为视频输入设备吗?
【发布时间】:2012-12-31 11:07:25
【问题描述】:

我们想知道是否可以从 Elgato 的 Game Capture HD(或类似的东西——型号/品牌无关紧要)捕获视频流,并使用 C# 将其放入窗口中。除了它自己的软件外,我们还没有找到任何关于将该产品与其他任何东西一起使用的信息,我们也没有找到任何其他可以捕获这种东西的硬件。

同样,我们的目标只是让具有 Component Out 的设备出现在屏幕上的窗口中,仅此而已。没有录音,没有屏幕截图,没有覆盖,什么都没有。只是纯粹的“现场”视频。

现在已经找了几个月了,但一无所获,所以我想我会把它扔给 SO 社区。​​p>

【问题讨论】:

    标签: video video-streaming video-capture


    【解决方案1】:

    查找已注册的视频捕获 DirectShow 过滤器,您可以通过其 GUID 加载它。它会在安装 Game Capture HD 1.2.1 时安装。如有问题,请联系 Elgato 支持。

    【讨论】:

    • 我确实联系了他们的二级支持...两次...同调“我们的硬件将与我们的软件一起使用。”我还询问了一个 API,甚至试图将一些信息作为另一个问题的旁白,但也没有骰子。我希望他们只是不支持它,但它确实有效。您是说从经验中知道您可以使用您在此处描述的方法将他们的设备用作高清捕获,还是您只是根据其他视频捕获设备进行推测?如果是前者,你能提供任何示例代码吗?同样,我们只想要一个实时视频源,没有别的。
    【解决方案2】:

    看看this Github 项目。它似乎展示了如何在 c++ DirectShow 应用程序中使用 Elgato 的 Game Capture HD 作为捕获设备。相同的方法应该适用于 c# 项目。

    【讨论】:

      【解决方案3】:

      我知道这是一个老问题,但如果其他人偶然发现它,在 C# 中使用来自 Elgato 采集卡和 DirectShow 的视频流非常容易。下面是一个创建简单图表并预览 Elgato 视频流的示例。

      using DirectShowLib;
      
      DsROTEntry rot; //Used for remotely connecting to graph
      
      IFilterGraph2 graph;
      ICaptureGraphBuilder2 captureGraph;
      IBaseFilter elgatoFilter;
      IBaseFilter smartTeeFilter;
      IBaseFilter videoRendererFilter;
      Size videoSize;
      
      //Set the video size to use for capture and recording
      videoSize = new Size(1280, 720);
      
      //Initialize filter graph and capture graph
      graph = (IFilterGraph2)new FilterGraph();
      captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
      captureGraph.SetFiltergraph(graph);
      rot = new DsROTEntry(graph);
      
      //Create filter for Elgato
      Guid elgatoGuid = new Guid("39F50F4C-99E1-464A-B6F9-D605B4FB5918");
      Type comType = Type.GetTypeFromCLSID(elgatoGuid);
      elgatoFilter = (IBaseFilter)Activator.CreateInstance(comType);
      graph.AddFilter(elgatoFilter, "Elgato Video Capture Filter");
      
      //Create smart tee filter, add to graph, connect Elgato's video out to smart tee in
      smartTeeFilter = (IBaseFilter)new SmartTee();
      graph.AddFilter(smartTeeFilter, "Smart Tee");
      IPin outPin = GetPin(PinDirection.Output, "Video", elgatoFilter);
      IPin inPin = GetPin(PinDirection.Input, smartTeeFilter);
      graph.Connect(outPin, inPin);
      
      //Create video renderer filter, add it to graph, connect smartTee Preview pin to video renderer's input pin
      videoRendererFilter = (IBaseFilter)new VideoRenderer();
      graph.AddFilter(videoRendererFilter, "Video Renderer");
      outPin = GetPin(PinDirection.Output, "Preview", smartTeeFilter);
      inPin = GetPin(PinDirection.Input, videoRendererFilter);
      graph.Connect(outPin, inPin);
      
      //Render stream from video renderer
      captureGraph.RenderStream(PinCategory.Preview, MediaType.Video, videoRendererFilter, null, null);
      
      //Set the video preview to be the videoFeed panel
      IVideoWindow vw = (IVideoWindow)graph;
      vw.put_Owner(videoFeed.Handle);
      vw.put_MessageDrain(this.Handle);
      vw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
      vw.SetWindowPosition(0, 0, 1280, 720);
      
      //Start the preview
      mediaControl = graph as IMediaControl;
      mediaControl.Run();
      
      private IPin GetPin(PinDirection pinDir, IBaseFilter filter)
      {
          IEnumPins epins;
          int hr = filter.EnumPins(out epins);
          if (hr < 0)
              return null;
          IntPtr fetched = Marshal.AllocCoTaskMem(4);
          IPin[] pins = new IPin[1];
          epins.Reset();
          while (epins.Next(1, pins, fetched) == 0)
          {
              PinInfo pinfo;
              pins[0].QueryPinInfo(out pinfo);
              bool found = (pinfo.dir == pinDir);
              DsUtils.FreePinInfo(pinfo);
              if (found)
                  return pins[0];
          }
          return null;
      }
      
      private IPin GetPin(PinDirection pinDir, string name, IBaseFilter filter)
      {
          IEnumPins epins;
          int hr = filter.EnumPins(out epins);
          if (hr < 0)
              return null;
          IntPtr fetched = Marshal.AllocCoTaskMem(4);
          IPin[] pins = new IPin[1];
          epins.Reset();
          while (epins.Next(1, pins, fetched) == 0)
          {
              PinInfo pinfo;
              pins[0].QueryPinInfo(out pinfo);
              bool found = (pinfo.dir == pinDir && pinfo.name == name);
              DsUtils.FreePinInfo(pinfo);
              if (found)
                  return pins[0];
          }
          return null;
      }
      

      【讨论】:

      • Roman 什么是 GetPin 我找不到这个方法?该行中的变量 rot 是什么: rot = new DsROTEntry(graph);烂不存在。我收到 GetPin 和 rot 不存在的错误。
      • 我同意@Simon 的评论,因为这段代码似乎并不完整。西蒙,您能发表评论或进一步详细说明吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多