Array<WebcamInfo> EnumerateWebcams() { Array<WebcamInfo> results; ComPtr<ICreateDevEnum> devEnum; if (!detail::CreateSystemDeviceEnum(&devEnum)) { return results; } ComPtr<IEnumMoniker> enumMoniker; if (FAILED(devEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumMoniker, 0))) { return results; } ComPtr<IMoniker> moniker; for (uint32 index = 0; enumMoniker->Next(1, &moniker, nullptr) == S_OK; ++index) { ComPtr<IPropertyBag> propertyBag; if (FAILED(moniker->BindToStorage(0, 0, IID_IPropertyBag, &propertyBag))) { continue; } VARIANT var; var.vt = VT_BSTR; if (FAILED(propertyBag->Read(L"FriendlyName", &var, 0))) { continue; } WebcamInfo info; info.name = Unicode::FromWString(var.bstrVal); info.index = index; VariantClear(&var); var.vt = VT_BSTR; if (SUCCEEDED(propertyBag->Read(L"DevicePath", &var, 0))) { info.uniqueName = Unicode::FromWString(var.bstrVal); } results << info; } return results; }
HRESULT FilterEnumerator::TryGetDeviceMoniker(wstring deviceName, IMoniker** moniker) noexcept { GUID inputTypes[2]; inputTypes[0] = majorType_; inputTypes[1] = inputMinorType_; GUID outputTypes[2]; outputTypes[0] = majorType_; outputTypes[1] = outputMinorType_; ComPtr<IEnumMoniker> enumMoniker; HRESULT hr = filterMapper_->EnumMatchingFilters( &enumMoniker, 0, TRUE, MERIT_DO_NOT_USE, TRUE, 1, inputTypes, nullptr, nullptr, FALSE, TRUE, 1, outputTypes, nullptr, nullptr); if (FAILED(hr)) throw HResultException(hr); ComPtr<IMoniker> localMoniker; while ((hr = enumMoniker->Next(1, &localMoniker, nullptr)) != S_FALSE) { ComPtr<IPropertyBag> propertyBag; hr = localMoniker->BindToStorage(0, 0, IID_IPropertyBag, &propertyBag); if (FAILED(hr)) continue; ComSupport::VariantString deviceNameVariant; hr = propertyBag->Read(constant_friendly_name, deviceNameVariant, 0); if (FAILED(hr)) continue; if (deviceNameVariant.GetString() == deviceName) { hr = localMoniker.CopyTo(moniker); return hr; } } return E_FAIL; }
vector<wstring> FilterEnumerator::GetDeviceNames() { GUID inputTypes[2]; inputTypes[0] = majorType_; inputTypes[1] = inputMinorType_; GUID outputTypes[2]; outputTypes[0] = majorType_; outputTypes[1] = outputMinorType_; ComPtr<IEnumMoniker> enumMoniker; HRESULT hr = filterMapper_->EnumMatchingFilters( &enumMoniker, 0, TRUE, MERIT_DO_NOT_USE, TRUE, 1, inputTypes, nullptr, nullptr, FALSE, TRUE, 1, outputTypes, nullptr, nullptr); if (FAILED(hr)) throw HResultException(hr); vector<wstring> deciceInfo; ComPtr<IMoniker> moniker; while ((hr = enumMoniker->Next(1, &moniker, nullptr)) != S_FALSE) { ComPtr<IPropertyBag> propertyBag; hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, &propertyBag); if (FAILED(hr)) continue; ComSupport::VariantString deviceNameVariant; hr = propertyBag->Read(constant_friendly_name, deviceNameVariant, 0); if (FAILED(hr)) continue; deciceInfo.emplace_back(deviceNameVariant.GetString()); } return move(deciceInfo); }