Freigeben über


Audio-/Videoaufnahme in Media Foundation

Microsoft Media Foundation unterstützt Audio- und Videoaufnahmen. Videoaufnahmegeräte werden über den UVC-Klassentreiber unterstützt und müssen mit UVC 1.1 kompatibel sein. Audioaufnahmegeräte werden über die Windows Audio Session API (WASAPI) unterstützt.

Ein Aufnahmegerät wird in Media Foundation durch ein Medienquellobjekt dargestellt, das die IMFMediaSource- Schnittstelle verfügbar macht. In den meisten Fällen verwendet die Anwendung diese Schnittstelle nicht direkt, sondern verwendet eine API auf höherer Ebene, z. B. die Quellleser-, um das Aufnahmegerät zu steuern.

Aufzählen von Aufnahmegeräten

Führen Sie die folgenden Schritte aus, um die Aufnahmegeräte auf dem System aufzulisten:

  1. Rufen Sie die MFCreateAttributes--Funktion auf, um einen Attributspeicher zu erstellen.

  2. Legen Sie das attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE auf einen der folgenden Werte fest:

    Wert Beschreibung
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID Aufzählen von Audioaufnahmegeräten.
    MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID Auflisten von Videoaufnahmegeräten.

     

  3. Rufen Sie die funktion MFEnumDeviceSources auf. Diese Funktion weist ein Array von IMFActivate Zeiger zu. Jeder Zeiger stellt ein Aktivierungsobjekt für ein Gerät im System dar.

  4. Rufen Sie die IMFActivate::ActivateObject-Methode auf, um eine Instanz der Medienquelle aus einem der Aktivierungsobjekte zu erstellen.

Im folgenden Beispiel wird eine Medienquelle für das erste Videoaufnahmegerät in der Enumerationsliste erstellt:

HRESULT CreateVideoCaptureDevice(IMFMediaSource **ppSource)
{
    *ppSource = NULL;

    UINT32 count = 0;

    IMFAttributes *pConfig = NULL;
    IMFActivate **ppDevices = NULL;

    // Create an attribute store to hold the search criteria.
    HRESULT hr = MFCreateAttributes(&pConfig, 1);

    // Request video capture devices.
    if (SUCCEEDED(hr))
    {
        hr = pConfig->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, 
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
            );
    }

    // Enumerate the devices,
    if (SUCCEEDED(hr))
    {
        hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);
    }

    // Create a media source for the first device in the list.
    if (SUCCEEDED(hr))
    {
        if (count > 0)
        {
            hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));
        }
        else
        {
            hr = MF_E_NOT_FOUND;
        }
    }

    for (DWORD i = 0; i < count; i++)
    {
        ppDevices[i]->Release();
    }
    CoTaskMemFree(ppDevices);
    return hr;
}

Sie können die Aktivierungsobjekte nach verschiedenen Attributen abfragen, einschließlich der folgenden:

  • Das attribut MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME enthält den Anzeigenamen des Geräts. Der Anzeigename eignet sich für die Anzeige für den Benutzer, ist jedoch möglicherweise nicht eindeutig.
  • Für Videogeräte enthält das MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK-Attribut die symbolische Verknüpfung mit dem Gerät. Die symbolische Verknüpfung identifiziert das Gerät auf dem System eindeutig, ist jedoch keine lesbare Zeichenfolge.
  • Für Audiogeräte enthält das attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID die Audioendpunkt-ID des Geräts. Die Audioendpunkt-ID ähnelt einer symbolischen Verknüpfung. Es identifiziert das Gerät auf dem System eindeutig, ist aber keine lesbare Zeichenfolge.

Im folgenden Beispiel wird ein Array von IMFActivate Zeigern verwendet und der Anzeigename jedes Geräts in das Debugfenster gedruckt:

void DebugShowDeviceNames(IMFActivate **ppDevices, UINT count)
{
    for (DWORD i = 0; i < count; i++)
    {
        HRESULT hr = S_OK;
        WCHAR *szFriendlyName = NULL;
    
        // Try to get the display name.
        UINT32 cchName;
        hr = ppDevices[i]->GetAllocatedString(
            MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
            &szFriendlyName, &cchName);

        if (SUCCEEDED(hr))
        {
            OutputDebugString(szFriendlyName);
            OutputDebugString(L"\n");
        }
        CoTaskMemFree(szFriendlyName);
    }
}

Wenn Sie die symbolische Verknüpfung für ein Videogerät bereits kennen, gibt es eine weitere Möglichkeit, die Medienquelle für das Gerät zu erstellen:

  1. Rufen Sie MFCreateAttributes- auf, um einen Attributspeicher zu erstellen.
  2. Legen Sie das attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE auf MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUIDfest.
  3. Legen Sie das attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK auf die symbolische Verknüpfung fest.
  4. Rufen Sie entweder die MFCreateDeviceSource- oder MFCreateDeviceSourceActivate-Funktion auf. Der frühere Gibt einen IMFMediaSource Zeiger zurück. Letzteres gibt einen IMFActivate Zeiger auf ein Aktivierungsobjekt zurück. Sie können das Aktivierungsobjekt verwenden, um die Quelle zu erstellen. (Ein Aktivierungsobjekt kann an einen anderen Prozess gemarstet werden, daher ist es nützlich, wenn Sie die Quelle in einem anderen Prozess erstellen möchten. Weitere Informationen finden Sie unter Aktivierungsobjekte.)

