SSAI Click-through, 플레이어 CTA가 뜨지 않는 이유
SSAI 스트림에 CTA(Call To Action, "지금 구매하기" 같은 클릭 유도 버튼) 오버레이를 붙이는 작업을 해본 적이 있습니다. 광고가 재생되는 동안 플레이어 화면 위에 버튼을 띄우고, 누르면 그 광고에 연결된 랜딩 페이지로 이동하는 기능입니다. 막상 붙여보니 문서만 보고 짐작했던 것과 실제 동작이 어긋나는 지점이 몇 군데 있었습니다. 이번 글에서는 StreamPackage의 SSAI Click-through 기능을 직접 구현하면서 겪은 세 가지 문제를 정리합니다.
Click-through가 동작하는 기본 구조
StreamPackage의 SSAI 트래킹 정보 응답은 광고 구간(avail)마다 광고 목록(ads)을 담고 각 광고는 trackingEvents라는 배열을 갖습니다. 이 배열의 항목 중 eventType이 clickThrough인 항목에는 beaconUrls라는 필드가 있습니다. 여기 담긴 URL이 바로 CTA를 클릭했을 때 이동할 랜딩 페이지 주소입니다. 대략 이런 모양입니다.
{
"adId": "ad_0001",
"durationInSeconds": 30,
"startTimeInSeconds": 0,
"trackingEvents": [
{
"eventType": "clickThrough",
"beaconUrls": ["https://ad.example.com/landing"],
"startTimeInSeconds": 0
}
]
}플레이어는 지금 재생 중인 위치를 이 ads 목록과 대조해 "지금 재생 중인 광고"를 특정합니다. 그런 다음 그 광고의 clickThrough 항목에서 beaconUrls를 꺼내 CTA 버튼에 연결합니다. 말로는 간단한데 실제로 이 매칭이 항상 성공하는 건 아니었습니다.
문제 1: 절대 시간 기준이 없어서 광고 자체가 버려진다
현재 스펙에서 광고 하나를 특정하는 시간 필드는 startTimeInSeconds와 durationInSeconds뿐입니다. 둘 다 광고 구간 시작을 기준으로 한 상대 시간입니다. 그런데 라이브 스트림에서는 플레이리스트 윈도우가 계속 앞으로 밀립니다. 그래서 플레이어가 들고 있는 "지금 재생 위치"와 이 상대 시간 사이의 기준점이 미묘하게 어긋나는 순간이 생깁니다. 이 어긋남이 생기면 플레이어는 지금 재생 중인 광고를 특정하지 못합니다. 매칭에 실패한 광고는 그냥 버려집니다. clickThrough의 beaconUrls가 응답에 멀쩡히 들어 있어도 그 광고 자체가 매칭되지 않으면 CTA는 뜨지 않습니다.
HLS 플레이리스트에는 EXT-X-PROGRAM-DATE-TIME처럼 상대 위치를 절대 시각(UTC)에 고정해주는 태그가 있습니다. 광고 쪽에도 이런 절대 시각 기준 필드가 하나 있으면 상대 시간 계산에 기대지 않고 광고를 특정할 수 있습니다. 그러면 이 문제는 사라집니다. 실제로 문서와 응답 스펙을 다시 확인해봐도 이런 절대 시각 필드는 아직 없었습니다. CTA를 라이브 환경에서 안정적으로 띄우려면 이 필드가 꼭 필요하다고 느꼈습니다.
문제 2: clickThrough만으로는 클릭이 집계되지 않는다
두 번째로 헷갈렸던 부분은 클릭 자체와 클릭 지표가 별개로 움직인다는 점입니다. eventType: "clickThrough" 항목은 사용자가 버튼을 눌렀을 때 어디로 보낼지(랜딩 페이지 리다이렉트)를 결정할 뿐입니다. 그 클릭이 지표로 집계되는 것과는 다른 이야기였습니다. 클릭이 실제로 카운트되려면 trackingEvents에 eventType: "clickTracking" 항목이 별도로 존재해야 했습니다. clickThrough 하나만 붙여 둔 상태로 테스트했을 때는 버튼을 눌러 랜딩 페이지까지는 잘 이동했습니다. 그런데 대시보드에서 클릭 수치는 계속 0으로 남아 있었습니다. 리다이렉트 동작과 지표 집계가 서로 다른 eventType에 걸려 있다는 걸 확인한 뒤에야 원인을 찾을 수 있었습니다.
문제 3: 트래킹 URL이 처음 한 번만 값을 주고 그 뒤로는 계속 빈 값
세 번째는 트래킹 URL을 폴링하는 쪽에서 발견한 문제입니다. StreamPackage의 트래킹 URL은 폴링 방식으로 동작합니다. 매 요청마다 아직 전달되지 않은 최신 이벤트만 반환하고 이미 반환한 이벤트는 다시 보내지 않는 구조입니다. 그런데 실제로 반복 호출해보니 첫 번째 광고 구간에서만 값이 정상적으로 내려왔습니다. 그 이후로는 새로운 광고 구간이 열려도 계속 다음과 같은 빈 응답만 돌아왔습니다.
{
"avails": ,
"dashAvailabilityStartTime": null,
"hlsAnchorMediaSequenceNumber": 1694498,
"nextToken": null,
"nonLinearAvails":
}"이미 보낸 이벤트는 다시 안 보낸다"는 설계라면 새로운 광고 구간이 열렸을 때는 그 구간에 대한 새 이벤트가 와야 정상입니다. 그런데 관찰한 동작은 달랐습니다. 새 광고 구간이 열려도 빈 배열만 계속 내려오는 쪽이었습니다. 첫 응답 이후 트래킹 쪽 상태가 갱신되지 않고 멈춰버리는 것처럼 보였습니다. 이 부분은 폴링 쪽 상태 관리를 다시 들여다볼 필요가 있어 보입니다.
정리하며
SSAI 환경에서 CTA를 붙일 때는 세 가지를 순서대로 확인해보길 권합니다. 먼저 광고를 특정하는 데 상대 시간만 쓰고 있는지 봅니다. 절대 시각 기준이 없어서 매칭이 실패할 여지는 없는지도 같이 확인합니다. 다음은 trackingEvents입니다. clickThrough와 clickTracking이 둘 다 들어 있는지, 리다이렉트만 되고 지표는 안 잡히는 상태는 아닌지 확인합니다. 마지막은 폴링입니다. 트래킹 URL을 여러 광고 구간에 걸쳐 반복 호출해보고 두 번째 구간부터도 값이 제대로 내려오는지 봅니다. CTA가 안 뜨거나 클릭이 안 잡히는 문제는 대부분 이 세 지점 중 하나에서 나왔습니다.