使用带有 Python 的 COM 通过 DirectShow 访问网络摄像头
Accessing webcam via DirectShow using COM with Python
我想获得对 webcam properties using DirectShow's IAMVideoProcAmp 的低级别访问权限。
这里用到了几个Python模块)pywin32
, pywintypes
, comtypes
, win32com
, pythoncom
)上下文,它们似乎以某种方式相关。但是我不知道从哪里开始。
我找到了一些示例 (here, here, here),但我无法弄清楚如何获取 IID / CLSID 来使用
import win32com.client
clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
ShellWindows=win32com.client.Dispatch(clsid)
或使用清晰的名称,例如
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
或
from comtypes import client, GUID
graph = client.CreateObject(some_CLSID)
graph.QueryInterface(...)
有人可以帮我解决这个问题吗?
我找到了另一个示例 (dshow.py),但它有一些我找不到的依赖项 (interfaces
、uuids
)。
Microsoft 的 This 页面将程序列为
Call QueryInterface on the capture filter for the IAMVideoProcAmp interface.
或
Query the capture filter for the IAMCameraControl.
并为此声明了一些 C++ 代码:
// 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);
编辑:
我终于找到了一些到目前为止看起来不错的代码:
它似乎完全符合我想写的内容,并使用了来自
DirectShow(see here):
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video 自称是 "a port of the VideoCapture module in pure Python using ctypes and comtypes."
它正在使用 DirectShow.tlb
文件(无论是什么)来获取定义
进入 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.
确定复制代码所需的值
再看一眼您 post 末尾的代码摘录,我意识到您只需要 IAMVideoProcAmp
的 IID 而不是 CLSID 即可获取它的实例.
查看this source of strmif.h的第8733行,注明接口需要header,发现IID_IAMVideoProcAmp
是C6E13360-30AC-11d0-A18C-00A0C9118956
。
在 strmif.h 的这一部分之上,您可以识别哪些整数对应于 tagVideoProcAmpProperty
枚举中的哪些属性,例如 0
对应 VideoProcAmp_Brightness
。在 strmif.h 的这一部分下面,您可以识别 IAMVideoProcAmpVtbl
VTable 中的哪些整数对应于哪些函数,例如 3
对应 GetRange
。我不熟悉如何与 Python 中的 COM objects 交互,但在 Java 中,您需要确定这些 属性 和函数索引才能复制 C++ 代码摘录演示如何获取 IAmVideoProcAmp
.
的实例
正在获取 IAMVideoProcAmp
的一个实例
您可能已经注意到,C++ 代码摘录在名为 pCap
的对象上调用 QueryInterface
并指出您需要 "Query the capture filter for the IAMVideoProcAmp interface." This sibling of the article you linked 解释如何执行此操作:
To create a DirectShow capture filter for the device, call the IMoniker::BindToObject method to get an IBaseFilter pointer. Then call IFilterGraph::AddFilter to add the filter to the filter graph:
IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr))
{
hr = m_pGraph->AddFilter(pCap, L"Capture Filter");
}
既然您知道如何获取 pCap
,您会注意到您需要一个名为 pMoniker
的东西,它在同一篇文章的前面部分已经定义。代码比较长,这里省略
在 Python
中完成所有这些
正如我之前提到的,我从未使用过任何 Python COM 库,所以我不能轻易地举出一个例子,但你的目标应该是在 Python 中复制函数调用C++ 示例以获取 IAMVideoProcAmp
的实例并修改它们以满足您的需要。
我终于找到了一些可用的示例库:
它完全符合我想要实现的目标,并使用了来自
DirectShow(see here):
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video 自称是 "a port of the VideoCapture module in pure Python using ctypes and comtypes."
它正在使用 DirectShow.tlb
文件(无论是什么)来获取定义
进入 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.
导入是在 __init__.py
中自动生成的,可以轻松使用:
from api.objects import ..., IMediaControl, IAMVideoProcAmp, IAMCameraControl, ...
并且可以使用
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)
然后您可以结合文档中所述的 enum
使用这些函数,例如
# CameraControl_Exposure = 4
print(d.get_camera_control_property(4))
我想获得对 webcam properties using DirectShow's IAMVideoProcAmp 的低级别访问权限。
这里用到了几个Python模块)pywin32
, pywintypes
, comtypes
, win32com
, pythoncom
)上下文,它们似乎以某种方式相关。但是我不知道从哪里开始。
我找到了一些示例 (here, here, here),但我无法弄清楚如何获取 IID / CLSID 来使用
import win32com.client
clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
ShellWindows=win32com.client.Dispatch(clsid)
或使用清晰的名称,例如
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
或
from comtypes import client, GUID
graph = client.CreateObject(some_CLSID)
graph.QueryInterface(...)
有人可以帮我解决这个问题吗?
我找到了另一个示例 (dshow.py),但它有一些我找不到的依赖项 (interfaces
、uuids
)。
This 页面将程序列为
Call QueryInterface on the capture filter for the IAMVideoProcAmp interface.
或
Query the capture filter for the IAMCameraControl.
并为此声明了一些 C++ 代码:
// 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);
编辑: 我终于找到了一些到目前为止看起来不错的代码:
它似乎完全符合我想写的内容,并使用了来自 DirectShow(see here):
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video 自称是 "a port of the VideoCapture module in pure Python using ctypes and comtypes."
它正在使用 DirectShow.tlb
文件(无论是什么)来获取定义
进入 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.
确定复制代码所需的值
再看一眼您 post 末尾的代码摘录,我意识到您只需要 IAMVideoProcAmp
的 IID 而不是 CLSID 即可获取它的实例.
查看this source of strmif.h的第8733行,注明接口需要header,发现IID_IAMVideoProcAmp
是C6E13360-30AC-11d0-A18C-00A0C9118956
。
在 strmif.h 的这一部分之上,您可以识别哪些整数对应于 tagVideoProcAmpProperty
枚举中的哪些属性,例如 0
对应 VideoProcAmp_Brightness
。在 strmif.h 的这一部分下面,您可以识别 IAMVideoProcAmpVtbl
VTable 中的哪些整数对应于哪些函数,例如 3
对应 GetRange
。我不熟悉如何与 Python 中的 COM objects 交互,但在 Java 中,您需要确定这些 属性 和函数索引才能复制 C++ 代码摘录演示如何获取 IAmVideoProcAmp
.
正在获取 IAMVideoProcAmp
的一个实例
您可能已经注意到,C++ 代码摘录在名为 pCap
的对象上调用 QueryInterface
并指出您需要 "Query the capture filter for the IAMVideoProcAmp interface." This sibling of the article you linked 解释如何执行此操作:
To create a DirectShow capture filter for the device, call the IMoniker::BindToObject method to get an IBaseFilter pointer. Then call IFilterGraph::AddFilter to add the filter to the filter graph:
IBaseFilter *pCap = NULL; hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap); if (SUCCEEDED(hr)) { hr = m_pGraph->AddFilter(pCap, L"Capture Filter"); }
既然您知道如何获取 pCap
,您会注意到您需要一个名为 pMoniker
的东西,它在同一篇文章的前面部分已经定义。代码比较长,这里省略
在 Python
中完成所有这些正如我之前提到的,我从未使用过任何 Python COM 库,所以我不能轻易地举出一个例子,但你的目标应该是在 Python 中复制函数调用C++ 示例以获取 IAMVideoProcAmp
的实例并修改它们以满足您的需要。
我终于找到了一些可用的示例库:
它完全符合我想要实现的目标,并使用了来自 DirectShow(see here):
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video 自称是 "a port of the VideoCapture module in pure Python using ctypes and comtypes."
它正在使用 DirectShow.tlb
文件(无论是什么)来获取定义
进入 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.
导入是在 __init__.py
中自动生成的,可以轻松使用:
from api.objects import ..., IMediaControl, IAMVideoProcAmp, IAMCameraControl, ...
并且可以使用
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)
然后您可以结合文档中所述的 enum
使用这些函数,例如
# CameraControl_Exposure = 4
print(d.get_camera_control_property(4))