Im folgenden Beispiel wird die symbolische Verknüpfung eines Videogeräts verwendet und eine Medienquelle erstellt.

HRESULT CreateVideoCaptureDevice(PCWSTR *pszSymbolicLink, IMFMediaSource **ppSource)
{
    *ppSource = NULL;
    
    IMFAttributes *pAttributes = NULL;
    IMFMediaSource *pSource = NULL;

    HRESULT hr = MFCreateAttributes(&pAttributes, 2);

    // Set the device type to video.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
            );
    }


    // Set the symbolic link.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetString(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
            (LPCWSTR)pszSymbolicLink
            );            
    }

    if (SUCCEEDED(hr))
    {
        hr = MFCreateDeviceSource(pAttributes, ppSource);
    }

    SafeRelease(&pAttributes);
    return hr;    
}

Es gibt eine gleichwertige Möglichkeit zum Erstellen eines Audiogeräts aus der Audioendpunkt-ID:

  1. Rufen Sie MFCreateAttributes- auf, um einen Attributspeicher zu erstellen.
  2. Legen Sie das attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE auf MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUIDfest.
  3. Legen Sie das attribut MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID auf die Endpunkt-ID fest.
  4. Rufen Sie entweder die MFCreateDeviceSource- oder MFCreateDeviceSourceActivate-Funktion auf.

Im folgenden Beispiel wird eine Audioendpunkt-ID verwendet und eine Medienquelle erstellt.

HRESULT CreateAudioCaptureDevice(PCWSTR *pszEndPointID, IMFMediaSource **ppSource)
{
    *ppSource = NULL;
    
    IMFAttributes *pAttributes = NULL;
    IMFMediaSource *pSource = NULL;

    HRESULT hr = MFCreateAttributes(&pAttributes, 2);

    // Set the device type to audio.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
            );
    }

    // Set the endpoint ID.
    if (SUCCEEDED(hr))
    {
        hr = pAttributes->SetString(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID,
            (LPCWSTR)pszEndPointID
            ); 
    }

    if (SUCCEEDED(hr))
    {
        hr = MFCreateDeviceSource(pAttributes, ppSource);
    }

    SafeRelease(&pAttributes);
    return hr;    
}

Verwenden eines Aufnahmegeräts

Nachdem Sie die Medienquelle für ein Aufnahmegerät erstellt haben, verwenden Sie die Quellleser-, um Daten vom Gerät abzurufen. Der Quellleser liefert Medienbeispiele, die die Aufnahme von Audiodaten oder Videoframes enthalten. Der nächste Schritt hängt von Ihrem Anwendungsszenario ab:

  • Videovorschau: Verwenden Sie Microsoft Direct3D oder Direct2D, um das Video anzuzeigen.
  • Dateierfassung: Verwenden Sie die Sink Writer-, um die Datei zu codieren.
  • Audiovorschau: Verwenden Sie WASAPI-.

Wenn Sie die Audioaufnahme mit der Videoaufnahme kombinieren möchten, verwenden Sie die aggregierten Medienquelle. Die aggregierte Medienquelle enthält eine Sammlung von Medienquellen und kombiniert alle datenströme in einem einzelnen Medienquellobjekt. Rufen Sie zum Erstellen einer Instanz der Aggregatmedienquelle die MFCreateAggregateSource-Funktion auf.

Herunterfahren des Aufnahmegeräts

Wenn das Aufnahmegerät nicht mehr benötigt wird, müssen Sie das Gerät herunterfahren, indem Sie Shutdown für das IMFMediaSource-Objekt aufrufen, das Sie durch Aufrufen MFCreateDeviceSource oder IMFActivate::ActivateObjectabgerufen haben. Fehler beim Aufrufen Herunterfahrens kann zu Speicherverlusten führen, da das System möglicherweise einen Verweis auf IMFMediaSource- Ressourcen beibehalten kann, bis Herunterfahren aufgerufen wird.

if (g_pSource)
{
    g_pSource->Shutdown();
    g_pSource->Release();
    g_pSource = NULL;
}

Wenn Sie eine Zeichenfolge zugewiesen haben, die die symbolische Verknüpfung zu einem Aufnahmegerät enthält, sollten Sie dieses Objekt ebenfalls freigeben.

    CoTaskMemFree(g_pwszSymbolicLink);
    g_pwszSymbolicLink = NULL;

    g_cchSymbolicLink = 0;

Audio-/Videoaufnahme