ビデオ入力デバイス名を取得する

ここでは、ビデオカメラ(デスクトップカメラ、DVカメラなど)やTVチューナーデバイスの名前を取得する方法を説明したいと思います。 (注意)ここの例では、サンプルを簡潔にするためにエラー処理を書いていません。

とりあえず、コードを書いてみる

まず、何も考えずに以下のコードを書いてみましょう。 このコードは、発見したビデオ入力デバイスのFriendlyNameを一つずつ表示します。 例えば、一番最初に発見したビデオキャプチャデバイスがDVカメラであった場合、MessageBoxで「Microsoft DV Camera and VCR」と表示されます。


#include <stdio.h>

#include <dshow.h>

int
main()
{
 // 補足情報)英単語の日本語訳
 //   Enumerate : 列挙、一覧
 //   Moniker   : あだ名
 ICreateDevEnum *pCreateDevEnum = NULL;
 IEnumMoniker *pEnumMoniker = NULL;
 IMoniker *pMoniker = NULL;
 ULONG nFetched = 0;

 // COMを初期化
 CoInitialize(NULL);

 // デバイスを列挙するためのCreateDevEnumを生成
 CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, 
   IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
    
 // VideoInputDeviceを列挙するためのEnumMonikerを生成 
 pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
   &pEnumMoniker, 0);
 if (pEnumMoniker == NULL) {
   // 接続された映像入力デバイスが一つも無い場合にはこのif文に入ります
   printf("no device\n");
   return 0;
 }

 // EnumMonikerをResetする
 // Resetすると、先頭から数えなおします
 pEnumMoniker->Reset();

 // 最初のMonikerを取得
 while (pEnumMoniker->Next(1, &pMoniker, &nFetched) == S_OK) {
   // get the device friendly name:
   IPropertyBag *pPropertyBag;
   TCHAR devname[128];

   // IPropertyBagにbindする
   pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
     (void **)&pPropertyBag);

   // Friendly nameを取得するための入れ物
   VARIANT varFriendlyName;
   varFriendlyName.vt = VT_BSTR;

   // FriendlyNameを取得
   pPropertyBag->Read(L"FriendlyName", &varFriendlyName, 0);

   // 取得したFriendlyNameをコピー
#ifdef UNICODE
   // 念のためUNICODEの時のコード
   _tcscpy(devname, varFriendlyName.bstrVal);
#else
   // 特に何もしなければ、UNICODEではなく、こちらになるはずです
   WideCharToMultiByte(CP_ACP, 0,
     varFriendlyName.bstrVal, -1, devname, sizeof(devname), 0, 0);
#endif      

   // 結果を表示
   MessageBox(NULL, devname, "DEVICE NAME", MB_OK);

   // 資源を解放
   VariantClear(&varFriendlyName);

   // 資源を解放
   pMoniker->Release();
   pPropertyBag->Release();
 }

 // 資源を解放
 pEnumMoniker->Release();
 pCreateDevEnum->Release();

 // COM終了
 CoUninitialize();

 return 0;
}

このサンプルはデバイスのFriendlyNameだけを表示しています。 例えば、デスクトップカメラ、DVカメラ、TVチューナーデバイスなどが同時にある場合、それらを選択するUIを作りたいと思ったときなどに上記例を改造すると良いでしょう。