워터마크 삽입
CloudFront 임베더를 배포하고 Session Manager API로 시청자별 세션 URL을 만들어, 재생 시점에 CDN이 A/B 세그먼트를 섞어 워터마크를 삽입하는 과정을 따라 해 봅니다.
워터마크 삽입 방식
전처리로 영상의 두 가지 버전, A(0/)와 B(1/)가 만들어졌습니다. 워터마크 삽입은 재생 시점에 이루어집니다. 시청자가 스트림을 요청하면 세션 정보를 이진수로 바꾸고, 각 비트 값에 맞는 세그먼트를 골라 내보냅니다. 그 결과 시청자마다 눈에 보이지 않는 고유한 워터마크가 담긴 스트림을 받게 됩니다.
세그먼트 목록은 세션과 관계없이 모든 사용자에게 같은 경로와 파일명으로 제공되므로, 세그먼트 이름을 이용한 공격에도 안전합니다.
동작 흐름
- 세션 매니저가 세션 키(payload)를 생성하고 세션 데이터를 저장합니다.
- 암호화된 세션 정보가 서비스 사이트를 거쳐 CDN으로 전달됩니다.
- CDN의 워터마크 임베더 모듈이 세션 URL에 따라 DASH/HLS 세그먼트를 섞어 전송합니다.
이 레슨은 두 부분으로 구성됩니다. CloudFront 임베더를 배포하고(1부), Session Manager API로 시청자별 세션 URL을 만듭니다(2부). 위 영상은 DRM과 워터마크가 적용된 콘텐츠이며 같은 흐름으로 재생됩니다. 페이지를 열면 Lab이 Session URL API로 세션을 요청하므로, 플레이어 아래의 세션 데이터가 지금 재생에 실제로 삽입된 값입니다.
지원 CDN
- Amazon CloudFront (이 레슨)
- Akamai
- Cloudflare Workers
시작하기 전에
- 이전 레슨에서 전처리한 콘텐츠가 S3 출력 버킷(
wm-contents/…/0,…/1)에 있어야 합니다. - DoveRunner Site ID, Site Key, Access Key: DoveRunner Console에서 확인합니다.
- IAM 역할, Lambda 함수, CloudFront 배포를 만들 수 있는 AWS 계정
1부. CloudFront 임베더 배포하기
CloudFront의 모든 뷰어 요청마다 Lambda@Edge 함수가 실행됩니다. 함수는 URL의 세션 토큰을 읽고 A/B 버전의 세그먼트를 섞습니다. 이 레슨은 AWS 콘솔에서 직접 설정하며, 코드로 구성하고 싶다면 CDK 샘플도 있습니다.
1. IAM 역할 만들기
함수에 사용할 IAM 역할을 만듭니다. 가이드에 나온 Lambda와 CloudFront 권한, 그리고 CloudWatch Logs 접근 권한을 부여합니다. 이어서 신뢰 관계를 편집해 Lambda와 Lambda@Edge가 모두 이 역할을 맡을 수 있게 합니다.
2. Lambda@Edge 함수 만들기
- Lambda를 열고 리전이 **미국 동부(버지니아 북부, us-east-1)**인지 확인합니다. Lambda@Edge 함수는 이 리전에서만 만들 수 있습니다. 다른 리전에서 만들었다면 삭제하고 처음부터 다시 해야 합니다.
- 함수 이름을 입력하고 런타임은 Node.js 22.x, 아키텍처는 x86_64로 둡니다.
- 추가 설정에서 사용자 지정 실행 역할을 켜고 방금 만든 역할을 선택한 뒤 함수 생성을 클릭합니다.
S3 버킷은 다른 리전에 있어도 됩니다(이 튜토리얼은 오레곤, us-west-2에 둡니다). us-east-1에 있어야 하는 것은 함수뿐입니다.
3. 임베더 코드 업로드
업데이트, .zip 파일에서 업로드를 차례로 선택하고, DoveRunner 샘플 다운로드 페이지의 CloudFront 임베더 샘플을 선택합니다.
4. config.json 설정
| 키 | 설정값 |
|---|---|
aesKey |
DoveRunner Site Key |
type |
A/B가 0/, 1/ 폴더로 나뉘어 있으면(Transcoding & Packaging 출력이 이 구조입니다) directory prefix. 두 버전이 한 폴더에 있고 B 파일 이름 앞에 b가 붙어 있다면 unlabeled A variant 타입을 사용합니다. |
availableInterval |
타임스탬프가 유효한 시간(분). 0이면 검사하지 않으며, 데모에서는 0으로 충분합니다. |
prefixFolder |
패키징된 콘텐츠가 있는 폴더. Transcoding & Packaging 출력은 wm-contents입니다. |
5. 배포하고 버전 게시하기
변경 사항을 배포한 다음 새 버전을 게시합니다. Lambda@Edge에는 게시되지 않은 초안이 아니라 게시된 버전이 필요합니다. 오른쪽 위에서 해당 버전의 ARN을 복사합니다.
6. CloudFront 배포 만들기
- CloudFront를 열고 배포를 만듭니다. 이 데모는 Pay as you go 요금제를 선택합니다.
- 배포 이름을 입력하고, 오리진으로는 패키징 작업 결과가 저장된 S3 버킷을 선택합니다.
- 출력 버킷은 비공개이므로 Allow private S3 bucket access to CloudFront를 선택한 상태로 둡니다. CloudFront가 오리진 액세스 제어(OAC)를 만들고 버킷 정책도 업데이트합니다. 이 설정이 없으면 모든 요청이 접근 거부로 끝납니다.
- 보안 단계에서 이 데모는 별도로 과금되는 WAF 보호를 켜지 않습니다. 이후 배포를 생성합니다.
7. 뷰어 요청에 함수 연결하기
배포의 동작(Behaviors) 탭에서 기본 동작을 선택하고 편집을 클릭합니다. 함수 연결에서 뷰어 요청을 Lambda@Edge로 설정하고, 복사해 둔 함수 ARN을 붙여 넣은 뒤 저장합니다.
마지막 수정에 배포 중 대신 날짜가 표시될 때까지 기다린 다음 배포의 도메인 이름을 기록해 둡니다. 2부에서 사용합니다.
2부. Session Manager API로 세션 URL 만들기
서비스에서 시청자 정보를 담아 Session Manager API를 호출하면, 재생 세션이 담긴 혼합 콘텐츠 URL을 반환합니다. 플레이어가 CloudFront에 요청하는 URL이 바로 이것입니다.
인증 방식
암호화된 pallycon-apidata 파라미터 또는 JWT 베어러 토큰으로 인증할 수 있습니다. 이 레슨은 pallycon-apidata를 사용합니다. CloudFront에서는 wmt_type을 기본값인 AES로 둡니다. JWT는 Akamai와 Fastly용입니다.
요청 파라미터
| 필드 | 값 |
|---|---|
domain |
CloudFront 도메인 |
output_path |
워터마크 패키징을 요청할 때 입력한 Output Directory Path |
cid |
패키징 작업에 입력한 콘텐츠 ID |
streaming_format |
dash 또는 hls |
forensic_mark |
삽입할 세션 데이터(사용자 ID, 기기 정보 등). 최대 254바이트 |
wmt_type |
AES |
prefix_folder |
Transcoding & Packaging으로 패키징한 콘텐츠는 wm-contents |
마크가 254바이트를 넘으면 API가 A1916 오류를 반환하고, 요청 해시가 맞지 않으면 A1007 오류를 반환합니다.
요청이 만들어지는 과정
- JSON 요청 데이터를 Site Key로 AES-256 CBC 암호화합니다.
- Access Key, Site ID, 암호화된 데이터, 타임스탬프를 SHA-256으로 해시합니다.
data,timestamp,hash를 JSON으로 묶고 base64로 인코딩해pallycon-apidata로 사용합니다.
코드로 직접 작성할 수도 있습니다(Python, Java 샘플 제공). 이 퀵스타트에서는 Lab Playground가 대신 만들어 줍니다.
Lab Playground에서 요청 만들기
- Lab Playground의 FWM Session Tools를 열고 Session URL API를 선택합니다.
- Site ID, Site Key, Access Key를 입력합니다.
- 요청 데이터를 채웁니다. CloudFront 도메인, 출력 경로
lab-contents, 콘텐츠 ID, 프리픽스 폴더wm-contents를 입력합니다. - Forensic mark를 입력하고 DASH 또는 HLS를 고른 뒤, 토큰 타입은 AES로 두고 Build request를 클릭합니다.
- 요청 URL을 엽니다. 응답에 워터마크 재생용 세션 URL이 담겨 있습니다.
세션 URL의 구조
URL에는 CloudFront 도메인, 프리픽스 폴더, forensic mark가 담긴 암호화된 페이로드, 그리고 앞에서 본 출력 경로, 콘텐츠 ID, 포맷이 차례로 들어 있습니다. 플레이어가 이 URL을 요청하면 임베더가 페이로드를 해독하고 A/B 버전의 세그먼트를 섞습니다.
재생해 보기
Lab Playground의 DRM Playback Tester를 열고, 세션 URL을 매니페스트로 붙여 넣은 뒤 라이선스 URL과 토큰을 입력합니다. 토큰은 테스터의 DRM 배지에 표시된 DRM 종류에 맞춰 발급합니다.
워터마크 삽입은 DRM과 무관하며, 세션 URL은 어느 쪽이든 같은 방식으로 동작합니다. 다만 이 콘텐츠는 DRM으로 보호되어 있으므로 플레이어에는 라이선스가 필요합니다. forensic mark를 다르게 해서 요청하면 세션이 달라지고, 고유한 워터마크가 담긴 스트림이 만들어집니다.
정리
- CloudFront 임베더는 콘텐츠 앞단에서 세션마다 A/B 세그먼트를 섞습니다.
- Session Manager API는 시청자마다 고유한 세션 URL을 만듭니다.
- 다음 레슨에서는 유출된 영상에서 워터마크를 검출하는 방법을 알아봅니다.
다른 삽입 방식과 자세한 내용은 워터마크 삽입 가이드를 참고하세요.