One Click Multi DRM
Naver Cloud Platform의 One Click Multi DRM을 TV SDK에서 사용하여 Widevine(Android TV)과 FairPlay(tvOS)를 한 번에 구성하는 방법을 안내합니다.
DRM은 시뮬레이터/에뮬레이터에서 동작하지 않습니다. 반드시 실기기에서 테스트하세요.
동작 원리
TV SDK는 네이티브 비디오 엔진(ExoPlayer/AVPlayer)을 사용하여 HLS/DASH를 직접 재생합니다. SDK가 플랫폼에 따라 자동으로 Widevine(Android TV) 또는 FairPlay(tvOS)를 선택합니다.
| 플랫폼 | DRM | 프로토콜 |
|---|---|---|
| Android TV / Fire TV | Widevine | DASH |
| Apple TV (tvOS) | FairPlay | HLS |
Naver Cloud Platform One Click Multi DRM 예제
https://vpe-api.sgrsoft.com/api/drmTest 엔드포인트를 호출해 DRM 정보를 받아온 뒤 플레이어 옵션으로 전달합니다.
import React, { useEffect, useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { VpePlayer } from '@sgrsoft/vpe-reactnative-tv-sdk';
export default function OneClickMultiDrmExample() {
const [options, setOptions] = useState<any>(null);
useEffect(() => {
fetch('https://vpe-api.sgrsoft.com/api/drmTest')
.then((res) => res.json())
.then((data) => setOptions(data));
}, []);
if (!options) {
return (
<View style={styles.container}>
{/* DRM 옵션 로딩 중 */}
</View>
);
}
return (
<View style={styles.container}>
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
options={options}
onBack={() => { /* navigation.goBack() */ }}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#000' },
});TV SDK는 네이티브 비디오 엔진(ExoPlayer/AVPlayer)이 HLS/DASH를 직접 처리하므로 별도의 스트리밍 라이브러리 주입 없이 DRM 옵션만 전달하면 됩니다.
[Backend] Ncloud DRM Helper 설치
npm i vpe-drm-helper- Ncloud DRM Helper는 DRM 재생소스를 생성하는데 사용됩니다.
- Ncloud API Key가 사용됩니다.
- Ncloud Sub Account를 사용하여 DRM 전용 API Key를 생성하여 사용합니다.
- 재생소스 생성 작업은 반드시 Backend에서 처리해야 합니다.
[Backend] Ncloud DRM Server 구현
import express from 'express';
import vpeDrmHelper from 'vpe-drm-helper';
const app = express();
const port = 3000;
// DRM Helper 설정
const NDRM = new vpeDrmHelper();
NDRM.isGov = false; // 공공클라우드 사용 여부 설정 (기본값 : false)
NDRM.setUserId('test-user'); // 시청자 아이디
NDRM.setSiteId('{SITEID}'); // One Click Multi DRM Site ID 설정
NDRM.setApiKey('{Ncloud API accessKey}', '{Ncloud API secretKey}'); // 네이버클라우드 플랫폼 ACCESS KEY, SECRET KEY 설정
// DRM 소스를 생성하는 API 엔드포인트
app.get('/drm-source', (req, res) => {
const drmSource = NDRM.drmSourceHelper({
dash: '{DASH 재생소스}',
hls: '{HLS 재생소스}',
}, '{contentId}'); // contentId 필수, VOD Station, LIVE Station에서 확인 및 설정 가능
res.json(drmSource);
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});- 이 코드는 Express.js를 사용하여 간단한 서버를 설정하고
/drm-source경로에서 DRM 소스를 생성하여 반환하는 API를 제공합니다. accessKey,secretKey,SITEID, DASH 재생소스, HLS 재생소스,contentId는 실제 값으로 대체해야 합니다.- 이 서버를 실행하려면 Node.js와 npm이 설치되어 있어야 하며,
vpe-drm-helper패키지를 설치해야 합니다.
⚠️ {SITEID} / {contentId}는 DRM 라이선스 토큰 생성시 필요합니다. 외부에 노출되면 안됩니다.
⚠️ API 키는 DRM 권한만 추가된 키를 사용해야합니다. 절대로 Master API 키를 사용하지 마세요.
응답 JSON 구조
DRM Helper가 반환하는 JSON에는 Widevine, PlayReady, FairPlay 키가 모두 포함됩니다. TV SDK는 플랫폼에 따라 자동으로 적합한 DRM을 선택합니다.
{
"playlist": [
{
"drm": {
"com.widevine.alpha": {
"src": "https://example.edge.naverncp.com/dash/.../manifest.mpd",
"licenseUri": "https://multi-drm.apigw.ntruss.com/api/v1/license",
"licenseRequestHeader": {
"x-ncp-region_code": "KR",
"x-ncp-iam-access-key": "...",
"x-ncp-apigw-timestamp": 1770471614859,
"x-ncp-apigw-signature-v2": "...",
"x-drm-token": "..."
}
},
"com.apple.fps": {
"src": "https://example.edge.naverncp.com/hls/.../index.m3u8",
"certificateUri": "https://multi-drm.apigw.ntruss.com/api/v1/license/fairPlay",
"certificateRequestHeader": {
"x-ncp-region_code": "KR",
"x-ncp-iam-access-key": "...",
"x-ncp-apigw-timestamp": 1770471614859,
"x-ncp-apigw-signature-v2": "...",
"x-drm-token": "...",
"accept": "application/json"
},
"licenseUri": "https://multi-drm.apigw.ntruss.com/api/v1/license",
"licenseRequestHeader": {
"x-ncp-region_code": "KR",
"x-ncp-iam-access-key": "...",
"x-ncp-apigw-timestamp": 1770471614859,
"x-ncp-apigw-signature-v2": "...",
"x-drm-token": "..."
}
}
},
"poster": "https://example.com/poster.jpg",
"description": {
"title": "DRM 보호 영상",
"created_at": "2024.07.13"
}
}
],
"autostart": true
}토큰 갱신
재생 중 DRM 토큰이 만료되면 ref 메서드로 갱신할 수 있습니다.
const playerRef = useRef<PlayerHandle>(null);
// 재생 중 토큰 갱신
playerRef.current?.tokenChange('NEW_TOKEN_VALUE');