플러그형 DRM을 사용하는 방법(HTML)
[ 이 문서는 Windows 런타임 앱을 작성하는 Windows 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]
JavaScript로 작성된 Windows 런타임 앱에서 MediaProtectionManager를 사용하여 DRM(디지털 권한 관리)으로 보호된 콘텐츠를 사용할 수 있습니다.
이 항목에서는 JavaScript로 작성한 기본 Windows 런타임 앱을 만들 수 있다고 가정합니다. 첫 번째 앱을 만드는 자세한 내용은 JavaScript를 사용하여 첫 번째 Windows 스토어 앱 만들기를 참조하세요.
다음 단계에서는 컴퓨터에서 보호된 콘텐츠를 MediaProtectionManager API를 사용하여 재생하는 방법을 설명합니다.
1. MediaProtectionManager 개체를 만듭니다.
응용 프로그램에서 이 클래스를 사용하여 발생한 이벤트를 수신하는 수신기를 연결할 수 있습니다.
다음 코드 예제에서는 MediaProtectionManager 개체를 만드는 방법을 보여 줍니다.
var mediaProtectionManager = new Windows.Media.Protection.MediaProtectionManager();
2. MediaProtectionManager.Properties 속성을 설정합니다.
미디어 보호 시스템에 정보를 제공하려면 Properties 속성을 사용합니다. 현재 세 개의 속성을 설정할 수 있습니다.
Windows.Media.ContentProtection.VideoFrameAccessCertificate - 프레임 서버 모드에서 프레임에 액세스하기 위한 응용 프로그램 인증서를 나타내는 UNIT 8 배열입니다.
Windows.Media.ContentProtection.ContentProtectionSystemId - 보호 시스템 ID를 나타내는 GUID입니다. 이 값은 WMDRM ASF(Advanced Streaming Format) 파일에서 보호된 콘텐츠를 처리하기 위해 사용해야 하는 타사 보호 시스템을 결정합니다.
Windows.Media.ContentProtection.ContentProtectionSystemContext - 응용 프로그램이 현재 콘텐츠에 대해 보호 시스템에 전달하고자 하는 추가 데이터를 나타내는 UNIT 8 배열입니다.
이 예에서는 Properties 속성을 설정하는 방법을 보여 줍니다.
mediaProtectionManager.properties["Windows.Media.Protection.MediaProtectionSystemId"] =
'{F4637010-03C3-42CD-B932-B48ADF3A6A54}';
// Microsoft.Media.PlayReadyClient.PlayReadyStatics.mediaProtectionSystemId;
3. HTML 비디오 태그 또는 XAML MediaElement에 MediaProtectionManager 설정.
msSetMediaProtectionManager 메서드를 비디오 또는 오디오 태그의 인스턴스로 설정합니다.
다음 코드 샘플에서는 비디오 플레이어의 MediaProtectionManager를 설정하는 방법을 보여 줍니다.
video.msSetMediaProtectionManager(mediaProtectionManager);
4. 이벤트 처리
이벤트를 처리하는 수신기를 연결하고 대리자를 구현하여 보호 작업을 처리합니다.
ComponentLoadFailed - 바이너리 데이터의 로드가 실패할 경우 발생합니다.
RebootNeeded - 구성 요소가 갱신된 후 다시 시작이 필요할 경우 발생합니다.
ServiceRequested - 콘텐츠 보호 시스템에 문제가 발생하여 응용 프로그램의 도움이 필요할 경우 발생합니다.
이 예에서는 이벤트 수신기를 추가하는 방법을 보여 줍니다.
mediaProtectionManager.addEventListener("componentloadfailed", componentLoadFailed);
mediaProtectionManager.addEventListener("servicerequested", serviceRequested);
예제
다음 예제에서는 MediaProtectionManager를 설정하여 미디어 파일을 재생하는 방법을 보여 줍니다.
var mpmCompletionNotifier;
function btnPlayOnClick()
{
try
{
clearLog();
var videoPlayer;
var mediaProtectionManager;
var mediaFilename;
logMsg( 'Beginning playback attempt...' );
videoPlayer = document.getElementById( 'video' );
logMsg( '--- Setting up video player object' );
videoPlayer.addEventListener.addEventListener( 'canplay', onCanPlay, false);
videoPlayer.addEventListener( 'error', onPlayError, false);
logMsg( '--- Creating new Windows.Media.Protection.MediaProtectionManager' );
mediaProtectionManager = new Windows.Media.Protection.MediaProtectionManager();
logMsg( '--- Setting up MediaProtectionManager' );
mediaProtectionManager.addEventListener( "componentloadfailed", componentLoadFailed, false);
mediaProtectionManager.addEventListener( "servicerequested", serviceRequested, false);
mediaProtectionManager.properties["Windows.Media.Protection.MediaProtectionSystemId"] =
'{F4637010-03C3-42CD-B932-B48ADF3A6A54}';
// Microsoft.Media.PlayReadyClient.PlayReadyStatics.mediaProtectionSystemId;
var registrar = new Windows.Media.MediaExtensionManager();
registrar.registerByteStreamHandler('Microsoft.Media.PlayReadyClient.PlayReadyByteStreamHandler', '.asf', null);
registrar.registerByteStreamHandler('Microsoft.Media.PlayReadyClient.PlayReadyByteStreamHandler', '.pyv', null);
logMsg( '--- Setting MediaProtectionManager to video player' );
videoPlayer.msSetMediaProtectionManager( mediaProtectionManager );
//playback PR content which has been renamed to .asf
//media content has been packed with application for now
logMsg( '--- Setting player source' );
mediaFilename = 'pr_006_1_01_v4_0_wmv.pyv.asf';
videoPlayer.src = mediaFilename;
}
catch ( e )
{
// handle the error.
logWarning( e, 'btnPlayOnClick' );
}
}
function onCanPlay()
{
var videoPlayer = document.getElementById( 'video' );
logMsg( 'Attempting to start playback' );
try
{
videoPlayer.play();
}
catch ( e )
{
logWarning( e, 'onCanPlay' );
// Handle the error.
}
}
function componentLoadFailed( e )
{
try
{
logMsg( e.information.items.size + " failed components!" );
logMsg( "Components:" );
// List the failing components
for ( var i = 0; i < e.information.items.size; i++ )
{
logMsg( e.information.items[i].name + "\nReasons=0x" + e.information.items[i].reasons + '\n'
+ "Renewal Id=" + e.information.items[i].renewalId );
}
e.completion.complete( false );
logMsg( "Resumed source (false)" );
}
catch ( e )
{
logWarning( e, 'componentLoadFailed' );
// Handle the error.
}
}
function serviceRequested( e )
{
try
{
logMsg( "Service request required before playback can happen, service request type: " + getSRType( e.request ) );
var serviceRequestOperation = e.request.operation;
mpmCompletionNotifier = e.completion;
logMsg( "--- Request type: " + getSRType( e.request ) );
serviceRequestOperation.enablingActionRequired = function ( sender, enabler ){ onEnablingActionRequired( sender, enabler ); };
if ( g_fUsePromises )
{
logMsg( '--- using promises model ( e.request.then(..) )' );
e.request.then( onPlaySRCompleted, onPlaySRError );
}
else
{
serviceRequestOperation.completed = function ( asyncOp ){ onPlaySRCompleted( asyncOp ); };
serviceRequestOperation.start();
}
}
catch ( e )
{
logWarning( e, 'serviceRequested' );
// Handle error.
}
}
function onPlaySRCompleted( asyncOp )
{
try
{
logMsg( 'Service Request completed with status: ' + getAsyncStatus( asyncOp ) );
mpmCompletionNotifier.complete( true );
logMsg( 'after mpmCompletionNotifier.complete( true )' );
}
catch ( e )
{
logWarning( e, 'onPlaySRCompleted' );
taef_testFailed( e, 'onPlaySRCompleted', 'playback' );
}
}
function onPlaySRError( sender, e )
{
logWarning( e, 'onPlaySRError' );
}
function onPlayError( )
{
logMsg( 'Play back failed' );
}