Partager via


Sélection d’un appareil de capture

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture in Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation au lieu de DirectShow, si possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Pour sélectionner un appareil de capture audio ou vidéo, utilisez l’énumérateur de périphérique système, décrit dans la rubrique Utilisation de l’énumérateur d’appareil système. L’énumérateur d’appareils système retourne une collection de monikers d’appareil, sélectionnés par catégorie d’appareil. Un moniker est un objet COM qui contient des informations sur un autre objet. Les monikers permettent à l’application d’obtenir des informations sur un objet sans créer réellement l’objet. Plus tard, l’application peut utiliser le moniker pour créer l’objet . Pour plus d’informations sur les monikers, consultez la documentation pour IMoniker.

Pour utiliser l’énumérateur d’appareils système, procédez comme suit.

  1. Appelez CoCreateInstance pour créer un instance de l’énumérateur de périphérique système.

  2. Appelez ICreateDevEnum::CreateClassEnumerator et spécifiez la catégorie d’appareil en tant que GUID. Pour les appareils de capture, les catégories suivantes sont pertinentes.

    GUID de catégorie Description
    CLSID_AudioInputDeviceCategory Périphériques de capture audio
    CLSID_VideoInputDeviceCategory Périphériques de capture vidéo

     

    Si une caméra vidéo a un microphone intégré, il apparaît dans les deux catégories. Toutefois, la caméra et le microphone sont traités comme des appareils distincts par le système, à des fins d’énumération, de création d’appareils et de diffusion en continu de données.

  3. La méthode CreateClassEnumerator retourne un pointeur vers l’interface IEnumMoniker . Pour énumérer les monikers, appelez IEnumMoniker::Next.

Le code suivant crée un énumérateur pour une catégorie d’appareil spécifiée.

#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;
}

L’interface IEnumMoniker énumère les interfaces IMoniker , chacune représentant un moniker d’appareil. L’application peut lire les propriétés du moniker ou utiliser le moniker pour créer un filtre de capture DirectShow pour l’appareil. Les propriétés Moniker sont retournées en tant que valeurs VARIANT . Les propriétés suivantes sont prises en charge par les monikers d’appareil.

Propriété Description Type VARIANT
« FriendlyName » Nom de l’appareil VT_BSTR
« Description » Description de l’appareil. VT_BSTR
« DevicePath » Chaîne unique qui identifie l’appareil. (Appareils de capture vidéo uniquement.) VT_BSTR
« WaveInID » Identificateur d’un périphérique de capture audio. (Périphériques de capture audio uniquement.) VT_I4

 

Les propriétés « FriendlyName » et « Description » conviennent à l’affichage dans une interface utilisateur.

  • La propriété « FriendlyName » est disponible pour chaque appareil. Il contient un nom lisible par l’utilisateur pour l’appareil.
  • La propriété « Description » est disponible uniquement pour les appareils caméscopes DV et D-VHS/MPEG. Pour plus d’informations, consultez Pilote MSDV et Pilote MSTape. S’il est disponible, il contient une description de l’appareil qui est plus spécifique que la propriété « FriendlyName ». En règle générale, il inclut le nom du fournisseur.
  • La propriété « DevicePath » n’est pas une chaîne lisible par l’homme, mais elle est garantie d’être unique pour chaque appareil de capture vidéo sur le système. Vous pouvez utiliser cette propriété pour faire la distinction entre plusieurs instances du même modèle d’appareil.
  • Si la propriété « WaveInID » est présente, cela signifie que le filtre de capture DirectShow utilise les API Audio Waveform en interne pour communiquer avec l’appareil. La valeur de la propriété « WaveInID » correspond à l’identificateur utilisé par les fonctions waveIn* , telles que waveInOpen.

Pour lire les propriétés du moniker, procédez comme suit.

  1. Appelez IMoniker::BindToStorage pour obtenir un pointeur vers l’interface IPropertyBag .
  2. Appelez IPropertyBag::Read pour lire la propriété.

L’exemple de code suivant montre comment énumérer une liste de monikers d’appareil et obtenir les propriétés.

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();
    }
}

Pour créer un filtre de capture DirectShow pour l’appareil, appelez la méthode IMoniker::BindToObject pour obtenir un pointeur IBaseFilter . Appelez ensuite IFilterGraph::AddFilter pour ajouter le filtre au graphique de filtre :

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

Audio Capture

Capture vidéo