我想使用DirectShow的IAMVideoProcAmp获得对网络摄像头属性的低级访问。
有几个 Python 模块(pywin32
、pywintypes
、comtypes
、win32com
、pythoncom
(用于此上下文,它们似乎以某种方式相关。但我不知道从哪里开始。
我找到了一些例子(这里,这里,这里(,但我无法弄清楚如何让 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的此页面将过程列为
在 IAMVideoProcAmp 接口的捕获筛选器上调用查询接口。
或
查询 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);
编辑: 我终于找到了一些到目前为止看起来不错的代码:
哈拉科
它似乎完全符合我想要编写的内容,并使用了一些元素 直接显示(见这里(:
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video声称是"使用ctypes和comtypes的纯Python中VideoCapture模块的端口"。
它使用DirectShow.tlb
文件(无论是什么(来获取定义 成商品
类型库 (.tlb( 是一个二进制文件,用于存储有关 COM 或 DCOM 对象的属性和方法,其形式为 其他应用程序可在运行时访问。
标识复制代码所需的值
再看一眼您帖子末尾的代码摘录,我意识到您只需要 IID 而不是 CLSID 即可IAMVideoProcAmp
获取它的实例。
查看这个 strmif.h 源代码的第 8733 行,标记为接口的必需标头,我发现IID_IAMVideoProcAmp
C6E13360-30AC-11d0-A18C-00A0C9118956
。
在 strmif.h 的这一部分上方,您可以确定哪些整数对应于tagVideoProcAmpProperty
枚举中的哪些属性,例如0
forVideoProcAmp_Brightness
。在 strmif.h 的这一部分下,您可以确定哪些整数对应于 VTableIAMVideoProcAmpVtbl
中的哪些函数,例如3
forGetRange
。我不熟悉如何在 Python 中与 COM 对象交互,但在 Java 中,您需要确定这些属性和函数索引,以便复制演示如何获取IAmVideoProcAmp
实例的C++代码摘录。
获取IAMVideoProcAmp
实例
您可能已经注意到,C++代码摘录调用了名为pCap
的内容QueryInterface
,并指出您需要"查询 IAMVideoProcAmp 接口的捕获筛选器"。您链接的文章的这个兄弟姐妹解释了如何做到这一点:
若要为设备创建 DirectShow 捕获筛选器,请调用 IMoniker::BindToObject 方法来获取 IBaseFilter 指针。然后调用 IFilterGraph::AddFilter 将筛选器添加到筛选器图中:
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
的实例并对其进行修改以满足您的需求。
我终于找到了一些工作的示例库:
哈拉科
它完全符合我想要实现的目标,并使用了一些元素 直接显示(见这里(:
from comtypes.gen.DirectShowLib import (FilterGraph, CaptureGraphBuilder2, ...)
jaraco.video声称是"使用ctypes和comtypes的纯Python中VideoCapture模块的端口"。
它使用DirectShow.tlb
文件(无论是什么(来获取定义 成商品
类型库 (.tlb( 是一个二进制文件,用于存储有关 COM 或 DCOM 对象的属性和方法,其形式为 其他应用程序可在运行时访问。
导入__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))