다음을 통해 공유


Windows Media Format SDK 잠금 해제

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngineMedia Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

Windows Media Format SDK 버전 7 또는 7.1에 액세스하려면 애플리케이션에서 런타임에 키라고도 하는 소프트웨어 인증서를 제공해야 합니다. 이 키는 빌드 시 애플리케이션이 연결되는 wmstub.lib라는 정적 라이브러리에 포함되어 있습니다. 개별화된 키는 DRM으로 보호되는 파일을 만들거나 읽는 데만 필요합니다. 비 DRM 파일은 Windows 미디어 형식 SDK와 함께 제공되는 정적 라이브러리를 사용하여 만들 수 있습니다. DRM 키 가져오기에 대한 자세한 내용은 Windows Media Format SDK를 참조하세요. DirectShow 애플리케이션은 필터 그래프에 추가되면 WM ASF 기록기에 인증서를 제공합니다. 애플리케이션은 COM IServiceProviderIObjectWithSite 인터페이스를 사용하여 키 공급자로 등록해야 합니다. 이 기술을 사용하여 애플리케이션은 IServiceProvider에서 파생된 키 공급자 클래스를 구현합니다. 이 클래스는 필터 그래프 관리자가 호출하는 하나의 추가 메서드인 QueryService와 함께 AddRef, QueryInterfaceRelease라는 세 가지 표준 COM 메서드를 구현합니다. QueryService는 Windows Media Format SDK 메서드 WMCreateCertificate 를 호출하고 생성된 인증서에 대한 포인터를 필터 그래프 관리자로 반환합니다. 인증서가 유효한 경우 필터 그래프 관리자를 사용하면 그래프 작성 프로세스를 진행할 수 있습니다.

참고

애플리케이션을 빌드하려면 WMCreateCertificate용 프로토타입용 Wmsdkidl.h를 포함하고 Wmstub.lib 라이브러리에 연결합니다.

 

다음 코드 예제에서는 이 프로세스의 기본 단계를 보여 줍니다.

// Declare and implement a key provider class derived from IServiceProvider.

class CKeyProvider : public IServiceProvider {
public:
    // IUnknown interface
    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    CKeyProvider();

    // IServiceProvider
    STDMETHODIMP QueryService(REFIID siid, REFIID riid, void **ppv);
    
private:
    ULONG m_cRef;
};

CKeyProvider::CKeyProvider() : m_cRef(0)
{
}

// IUnknown methods
ULONG CKeyProvider::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

ULONG CKeyProvider::Release()
{
    ASSERT(m_cRef > 0);

    ULONG lCount = InterlockedDecrement(&m_cRef);
    if (m_cRef == 0) 
    {
        delete this;
        return (ULONG)0;
    }
    return (ULONG)lCount;
}

// We only support IUnknown and IServiceProvider.
HRESULT CKeyProvider::QueryInterface(REFIID riid, void ** ppv)
{
    if (!ppv) return E_POINTER;

    if (riid == IID_IUnknown) 
    {
        *ppv = (void *) static_cast<IUnknown *>(this);
        AddRef();
        return S_OK;
    }
    if (riid == IID_IServiceProvider) 
    {
        *ppv = (void *) static_cast<IServiceProvider *>(this);
        AddRef();
        return S_OK;
    }

    return E_NOINTERFACE;
}

STDMETHODIMP CKeyProvider::QueryService(REFIID siid, REFIID riid, void **ppv)
{
    if (!ppv) return E_POINTER;

    if (siid == __uuidof(IWMReader) && riid == IID_IUnknown) 
    {
        IUnknown *punkCert;
        HRESULT hr = WMCreateCertificate(&punkCert);
        if (SUCCEEDED(hr)) 
        {
            *ppv = (void *) punkCert;
        }
        return hr;
    }
    return E_NOINTERFACE;
}

////////////////////////////////////////////////////////////////////
//
// These examples illustrate the sequence of method calls
// in your application. Error checking is omitted for brevity.
//
///////////////////////////////////////////////////////////////////

// Create the filter graph manager, but don't add any filters.
IGraphBuilder *pGraph;
hr = CreateFilterGraph(&pGraph);

...

// Instantiate the key provider class, and AddRef it
// so that COM doesn't try to free our static object.

CKeyProvider prov;
prov.AddRef();  // Don't let COM try to free our static object.

// Give the graph an IObjectWithSite pointer for callbacks and QueryService.
IObjectWithSite* pObjectWithSite = NULL;

hr = pGraph->QueryInterface(IID_IObjectWithSite, (void**)&pObjectWithSite);
if (SUCCEEDED(hr))
{
    // Use the IObjectWithSite pointer to specify our key provider object.
    // The filter graph manager will use this pointer to call
    // QueryService to do the unlocking.
    // If the unlocking succeeds, then we can build our graph.

    pObjectWithSite->SetSite((IUnknown *) (IServiceProvider *) &prov);
    pObjectWithSite->Release();
}

// Now build the graph.

DirectShow에서 ASF 파일 만들기