Bagikan melalui


Memilih Perangkat Pengambilan

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Pengambilan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine , dan Pengambilan Audio/Video di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Untuk memilih perangkat pengambilan audio atau video, gunakan Enumerator Perangkat Sistem, yang dijelaskan dalam topik Menggunakan Enumerator Perangkat Sistem. Enumerator Perangkat Sistem mengembalikan kumpulan moniker perangkat, yang dipilih oleh kategori perangkat. Moniker adalah objek COM yang berisi informasi tentang objek lain. Monikers memungkinkan aplikasi untuk mendapatkan informasi tentang objek tanpa benar-benar membuat objek . Nantinya, aplikasi dapat menggunakan moniker untuk membuat objek . Untuk informasi selengkapnya tentang monikers, lihat dokumentasi untuk IMoniker.

Untuk menggunakan Enumerator Perangkat Sistem, lakukan langkah-langkah berikut.

  1. Panggil CoCreateInstance untuk membuat instans Enumerator Perangkat Sistem.

  2. Panggil ICreateDevEnum::CreateClassEnumerator dan tentukan kategori perangkat sebagai GUID. Untuk menangkap perangkat, kategori berikut relevan.

    GUID Kategori Deskripsi
    CLSID_AudioInputDeviceCategory Perangkat penangkapan audio
    CLSID_VideoInputDeviceCategory Perangkat penangkapan video

     

    Jika kamera video memiliki mikrofon terintegrasi, kamera tersebut akan muncul di kedua kategori. Namun, kamera dan mikrofon diperlakukan sebagai perangkat terpisah oleh sistem, untuk tujuan enumerasi, pembuatan perangkat, dan streaming data.

  3. Metode CreateClassEnumerator mengembalikan pointer ke antarmuka IEnumMoniker . Untuk menghitung moniker, panggil IEnumMoniker::Next.

Kode berikut membuat enumerator untuk kategori perangkat tertentu.

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

Antarmuka IEnumMoniker menghitung daftar antarmuka IMoniker , yang masing-masing mewakili moniker perangkat. Aplikasi dapat membaca properti dari moniker, atau menggunakan moniker untuk membuat filter pengambilan DirectShow untuk perangkat. Properti Moniker dikembalikan sebagai nilai VARIAN . Properti berikut didukung oleh moniker perangkat.

Properti Deskripsi Jenis VARIAN
"FriendlyName" Nama perangkat. VT_BSTR
"Deskripsi" Deskripsi perangkat. VT_BSTR
"DevicePath" String unik yang mengidentifikasi perangkat. (Perangkat penangkapan video saja.) VT_BSTR
"WaveInID" Pengidentifikasi untuk perangkat pengambilan audio. (Perangkat pengambilan audio saja.) VT_I4

 

Properti "FriendlyName" dan "Description" cocok untuk ditampilkan di UI.

  • Properti "FriendlyName" tersedia untuk setiap perangkat. Ini berisi nama yang dapat dibaca manusia untuk perangkat.
  • Properti "Deskripsi" hanya tersedia untuk perangkat camcorder DV dan D-VHS/MPEG. Untuk informasi selengkapnya, lihat Driver MSDV dan Driver MSTape. Jika tersedia, ini berisi deskripsi perangkat yang lebih spesifik daripada properti "FriendlyName". Biasanya termasuk nama vendor.
  • Properti "DevicePath" bukan string yang dapat dibaca manusia, tetapi dijamin unik untuk setiap perangkat penangkapan video pada sistem. Anda dapat menggunakan properti ini untuk membedakan antara dua instans atau lebih dari model perangkat yang sama.
  • Jika properti "WaveInID" ada, itu berarti filter pengambilan DirectShow menggunakan WAVEFORM Audio API secara internal untuk berkomunikasi dengan perangkat. Nilai properti "WaveInID" sesuai dengan pengidentifikasi yang digunakan oleh fungsi waveIn* , seperti waveInOpen.

Untuk membaca properti dari moniker, lakukan langkah-langkah berikut.

  1. Panggil IMoniker::BindToStorage untuk mendapatkan penunjuk ke antarmuka IPropertyBag .
  2. Panggil IPropertyBag::Read untuk membaca properti .

Contoh kode berikut menunjukkan cara menghitung daftar moniker perangkat dan mendapatkan properti .

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

Untuk membuat filter pengambilan DirectShow untuk perangkat, panggil metode IMoniker::BindToObject untuk mendapatkan penunjuk IBaseFilter . Kemudian panggil IFilterGraph::AddFilter untuk menambahkan filter ke grafik filter:

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

Pengambilan Audio

Pengambilan Video