How can i use DirectShowLib to capture the elgato video stream window?

1.1k views Asked by At

I have elgato capture device connected to my pc and i'm trying to capture and watch live the window of the elgato capture device.

I searched in google and found this answer:

Can you use Elgato's HDMIComponent Game Capture HD as a video-in device in C#?

This is the code:

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();

I created a new form in my project and added the DirectShowLib-2005 dll Then i added in the top of the new form:

using DirectShowLib;

Before the constructor added the global vars:

IFilterGraph2 graph;
ICaptureGraphBuilder2 captureGraph;
IBaseFilter elgatoFilter;
IBaseFilter smartTeeFilter;
IBaseFilter videoRendererFilter;
Size videoSize;

Then in the constructor i added the rest of the code. And i'm getting now few errors:

On this line the variable rot is not exist:

rot = new DsROTEntry(graph);

In the four lines that use the method GetPin so the method GetPin not exist:

IPin outPin = GetPin(PinDirection.Output, "Video", elgatoFilter);
IPin inPin = GetPin(PinDirection.Input, smartTeeFilter);
outPin = GetPin(PinDirection.Output, "Preview", smartTeeFilter);
inPin = GetPin(PinDirection.Input, videoRendererFilter);

On this line:

vw.put_Owner(videoFeed.Handle);

The variable videoFeed not exist.

And in the end this two lines:

mediaControl = graph as IMediaControl;
mediaControl.Run();

mediaControl not exist.

What am i missing ?

1

There are 1 answers

6
Roman Ryltsov On BEST ANSWER

videoFeed is your control which is to host video you are embedding.

mediaControl would be a variable of type IMediaControl:

IMediaControl mediaControl = graph as IMediaControl;
mediaControl.Run();

GetPin is this or similar; DsROTEntry is not mandatory but helps inspect filter graph externally using GraphEdit or similar tool.