Freigeben über


Lesen DRM-Protected ASF-Dateien in DirectShow

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

In diesem Thema wird beschrieben, wie Sie Mit DirectShow Mediendateien wiedergeben, die mit Windows Media Digital Rights Management (DRM) geschützt sind.

DRM-Konzepte

Der Schutz einer Mediendatei mit Windows Media DRM umfasst zwei verschiedene Schritte:

  • Der Inhaltsanbieter packt die Datei, d. h. verschlüsselt die Datei und fügt Lizenzierungsinformationen an den ASF-Dateiheader an. Die Lizenzierungsinformationen enthalten eine URL, über die der Client die Lizenz erhalten kann.
  • Die Clientanwendung erhält eine Lizenz für den Inhalt.

Die Verpackung erfolgt, bevor die Datei verteilt wird. Der Lizenzerwerb erfolgt, wenn der Benutzer versucht, die Datei abzuspielen oder zu kopieren. Der Lizenzerwerb kann entweder silent oder non-silent erfolgen. Die automatische Erfassung erfordert keine Interaktion mit dem Benutzer. Die nicht unbeaufsichtigte Erfassung erfordert, dass die Anwendung ein Browserfenster öffnet und dem Benutzer eine Webseite anzeigt. Zu diesem Zeitpunkt muss der Benutzer dem Inhaltsanbieter möglicherweise Informationen bereitstellen. Beide Arten des Lizenzerwerbs erfordern jedoch, dass der Client eine HTTP-Anforderung an einen Lizenzserver sendet.

DRM-Versionen

Es gibt mehrere Versionen von Windows Media DRM. Aus sicht einer Clientanwendung können sie in zwei Kategorien unterteilt werden: DRM Version 1 und DRM Version 7 oder höher. (Die zweite Kategorie umfasst die DRM-Versionen 9 und 10 sowie Version 7.) Der Grund für die Kategorisierung von DRM-Versionen auf diese Weise ist, dass Lizenzen der Version 1 etwas anders behandelt werden als Lizenzen der Version 7 oder höher. In dieser Dokumentation bedeutet der Begriff Lizenzversion 7 oder höher.

Es ist auch wichtig, die DRM-Verpackung von der DRM-Lizenz zu unterscheiden. Wenn die Datei mit Windows Media Rights Manager Version 7 oder höher verpackt ist, kann der DRM-Header zusätzlich zur Lizenz-URL der Version 7 eine Lizenz-URL der Version 1 enthalten. Die Lizenz-URL der Version 1 ermöglicht es älteren Spielern, die Version 7 nicht unterstützen, eine Lizenz für den Inhalt zu erhalten. Umgekehrt ist jedoch nicht der Fall, sodass eine Datei mit Version 1-Paket keine Lizenz-URL der Version 7 aufweisen kann.

Anwendungssicherheitsebene

Um DRM-geschützte Dateien wiedergeben zu können, muss die Clientanwendung mit einer statischen Bibliothek verknüpft sein, die von Microsoft in binärer Form bereitgestellt wird. Diese Bibliothek, die die Anwendung eindeutig identifiziert, wird manchmal als Stubbibliothek bezeichnet. Die Stubbibliothek verfügt über eine zugewiesene Sicherheitsstufe, deren Wert durch den Lizenzvertrag bestimmt wird, den Sie beim Erhalt der Stubbibliothek unterzeichnet haben.

Der Inhaltsanbieter legt eine Mindestsicherheitsstufe fest, die zum Erwerb der Lizenz erforderlich ist. Wenn die Sicherheitsstufe Ihrer Stubbibliothek kleiner als die vom Lizenzserver erforderliche Mindestsicherheitsstufe ist, kann die Anwendung die Lizenz nicht erhalten.

Individualisierung

Um die Sicherheit zu erhöhen, aktualisiert eine Anwendung möglicherweise die DRM-Komponenten auf dem Clientcomputer. Dieses Als Individualisierung bezeichnete Update unterscheidet die Kopie der Anwendung des Benutzers von allen anderen Kopien derselben Anwendung. Der DRM-Header einer geschützten Datei kann eine Minimale Individualisierungsebene angeben. (Weitere Informationen finden Sie in der Dokumentation zu WMRMHeader.IndividualizedVersion im Windows Media Rights Manager SDK.)

