Abrufen von Ereignissen aus der Netzwerkquelle

Der Quelllöser ermöglicht es einer Anwendung, eine Netzwerkquelle zu erstellen und eine Verbindung mit einer bestimmten URL zu öffnen. Die Netzwerkquelle löst Ereignisse aus, um den Anfang und das Ende des asynchronen Vorgangs zum Öffnen einer Verbindung zu markieren. Eine Anwendung kann sich mithilfe der IMFSourceOpenMonitor-Schnittstelle für diese Ereignisse registrieren.

Diese Schnittstelle macht die IMFSourceOpenMonitor::OnSourceEvent-Methode verfügbar, die die Netzwerkquelle direkt aufruft, wenn sie die URL asynchron öffnet. Die Netzwerkquelle benachrichtigt die Anwendung, wenn sie mit dem Öffnen der URL beginnt, indem sie das MEConnectStart-Ereignis auslöst. Die Netzwerkquelle löst dann das MEConnectEnd-Ereignis aus, wenn sie den geöffneten Vorgang abgeschlossen hat.

Hinweis

Um diese Ereignisse an die Anwendung zu senden, verwendet die Netzwerkquelle nicht die IMFMediaEventGenerator-Schnittstelle , da diese Ereignisse ausgelöst werden, bevor die Netzwerkquelle erstellt wird. Die Anwendung kann alle anderen Netzwerkquellenereignisse mithilfe der IMFMediaEventGenerator-Schnittstelle der Mediensitzung abrufen.

 

So rufen Sie Ereignisse aus der Netzwerkquelle ab

  1. Implementieren Sie die IMFSourceOpenMonitor-Schnittstelle . Führen Sie in Ihrer Implementierung der IMFSourceOpenMonitor::OnSourceEvent-Methode die folgenden Schritte aus:
    1. Rufen Sie das Ereignis status ab, indem Sie IMFMediaEvent::GetStatus aufrufen. Diese Methode gibt an, ob der Vorgang, der das Ereignis ausgelöst hat, z. B. ein Aufruf der Quelllösermethode, erfolgreich war. Wenn der Vorgang nicht erfolgreich ist, ist die status ein Fehlercode.
    2. Verarbeiten Sie das Ereignis basierend auf dem Ereignistyp MEConnectStart oder MEConnectEnd, den die Anwendung durch Aufrufen von IMFMediaEvent::GetType abrufen kann.
  2. Konfigurieren Sie ein Schlüssel-Wert-Paar in einem Eigenschaftenspeicherobjekt, um einen Zeiger auf die in Schritt 1 beschriebene IMFSourceOpenMonitor-Implementierung zu speichern.
    1. Erstellen Sie ein Eigenschaftenspeicherobjekt, indem Sie die PSCreateMemoryPropertyStore-Funktion aufrufen.
    2. Legen Sie die MFPKEY_SourceOpenMonitor-Eigenschaft in einer PROPERTYKEY-Struktur fest.
    3. Geben Sie den VT_UNKNOWN Typdatenwert in einer PROPVARIANT-Struktur an, indem Sie den IUnknown-Zeiger auf die Implementierung der IMFSourceOpenMonitor-Schnittstelle der Anwendung festlegen.
    4. Legen Sie das Schlüssel-Wert-Paar im Eigenschaftenspeicher fest, indem Sie IPropertyStore::SetValue aufrufen.
  3. Übergeben Sie den Eigenschaftenspeicherzeiger an die Quellresolvermethoden, die die Anwendung zum Erstellen der Netzwerkquelle verwendet, z. B. IMFSourceResolver::CreateObjectFromURL und andere.

Beispiel

Das folgende Beispiel zeigt, wie die IMFSourceOpenMonitor-Schnittstelle implementiert wird, um Ereignisse aus der Netzwerkquelle abzurufen.

class CSourceOpenMonitor : public IMFSourceOpenMonitor
{
public:
    CSourceOpenMonitor () : m_cRef(1) { }

    STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        static const QITAB qit[] = 
        {
            QITABENT(CSourceOpenMonitor, IMFSourceOpenMonitor),
            { 0 }
        };
        return QISearch(this, qit, riid, ppv);
    }

    STDMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&m_cRef);
    }

    STDMETHODIMP_(ULONG) Release()
    {
        LONG cRef = InterlockedDecrement(&m_cRef);
        if (cRef == 0)
        {
            delete this;
        }
        // For thread safety, return a temporary variable.
        return cRef;
    }


    STDMETHODIMP OnSourceEvent(IMFMediaEvent* pEvent)
    {
        MediaEventType eventType = MEUnknown;   // Event type
        HRESULT hrStatus = S_OK;                // Event status

        // Get the event type.
        HRESULT hr = pEvent->GetType(&eventType);

        // Get the event status. If the operation that triggered the event
        // did not succeed, the status is a failure code.
        if (SUCCEEDED(hr))
        {
            hr = pEvent->GetStatus(&hrStatus);
        }

        if (FAILED(hrStatus))
        {
            hr = hrStatus;
        }

        if (SUCCEEDED(hr))
        {
            // Switch on the event type.
            switch(eventType)
            {
                case MEConnectStart:
                    // The application does something. (Not shown.)
                    OutputDebugString(L"Connecting...\n");
                    break;

                case MEConnectEnd:
                    // The application does something. (Not shown.)
                    OutputDebugString(L"Connect End.\n");
                    break;
            }
        }
        else
        {
            // Event failed.
            // The application handled a failure. (Not shown.)
        }
        return S_OK;
    }
private:
    long    m_cRef;
};

Im folgenden Beispiel wird gezeigt, wie die eigenschaft MFPKEY_SourceOpenMonitor für die Netzwerkquelle festgelegt wird, wenn Sie die URL öffnen:

HRESULT CreateMediaSourceWithSourceOpenMonitor(
    PCWSTR pszURL, 
    IMFMediaSource **ppSource
    )
{
    IPropertyStore *pConfig = NULL;

    CSourceOpenMonitor *pMonitor = new (std::nothrow) CSourceOpenMonitor();

    if (pMonitor == NULL)
    {
        return E_OUTOFMEMORY;
    }

    // Configure the property store.
    HRESULT hr = PSCreateMemoryPropertyStore(IID_PPV_ARGS(&pConfig));

    if (SUCCEEDED(hr))
    {
        PROPVARIANT var;
        var.vt = VT_UNKNOWN;
        pMonitor->QueryInterface(IID_PPV_ARGS(&var.punkVal));

        hr = pConfig->SetValue(MFPKEY_SourceOpenMonitor, var);

        PropVariantClear(&var);
    }

    // Create the source media source.
    if (SUCCEEDED(hr))
    {
        hr = CreateMediaSource(pszURL, pConfig, ppSource);
    }

    SafeRelease(&pConfig);
    SafeRelease(&pMonitor);

    return hr;
}

Netzwerk in Media Foundation