Auswählen eines Erfassungsgeräts

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

Verwenden Sie zum Auswählen eines Audio- oder Videoaufnahmegeräts den Systemgeräte-Enumerator, der im Thema Verwenden des Systemgeräte-Enumerators beschrieben wird. Der Systemgeräte-Enumerator gibt eine Sammlung von Gerätemonikern zurück, die nach Gerätekategorie ausgewählt sind. Ein Moniker ist ein COM-Objekt, das Informationen zu einem anderen Objekt enthält. Moniker ermöglichen es der Anwendung, Informationen zu einem Objekt abzurufen, ohne das Objekt tatsächlich zu erstellen. Später kann die Anwendung den Moniker verwenden, um das -Objekt zu erstellen. Weitere Informationen zu Monikern finden Sie in der Dokumentation zu IMoniker.

Führen Sie die folgenden Schritte aus, um den Systemgeräte-Enumerator zu verwenden.

  1. Rufen Sie CoCreateInstance auf, um eine instance des Systemgeräte-Enumerators zu erstellen.

  2. Rufen Sie ICreateDevEnum::CreateClassEnumerator auf, und geben Sie die Gerätekategorie als GUID an. Für Erfassungsgeräte sind die folgenden Kategorien relevant.

    Kategorie-GUID BESCHREIBUNG
    CLSID_AudioInputDeviceCategory Audioaufnahmegeräte
    CLSID_VideoInputDeviceCategory Videoaufnahmegeräte

     

    Wenn eine Videokamera über ein integriertes Mikrofon verfügt, wird es in beiden Kategorien angezeigt. Kamera und Mikrofon werden jedoch vom System als separate Geräte für Enumerations-, Geräteerstellungs- und Datenstreamings behandelt.

  3. Die CreateClassEnumerator-Methode gibt einen Zeiger auf die IEnumMoniker-Schnittstelle zurück. Um die Moniker aufzulisten, rufen Sie IEnumMoniker::Next auf.

Der folgende Code erstellt einen Enumerator für eine angegebene Gerätekategorie.

#include <windows.h>
#include <dshow.h>

#pragma comment(lib, "strmiids")

HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
    // Create the System Device Enumerator.
    ICreateDevEnum *pDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

    if (SUCCEEDED(hr))
    {
        // Create an enumerator for the category.
        hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
        if (hr == S_FALSE)
        {
            hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
        }
        pDevEnum->Release();
    }
    return hr;
}

Die IEnumMoniker-Schnittstelle listet eine Liste von IMoniker-Schnittstellen auf, die jeweils einen Gerätemoniker darstellen. Die Anwendung kann Eigenschaften aus dem Moniker lesen oder den Moniker verwenden, um einen DirectShow-Erfassungsfilter für das Gerät zu erstellen. Moniker-Eigenschaften werden als VARIANT-Werte zurückgegeben. Die folgenden Eigenschaften werden von Gerätemonikern unterstützt.

Eigenschaft BESCHREIBUNG VARIANT-Typ
"FriendlyName" Der Name des Geräts. VT_BSTR
"Beschreibung" Eine Beschreibung des Geräts. VT_BSTR
"DevicePath" Eine eindeutige Zeichenfolge, die das Gerät identifiziert. (Nur Videoaufnahmegeräte.) VT_BSTR
"WaveInID" Der Bezeichner für ein Audioaufnahmegerät. (Nur Audioaufnahmegeräte.) VT_I4

 

Die Eigenschaften "FriendlyName" und "Description" eignen sich für die Anzeige in einer Benutzeroberfläche.

  • Die Eigenschaft "FriendlyName" ist für jedes Gerät verfügbar. Es enthält einen lesbaren Namen für das Gerät.
  • Die Eigenschaft "Description" ist nur für DV- und D-VHS/MPEG-Camcorder-Geräte verfügbar. Weitere Informationen finden Sie unter MSDV-Treiber und MSTape-Treiber. Falls verfügbar, enthält es eine Beschreibung des Geräts, die spezifischer ist als die Eigenschaft "FriendlyName". In der Regel enthält er den Namen des Anbieters.
  • Die Eigenschaft "DevicePath" ist keine für Menschen lesbare Zeichenfolge, sie ist jedoch garantiert für jedes Videoaufnahmegerät auf dem System eindeutig. Sie können diese Eigenschaft verwenden, um zwischen zwei oder mehr Instanzen desselben Gerätemodells zu unterscheiden.
  • Wenn die Eigenschaft "WaveInID" vorhanden ist, bedeutet dies, dass der DirectShow-Aufnahmefilter die Waveform-Audio-APIs intern für die Kommunikation mit dem Gerät verwendet. Der Wert der "WaveInID"-Eigenschaft entspricht dem Bezeichner, der von den waveIn* -Funktionen verwendet wird, z. B. waveInOpen.

Führen Sie die folgenden Schritte aus, um Eigenschaften aus dem Moniker zu lesen.

  1. Rufen Sie IMoniker::BindToStorage auf, um einen Zeiger auf die IPropertyBag-Schnittstelle zu erhalten.
  2. Rufen Sie IPropertyBag::Read auf, um die Eigenschaft zu lesen.

Das folgende Codebeispiel zeigt, wie Sie eine Liste von Gerätemonikern auflisten und die Eigenschaften abrufen.

void DisplayDeviceInformation(IEnumMoniker *pEnum)
{
    IMoniker *pMoniker = NULL;

    while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
    {
        IPropertyBag *pPropBag;
        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
        if (FAILED(hr))
        {
            pMoniker->Release();
            continue;  
        } 

        VARIANT var;
        VariantInit(&var);

        // Get description or friendly name.
        hr = pPropBag->Read(L"Description", &var, 0);
        if (FAILED(hr))
        {
            hr = pPropBag->Read(L"FriendlyName", &var, 0);
        }
        if (SUCCEEDED(hr))
        {
            printf("%S\n", var.bstrVal);
            VariantClear(&var); 
        }

        hr = pPropBag->Write(L"FriendlyName", &var);

        // WaveInID applies only to audio capture devices.
        hr = pPropBag->Read(L"WaveInID", &var, 0);
        if (SUCCEEDED(hr))
        {
            printf("WaveIn ID: %d\n", var.lVal);
            VariantClear(&var); 
        }

        hr = pPropBag->Read(L"DevicePath", &var, 0);
        if (SUCCEEDED(hr))
        {
            // The device path is not intended for display.
            printf("Device path: %S\n", var.bstrVal);
            VariantClear(&var); 
        }

        pPropBag->Release();
        pMoniker->Release();
    }
}

void main()
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr))
    {
        IEnumMoniker *pEnum;

        hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
        if (SUCCEEDED(hr))
        {
            DisplayDeviceInformation(pEnum);
            pEnum->Release();
        }
        hr = EnumerateDevices(CLSID_AudioInputDeviceCategory, &pEnum);
        if (SUCCEEDED(hr))
        {
            DisplayDeviceInformation(pEnum);
            pEnum->Release();
        }
        CoUninitialize();
    }
}

Um einen DirectShow-Erfassungsfilter für das Gerät zu erstellen, rufen Sie die IMoniker::BindToObject-Methode auf, um einen IBaseFilter-Zeiger abzurufen. Rufen Sie dann IFilterGraph::AddFilter auf, um den Filter dem Filterdiagramm hinzuzufügen:

IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr))
{
    hr = m_pGraph->AddFilter(pCap, L"Capture Filter");
}

Audioaufnahme

Videoaufnahme