Der Microsoft Individualization Service verarbeitet Informationen vom Benutzer. Bevor Ihre Anwendung individualisiert wird, müssen Sie die Microsoft-Datenschutzerklärung anzeigen oder einen Link dazu bereitstellen (siehe Microsoft-Datenschutzbestimmungen).

Bereitstellen des Softwarezertifikats

Damit die Anwendung die DRM-Lizenz verwenden kann, muss die Anwendung ein Softwarezertifikat oder einen Schlüssel für den Filter Graph Manager bereitstellen. Dieser Schlüssel ist in einer statischen Bibliothek enthalten, die für die Anwendung individualisiert ist. Informationen zum Abrufen der individualisierten Bibliothek finden Sie unter Abrufen der erforderlichen DRM-Bibliothek in der Dokumentation zum Windows Media Format SDK.

Führen Sie zum Bereitstellen des Softwareschlüssels die folgenden Schritte aus:

  1. Link zur statischen Bibliothek.
  2. Implementieren Sie die IServiceProvider-Schnittstelle .
  3. Fragen Sie den Filter Graph-Manager nach der IObjectWithSite-Schnittstelle ab.
  4. Rufen Sie IObjectWithSite::SetSite mit einem Zeiger auf Ihre Implementierung von IServiceProvider auf.
  5. Der Filter Graph-Manager ruft IServiceProvider::QueryService auf und gibt IID_IWMReader für den Dienstbezeichner an.
  6. Rufen Sie in Ihrer Implementierung von QueryServiceWMCreateCertificate auf , um den Softwareschlüssel zu erstellen.

Der folgende Code zeigt, wie Die QueryService-Methode implementiert wird:

STDMETHODIMP Player::QueryService(REFIID siid, REFIID riid, void **ppv)
{
    if (ppv == NULL ) 
    { 
        return E_POINTER; 
    }

    if (siid == __uuidof(IWMReader) && riid == __uuidof(IUnknown))
    {
        IUnknown *punkCert;

        HRESULT hr = WMCreateCertificate(&punkCert);

        if (SUCCEEDED(hr))
        {
            *ppv = (void *) punkCert;
        }

        return hr;
    }
    return E_NOINTERFACE;
}

Der folgende Code zeigt, wie SetSite im Filter Graph Manager aufgerufen wird:

HRESULT Player::CreateFilterGraph()
{
    CComPtr<IObjectWithSite> pSite;

    HRESULT hr = pGraph.CoCreateInstance(CLSID_FilterGraph);

    if (FAILED(hr))
    {
        goto done;
    }

    // Register the application as a site (service).
    hr = pGraph->QueryInterface(&pSite);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSite->SetSite(this);


done:
    return hr;
}

Erstellen des Wiedergabediagramms

Führen Sie zum Wiedergeben einer DRM-geschützten ASF-Datei die folgenden Schritte aus:

  1. Erstellen Sie den Filter Graph-Manager , und registrieren Sie sich mit der IMediaEventEx-Schnittstelle für Graphereignisse.
  2. Rufen Sie CoCreateInstance auf, um eine neue instance des WM ASF Reader-Filters zu erstellen.
  3. Rufen Sie IFilterGraph::AddFilter auf, um den Filter dem Filterdiagramm hinzuzufügen.
  4. Fragen Sie den Filter für die IFileSourceFilter-Schnittstelle ab.
  5. Rufen Sie IFileSourceFilter::Load mit der URL der Datei auf.
  6. Behandeln sie EC_WMT_EVENT Ereignisse.
  7. Fragen Sie beim ersten EC_WMT_EVENT-Ereignis den WM ASF Reader-Filter nach der IServiceProvider-Schnittstelle ab.
  8. Rufen Sie IServiceProvider::QueryService auf, um einen Zeiger auf die IWMDRMReader-Schnittstelle zu erhalten.
  9. Rufen Sie IGraphBuilder::Render auf, um die Ausgabepins des WM ASF Reader-Filters zu rendern.

Hinweis

