Wiedergeben geschützter Mediendateien

Eine geschützte Mediendatei ist jede Mediendatei mit zugeordneten Regeln für die Verwendung des Inhalts. In einigen Fällen wird eine geschützte Mediendatei mithilfe einer DRM-Verschlüsselung (Digital Rights Management) verschlüsselt. Um eine geschützte Mediendatei wiederzugeben, muss die Wiedergabe innerhalb des geschützten Medienpfads (Protected Media Path, PMP) erfolgen. Darüber hinaus muss der Benutzer möglicherweise Rechte für den Inhalt erwerben.

Der Begriff Rechteerwerb bezieht sich auf jede Aktion, die die Anwendung ausführen muss, bevor der Benutzer den Inhalt wiedergeben kann. Das häufigste Beispiel ist der Erhalt einer DRM-Lizenz, aber Media Foundation definiert einen generischen Mechanismus, der andere Arten des Rechteerwerbs unterstützen kann. Die IMFContentEnabler-Schnittstelle definiert diesen generischen Mechanismus.

Der Rechteerwerb muss außerhalb des PMP erfolgen, und zwar ab dem Bewerbungsprozess. Die Mediensitzung benachrichtigt die Anwendung über die IMFContentProtectionManager-Schnittstelle , die von der Anwendung implementiert wird. Die Mediensitzung verwendet die IMFContentProtectionManager-Schnittstelle , um ein Content Enabler-Objekt an die Anwendung weiterzuleiten. Content Enabler implementieren die IMFContentEnabler-Schnittstelle . Die Anwendung verwendet diese Schnittstelle, um die erforderlichen Rechte zu erwerben.

Ein Content Enabler kann den automatischen Rechteerwerb unterstützen. In diesem Fall implementiert der Content Enabler den gesamten Prozess, und die Anwendung überwacht einfach die status. Andernfalls muss die Anwendung den Erwerb nicht unbeaufsichtigter Rechte verwenden. Hierbei handelt es sich um einen Prozess, bei dem die Anwendung HTTP POST-Daten an eine URL sendet, die vom Content Enabler bereitgestellt wird.

Um geschützte Medien wiederzugeben, führt eine Anwendung die gleichen Schritte aus, die im Thema Wiedergeben von Mediendateien mit Media Foundation beschrieben sind, mit den folgenden zusätzlichen Schritten:

  1. Fragen Sie ab, ob die Medienquelle geschützte Inhalte enthält. (Optional.)
  2. Erstellen Sie die Mediensitzung im PMP-Prozess anstelle des Anwendungsprozesses.
  3. Führen Sie den Rechteerwerb durch, wenn sie von der Mediensitzung dazu benachrichtigt wird. Dieser Vorgang wird von der Anwendung asynchron ausgeführt.
  4. Schließen Sie den asynchronen Vorgang ab.

Abfragen nach geschützten Inhalten

Um abzufragen, ob eine Medienquelle geschützte Inhalte enthält, rufen Sie die MFRequireProtectedEnvironment-Funktion für die Präsentationsbeschreibung der Medienquelle auf. Wenn die Funktion S_OK zurückgibt, müssen Sie den PMP verwenden, um den Inhalt wiederzugeben. Wenn die Funktion S_FALSE zurückgibt, ist der PMP nicht erforderlich, und Sie können die Mediensitzung im Anwendungsprozess erstellen. Alternativ können Sie den PMP verwenden, um beide Arten von Inhalten wiederzugeben, geschützt und nicht geschützt. Wenn Sie dies tun, müssen Sie MFRequireProtectedEnvironment nicht aufrufen.

Weitere Informationen zu Präsentationsdeskriptoren finden Sie unter Präsentationsdeskriptoren.

Erstellen der PMP-Mediensitzung

Um die Mediensitzung im PMP zu erstellen, rufen Sie MFCreatePMPMediaSession auf. Diese Funktion ähnelt MFCreateMediaSession, aber anstatt die Mediensitzung im Prozess der Anwendung zu erstellen, erstellt sie die Mediensitzung im PMP-Prozess. Die Anwendung empfängt einen Zeiger auf ein Proxyobjekt für die Mediensitzung. Die Anwendung ruft die IMFMediaSession-Methoden für das Proxyobjekt auf, genau wie in der Mediensitzung. Das Proxyobjekt leitet die Aufrufe an die Mediensitzung über die Prozessgrenze weiter.

