Lendo arquivos ASF DRM-Protected no DirectShow
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEnginee Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda vivamente que o novo código utilize MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]
Este tópico descreve como usar o DirectShow para reproduzir arquivos de mídia protegidos com o Gerenciamento de Direitos Digitais (DRM) do Windows Media.
Conceitos de DRM
A proteção de um ficheiro multimédia com o Windows Media DRM envolve dois passos distintos:
- O provedor de conteúdo empacota o arquivo, ou seja, criptografa o arquivo e anexa informações de licenciamento ao cabeçalho do arquivo ASF. As informações de licenciamento incluem um URL onde o cliente pode obter a licença.
- O aplicativo cliente adquire uma licença para o conteúdo.
O empacotamento acontece antes de o arquivo ser distribuído. A aquisição de licença ocorre quando o usuário tenta reproduzir ou copiar o arquivo. A aquisição de licenças pode ser silenciosa ou não silenciosa. A aquisição silenciosa não requer qualquer interação com o utilizador. A aquisição não silenciosa requer que o aplicativo abra uma janela do navegador e exiba uma página da Web para o usuário. Nesse ponto, o usuário pode precisar fornecer algum tipo de informação ao provedor de conteúdo. No entanto, ambos os tipos de aquisição de licença exigem que o cliente envie uma solicitação HTTP para um servidor de licenças.
Versões DRM
Existem várias versões do Windows Media DRM. Da perspetiva de um aplicativo cliente, eles podem ser agrupados em duas categorias: DRM versão 1 e DRM versão 7 ou posterior. (A segunda categoria inclui as versões DRM 9 e 10, bem como a versão 7.) A razão para categorizar versões DRM dessa maneira é que as licenças da versão 1 são tratadas de forma um pouco diferente das licenças da versão 7 ou posterior. Nesta documentação, o termo licença versão 7 significa versão 7 ou posterior.
Também é importante distinguir a embalagem DRM da licença DRM. Se o ficheiro for empacotado utilizando o Windows Media Rights Manager versão 7 ou posterior, o cabeçalho DRM pode conter um URL de licença versão 1, além do URL de licença versão 7. O URL da licença da versão 1 permite que os jogadores mais antigos que não suportam a versão 7 obtenham uma licença para o conteúdo. No entanto, o inverso não é verdadeiro, portanto, um arquivo com empacotamento da versão 1 não pode ter uma URL de licença da versão 7.
Nível de segurança do aplicativo
Para reproduzir arquivos protegidos por DRM, o aplicativo cliente deve ser vinculado a uma biblioteca estática fornecida em formato binário pela Microsoft. Essa biblioteca, que identifica exclusivamente o aplicativo, às vezes é chamada de biblioteca de stub. A biblioteca de stub tem um nível de segurança atribuído, cujo valor é determinado pelo contrato de licença que você assinou quando obteve a biblioteca de stub.
O provedor de conteúdo define um nível mínimo de segurança necessário para adquirir a licença. Se o nível de segurança da sua biblioteca de stub for inferior ao nível mínimo de segurança exigido pelo servidor de licenças, a aplicação não poderá obter a licença.
Individualização
Para aumentar a segurança, um aplicativo pode atualizar os componentes DRM no computador do cliente. Essa atualização, chamada de individualização, diferencia a cópia do usuário do aplicativo de todas as outras cópias do mesmo aplicativo. O cabeçalho DRM de um arquivo protegido pode especificar um nível mínimo de individualização. (Para obter mais informações, consulte a documentação de WMRMHeader.IndividualizedVersion no SDK do Windows Media Rights Manager.)
O Serviço de Individualização da Microsoft lida com informações do usuário. Portanto, antes que seu aplicativo seja individualizado, você deve exibir a Declaração de Privacidade da Microsoft ou fornecer um link para ela (consulte Declaração de Privacidade da Microsoft).
Fornecer o certificado de software
Para permitir que a aplicação use a licença DRM, a aplicação deve fornecer um certificado de software ou a chave ao Gestor de Gráficos de Filtro. Essa chave está contida em uma biblioteca estática que é individualizada para o aplicativo. Para obter informações sobre como obter a biblioteca individualizada, consulte Obtendo a biblioteca DRM necessária na documentação do SDK do Windows Media Format.
Para fornecer a chave de software, execute as seguintes etapas:
- Link para a biblioteca estática.
- Implemente o IServiceProvider interface.
- Consulte o Gestor de Gráfico de Filtro para a interface IObjectWithSite.
- Chame IObjectWithSite::SetSite com um ponteiro para a sua implementação de IServiceProvider.
- O Filter Graph Manager chamará IServiceProvider::QueryService, especificando IID_IWMReader para o identificador de serviço.
- Na implementação do QueryService, chame WMCreateCertificate para criar a chave de software.
O código a seguir mostra como implementar o QueryService método:
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;
}
O código seguinte mostra como chamar no Gestor de Gráficos de Filtro SetSite:
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;
}
Construindo o gráfico de reprodução
Para reproduzir um arquivo ASF protegido por DRM, execute as seguintes etapas:
- Crie o Filter Graph Manager e use a interfaceIMediaEventEx dopara se registrar em eventos de gráfico.
- Chame CoCreateInstance para criar uma nova instância do filtro WM ASF Reader.
- Chame IFilterGraph::AddFilter para adicionar o filtro ao gráfico de filtro.
- Consulte o filtro para a interface IFileSourceFilter .
- Chame IFileSourceFilter::Load com a URL do arquivo.
- Lidar com eventos EC_WMT_EVENT.
- No primeiro evento EC_WMT_EVENT, consulte o filtro WM ASF Reader para a interface IServiceProvider.
- Chame IServiceProvider::QueryService para obter um ponteiro para a interface IWMDRMReader.
- Chame IGraphBuilder::Render para renderizar os pinos de saída do filtro WM ASF Reader.
Observação
Ao abrir um arquivo protegido por DRM, não chame IGraphBuilder::RenderFile para criar o gráfico de filtro. O filtro WM ASF Reader não pode se conectar a nenhum outro filtro até que a licença DRM seja adquirida. Esta etapa requer que o aplicativo use a interface IWMDRMReader, que deve ser obtida do filtro, conforme descrito nas etapas 7 até 8. Portanto, você deve criar o filtro e adicioná-lo ao gráfico
Observação
É importante registar eventos do gráfico (etapa 1) antes de adicionar o filtro WM ASF Reader ao gráfico (etapa 3), porque a aplicação deve manipular os eventos EC_WMT_EVENT. Os eventos são enviados no momento em que Load é chamado (etapa 5).
O código a seguir mostra como criar o gráfico:
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++ |
---|
|
No código anterior, a função RenderOutputPins
enumera os pinos de saída no filtro WM ASF Reader e chama IGraphBuilder::Render para cada pino.
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;
}
O código a seguir mostra como obter um ponteiro para o interface de IWMDRMReader do WM ASF Reader:
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;
}
Tópicos relacionados