Rufen Sie beim Öffnen einer DRM-geschützten Datei nicht IGraphBuilder::RenderFile auf, um das Filterdiagramm zu erstellen. Der WM ASF Reader-Filter kann keine Verbindung mit anderen Filtern herstellen, bis die DRM-Lizenz erworben wurde. Für diesen Schritt muss die Anwendung die IWMDRMReader-Schnittstelle verwenden, die aus dem Filter abgerufen werden muss, wie in den Schritten 7 bis 8 beschrieben. Daher müssen Sie den Filter erstellen und dem Diagramm hinzufügen.

 

Hinweis

Es ist wichtig, sich für Graphereignisse (Schritt 1) zu registrieren, bevor Sie dem Diagramm den WM ASF Reader-Filter hinzufügen (Schritt 3), da die Anwendung die EC_WMT_EVENT Ereignisse verarbeiten muss. Die Ereignisse werden gesendet, wenn Load aufgerufen wird (Schritt 5).

 

Der folgende Code zeigt, wie das Diagramm erstellt wird:

HRESULT Player::LoadMediaFile(PCWSTR pwszFile)
{


    BOOL bIsWindowsMediaFile = IsWindowsMediaFile(pwszFile);

    HRESULT hr = S_OK;

    // If this is the first time opening the file, create the
    // filter graph and add the WM ASF Reader filter.

    if (m_DRM.State() == DRM_INITIAL)
    {
        hr = CreateFilterGraph();
        if (FAILED(hr))
        {
            goto done;
        }

        // Use special handling for Windows Media files.
        if (bIsWindowsMediaFile)
        {
            // Add the ASF Reader filter to the graph.
            hr = m_pReader.CoCreateInstance(CLSID_WMAsfReader);
            if (FAILED(hr))
            {
                goto done;
            }

            hr = pGraph->AddFilter(m_pReader, NULL);
            if (FAILED(hr))
            {
                goto done;
            }

            hr = m_pReader->QueryInterface(&m_pFileSource);
            if (FAILED(hr))
            {
                goto done;
            }
        }
    }

    if (bIsWindowsMediaFile)
    {
            hr = m_pFileSource->Load(pwszFile, NULL);
C++
            if (FAILED(hr))            {                goto done;            }            hr = RenderOutputPins(pGraph, m_pReader);    }    else    {        // Not a Windows Media file, so just render the standard way.        hr = pGraph->RenderFile(pwszFile, NULL);    }done:    return hr;}

Im vorherigen Code listet die Funktion die RenderOutputPins Ausgabepins im WM ASF Reader-Filter auf und ruft IGraphBuilder::Render für jeden Pin auf.

HRESULT RenderOutputPins(IGraphBuilder *pGraph, IBaseFilter *pFilter)
{
    CComPtr<IEnumPins>  pEnumPin = NULL;
    CComPtr<IPin>       pConnectedPin;
    CComPtr<IPin>       pPin;

    // Enumerate all pins on the filter
    HRESULT hr = pFilter->EnumPins(&pEnumPin);
    if (FAILED(hr))
    {
        goto done;
    }

    // Step through every pin, looking for the output pins.
    while (S_OK == (hr = pEnumPin->Next(1, &pPin, NULL)))
    {
        // Skip connected pins.
        hr = pPin->ConnectedTo(&pConnectedPin);
        if (hr == VFW_E_NOT_CONNECTED)
        {
            PIN_DIRECTION PinDirection;
            hr = pPin->QueryDirection(&PinDirection);

            if ((S_OK == hr) && (PinDirection == PINDIR_OUTPUT))
            {
                hr = pGraph->Render(pPin);
            }
        }

        pConnectedPin.Release();
        pPin.Release();

        // If there was an error, stop enumerating.
        if (FAILED(hr))
        {
            break;
        }
    }

done:
    return hr;
}

Der folgende Code zeigt, wie Sie einen Zeiger auf die IWMDRMReader-Schnittstelle aus dem WM ASF Reader abrufen:

HRESULT DrmManager::Initialize(IBaseFilter *pFilter)
{


    CComPtr<IServiceProvider> pService;
    CComPtr<IWMDRMReader> pDrmReader;

    HRESULT hr = pFilter->QueryInterface(&pService);
    if (SUCCEEDED(hr))
    {
        hr = pService->QueryService(
            __uuidof(IWMDRMReader), IID_PPV_ARGS(&m_pDrmReader));
    }
    return hr;
}

Lesen von ASF-Dateien in DirectShow