Erstellen Sie die PMP-Mediensitzung wie folgt:

  1. Erstellen Sie einen neuen Attributspeicher, indem Sie MFCreateAttributes aufrufen.
  2. Legen Sie das attribut MF_SESSION_CONTENT_PROTECTION_MANAGER im Attributspeicher fest. Der Wert dieses Attributs ist ein Zeiger auf die Implementierung von IMFContentProtectionManager in Ihrer Anwendung. Rufen Sie IMFAttributes::SetUnknown auf, um das Attribut festzulegen.
  3. Rufen Sie MFCreatePMPMediaSession auf, um die Mediensitzung im PMP-Prozess zu erstellen. Der pConfiguration-Parameter ist ein Zeiger auf die IMFAttributes-Schnittstelle des Attributspeichers .
IMFAttributes *pAttributes = NULL;
IMFMediaSession *pSession = NULL;

// Create the attribute store.
hr = MFCreateAttributes(&pAttributes, 1);

// Set the IMFContentProtectionManager pointer.
if (SUCCEEDED(hr))
{
    hr = pAttributes->SetUnknown(
        MF_SESSION_CONTENT_PROTECTION_MANAGER, 
        pCPM  // Your implementation of IMFContentProtectionManager.
        );
}

// Create the Media Session.
if (SUCCEEDED(hr))
{
    hr = MFCreatePMPMediaSession(
        0,
        pAttributes, 
        &pSession,
        NULL
    );
}

SAFE_RELEASE(pAttributes); // Release the attribute store.
// Use the Media Session to control playback (not shown).

Erstellen Sie als Nächstes eine Wiedergabetopologie, und stellen Sie sie in der Mediensitzung in eine Warteschlange ein, wie unter Erstellen von Wiedergabetopologien beschrieben.

Ausführen des Rechteerwerbs

Wenn die Wiedergabe den Erwerb von Rechten erfordert, ruft die Mediensitzung IMFContentProtectionManager::BeginEnableContent auf. Der pEnablerActivate-Parameter dieser Methode ist ein Zeiger auf die IMFActivate-Schnittstelle . Verwenden Sie diese Schnittstelle, um das Content Enabler-Objekt zu erstellen, das die IMFContentEnabler-Schnittstelle verfügbar macht. Verwenden Sie dann den Inhaltsaktivierer, um den Schritt zum Erwerb von Rechten auszuführen.

Um den Inhaltsaktivierer zu erstellen, rufen Sie IMFActivate::ActivateObject auf:

IMFContentEnabler *pEnabler = NULL;
hr = pEnablerActivate->ActivateObject(
    IID_IMFContentEnabler, 
    (void**)&pEnabler
    );

Fragen Sie den zurückgegebenen IMFContentEnabler-Zeiger für die IMFMediaEventGenerator-Schnittstelle ab. Verwenden Sie diese Schnittstelle, um Ereignisse aus dem Content Enabler-Objekt abzurufen. Weitere Informationen zu Ereignissen finden Sie unter Medienereignisgeneratoren.

Um herauszufinden, ob der Inhaltsaktivierer die automatische Erfassung unterstützt, rufen Sie IMFContentEnabler::IsAutomaticSupported auf. Wenn diese Methode den Wert TRUE zurückgibt, sollte die Anwendung die automatische Erfassung verwenden. Andernfalls verwenden Sie die nicht unbeaufsichtigte Erfassung.

Die BeginEnableContent-Methode ist asynchron. Die Anwendung sollte den Erfassungsschritt im Thread der Anwendung ausführen. Ein Ansatz besteht darin, eine private Fensternachricht im Standard Fenster der Anwendung zu posten und den Anwendungsthread zu benachrichtigen, um die Erfassung durchzuführen. Während der Vorgang aussteht, muss die Anwendung den Rückrufzeiger und das Zustandsobjekt, das sie empfangen hat, in den Parametern pCallback und punkState von BeginEnableContent speichern. Diese werden verwendet, um den asynchronen Vorgang abzuschließen.

Automatische Erfassung

Um die automatische Erfassung durchzuführen, rufen Sie IMFContentEnabler::AutomaticEnable auf. Diese Methode ist asynchron. Nach Abschluss des Vorgangs sendet der Content Enabler ein MEEnablerCompleted-Ereignis . Der status Code des Ereignisses gibt an, ob der Vorgang erfolgreich war. Wenn der status Code aus dem MEEnablerCompleted-Ereignis NS_E_DRM_LICENSE_NOTACQUIRED ist, sollte die Anwendung versuchen, die nicht unbeaufsichtigte Erfassung zu verwenden.

