Search code examples
pythonpywin32win32compython.netcomtypes

Accessing webcam via DirectShow using COM with Python


I want to get low level access to webcam properties using DirectShow's IAMVideoProcAmp.

There are several Python modules )pywin32, pywintypes, comtypes, win32com, pythoncom) that are used in this context and they seem to be related somehow. But I have no clue where to start.

I found some examples (here, here, here) but I could not figure out how to get a IID / CLSID to use like

import win32com.client
clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
ShellWindows=win32com.client.Dispatch(clsid)

or with a clear name like

import win32com.client
xl = win32com.client.Dispatch("Excel.Application")

or

from comtypes import client, GUID
graph = client.CreateObject(some_CLSID)
graph.QueryInterface(...)

Can someone help me with this?

I found another example (dshow.py), but it has some dependencies that I could not find (interfaces, uuids).

This page from Microsoft lists the procedures as

Call QueryInterface on the capture filter for the IAMVideoProcAmp interface.

or

Query the capture filter for the IAMCameraControl.

and states some C++ code for this:

// Query the capture filter for the IAMVideoProcAmp interface.
IAMVideoProcAmp *pProcAmp = 0;
hr = pCap->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
hr = m_pProcAmp->GetRange(VideoProcAmp_Brightness, &Min, &Max, &Step,
    &Default, &Flags);

Edit: I finally found some code that looks good so far:

jaraco

It seem to do exactly what I am trying to write and uses some elements from DirectShow (see here):

from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)

jaraco.video claims to be "a port of the VideoCapture module in pure Python using ctypes and comtypes."

It is using a DirectShow.tlb file (whatever that is) to get the definitions into comtypes

A type library (.tlb) is a binary file that stores information about a COM or DCOM object's properties and methods in a form that is accessible to other applications at runtime.


Solution

  • I finally found some example library that is working:

    jaraco

    It does exactly what I am trying to achive and uses some elements from DirectShow (see here):

    from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
    

    jaraco.video claims to be "a port of the VideoCapture module in pure Python using ctypes and comtypes."

    It is using a DirectShow.tlb file (whatever that is) to get the definitions into comtypes

    A type library (.tlb) is a binary file that stores information about a COM or DCOM object's properties and methods in a form that is accessible to other applications at runtime.

    The imports are auto-generated in __init__.py and can be used easily:

    from api.objects import ..., IMediaControl, IAMVideoProcAmp, IAMCameraControl, ...
    

    and can be used

    def _get_camera_control(self):
        return self._get_graph_builder_interface(IAMCameraControl)
    
    def get_camera_control_property(self, i):
    
        video_properties = self._get_camera_control()
        return video_properties.Get(i)
    

    Then you can use the functions in combination with the enum stated in the docs, e.g.

    # CameraControl_Exposure = 4
    print(d.get_camera_control_property(4))