最近的项目用到一个视频模块,要求很简单,就是用本机的摄像头、摄像机或照相机实时拍照获取照片,用 VFW 很容易实现了,不过 avicap 中的函数 capGetDriverDescription 在获取驱动名称的时候,只能获取基本接口驱动的名称 Microsoft WDM Image Capture (Win32),无法获取真实设备的名称,而且没有其它相关函数来实现此功能。
视频相关的开发现在首选 DirectShow,用 Delphi + DirectShow 很容易就实现了:
unit DirectShow;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, ActiveX;
const
CLSID_SystemDeviceEnum: TGUID = (D1:$62BE5D10;D2:$60EB;D3:$11D0;D4:($BD,$3B,$00,$A0,$C9,$11,$CE,$86));
CLSID_VideoInputDeviceCategory: TGUID = (D1:$860BB310;D2:$5D01;D3:$11D0;D4:($BD,$3B,$00,$A0,$C9,$11,$CE,$86));
IID_ICreateDevEnum: TGUID = '{29840822-5B84-11D0-BD3B-00A0C911CE86}';
IID_IPropertyBag: TGUID = '{55272A00-42CB-11CE-8135-00AA004BB851}';
type
ICreateDevEnum = interface(IUnknown)
['{29840822-5B84-11D0-BD3B-00A0C911CE86}']
function CreateClassEnumerator(const clsidDeviceClass: TGUID;
out ppEnumMoniker: IEnumMoniker; dwFlags: DWORD): HResult; stdcall;
end;
procedure GetVideoDeviceList(List: TStrings);
implementation
procedure GetVideoDeviceList(List: TStrings);
var
SysDevEnum: ICreateDevEnum;
EnumCat: IEnumMoniker;
Moniker: IMoniker;
PropBag: IPropertyBag;
Fetched: LongInt;
VarName: OleVariant;
begin
CoCreateInstance(CLSID_SystemDeviceEnum, nil, CLSCTX_INPROC, IID_ICreateDevEnum, SysDevEnum);
SysDevEnum.CreateClassEnumerator(CLSID_VideoInputDeviceCategory, EnumCat, 0);
List.Clear;
while EnumCat.Next(1, Moniker, @Fetched) = S_OK do begin
Moniker.BindToStorage(nil, nil, IID_IPropertyBag, PropBag);
PropBag.Read('FriendlyName', VarName, nil);
List.Add(VarName);
PropBag := nil;
Moniker := nil;
end;
EnumCat := nil;
SysDevEnum := nil;
end;
end.