Während der Erfassungsvorgang wird vom Enabler-Objekt möglicherweise das MEEnablerProgress-Ereignis gesendet, um den Fortschritt des Vorgangs anzuzeigen. Um den Vorgang abzubrechen, rufen Sie IMFContentEnabler::Cancel auf.

Nicht unbeaufsichtigte Erfassung

Wenn die IsAutomaticSupported-MethodeFALSE zurückgibt oder die AutomaticEnable-Methode mit dem Fehlercode NS_E_DRM_LICENSE_NOTACQUIRED fehlschlägt, sollte die Anwendung eine nicht unbeaufsichtigte Erfassung durchführen, wie in den folgenden Schritten beschrieben:

  1. Rufen Sie IMFContentEnabler::GetEnableURL auf, um die URL für den Rechteerwerb abzurufen. Diese Methode gibt auch ein Flag zurück, das angibt, ob die URL vertrauenswürdig ist.

  2. Rufen Sie IMFContentEnabler::GetEnableData auf, um die HTTP POST-Daten abzurufen.

  3. Rufen Sie IMFContentEnabler::MonitorEnable auf. Diese Methode bewirkt, dass der Inhaltsaktivierer den Fortschritt der Aktion zum Erwerb von Rechten überwacht.

  4. Übermitteln Sie die Daten mithilfe einer HTTP POST-Aktion an die Rechteerwerbs-URL. Sie können das Internet-Explorer-Steuerelement oder die Windows Internet-APIs (WinINet) verwenden.

Der folgende Code zeigt die Schritte 1 bis 3. Schritt 4 hängt von den spezifischen Anforderungen Ihrer Anwendung ab.

WCHAR   *sURL = NULL;  // URL.
DWORD   cchURL = 0;    // Size of the URL in characters.

// Trust status of the URL.
MF_URL_TRUST_STATUS  trustStatus = MF_LICENSE_URL_UNTRUSTED;

BYTE    *pPostData = NULL;  // Buffer to hold HTTP POST data.
DWORD   cbPostDataSize = 0; // Size of the buffer, in bytes.

HRESULT hr = S_OK;

// Get the URL. 
hr = m_pEnabler->GetEnableURL(&sURL, &cchURL, &trustStatus);

if (SUCCEEDED(hr))
{
    if (trustStatus != MF_LICENSE_URL_TRUSTED)
    {
        // The URL is not trusted. Do not proceed.
        hr = E_FAIL;
    }
}

// Monitor the rights acquisition. 
if (SUCCEEDED(hr))
{
    hr = m_pEnabler->MonitorEnable();
}

// Get the HTTP POST data.
if (SUCCEEDED(hr))
{
    hr = m_pEnabler->GetEnableData(&pPostData, &cbPostDataSize);
}

// Open the URL and send the HTTP POST data. (Not shown.)

// Release the buffers.
CoTaskMemFree(pPostData);
CoTaskMemFree(sURL);

Nach Abschluss des Vorgangs sendet der Content Enabler ein MEEnablerCompleted-Ereignis .

Abschließen des asynchronen Vorgangs

Wenn der Rechteerwerb erfolgreich oder anderweitig abgeschlossen ist, muss die Anwendung die Mediensitzung benachrichtigen, indem sie den Rückrufzeiger aufruft, der in der BeginEnableContent-Methode angegeben ist.

  1. Erstellen Sie ein asynchrones Ergebnisobjekt, indem Sie MFCreateAsyncResult aufrufen.
  2. Rufen Sie den Rückruf der Mediensitzung auf, indem Sie MFInvokeCallback aufrufen.
  3. Die Mediensitzung ruft IMFContentProtectionManager::EndEnableContent auf. Geben Sie in Ihrer Implementierung dieser Methode alle Zeiger oder Ressourcen frei, die Sie in BeginEnableContent zugewiesen haben. Gibt ein HRESULT zurück, das den Gesamterfolg des Vorgangs angibt. Wenn beim Erwerb der Rechte ein Fehler aufgetreten ist oder der Benutzer vor Abschluss abgebrochen wurde, geben Sie einen Fehlercode zurück.

Der folgende Code zeigt, wie Sie das asynchrone Ergebnis erstellen und den Rückruf aufrufen.

IMFAsyncResult  *pResult = NULL;

// Create the asynchronous result object.
hr = MFCreateAsyncResult(NULL, pCallback, punkState, &pResult);

// Invoke the callback.
if (SUCCEEDED(hr))
{
    pResult->SetStatus(hrStatus);
    hr = MFInvokeCallback(pResult);
}
SAFE_RELEASE(pResult);

Mediensitzung

Audio-/Videowiedergabe