Skip to content

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를 클릭했을 때 이동할 랜딩 페이지 주소입니다. 대략 이런 모양입니다.

json
{
  "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은 폴링 방식으로 동작합니다. 매 요청마다 아직 전달되지 않은 최신 이벤트만 반환하고 이미 반환한 이벤트는 다시 보내지 않는 구조입니다. 그런데 실제로 반복 호출해보니 첫 번째 광고 구간에서만 값이 정상적으로 내려왔습니다. 그 이후로는 새로운 광고 구간이 열려도 계속 다음과 같은 빈 응답만 돌아왔습니다.

json
{
  "avails": ,
  "dashAvailabilityStartTime": null,
  "hlsAnchorMediaSequenceNumber": 1694498,
  "nextToken": null,
  "nonLinearAvails":
}

"이미 보낸 이벤트는 다시 안 보낸다"는 설계라면 새로운 광고 구간이 열렸을 때는 그 구간에 대한 새 이벤트가 와야 정상입니다. 그런데 관찰한 동작은 달랐습니다. 새 광고 구간이 열려도 빈 배열만 계속 내려오는 쪽이었습니다. 첫 응답 이후 트래킹 쪽 상태가 갱신되지 않고 멈춰버리는 것처럼 보였습니다. 이 부분은 폴링 쪽 상태 관리를 다시 들여다볼 필요가 있어 보입니다.

정리하며 ​

SSAI 환경에서 CTA를 붙일 때는 세 가지를 순서대로 확인해보길 권합니다. 먼저 광고를 특정하는 데 상대 시간만 쓰고 있는지 봅니다. 절대 시각 기준이 없어서 매칭이 실패할 여지는 없는지도 같이 확인합니다. 다음은 trackingEvents입니다. clickThrough와 clickTracking이 둘 다 들어 있는지, 리다이렉트만 되고 지표는 안 잡히는 상태는 아닌지 확인합니다. 마지막은 폴링입니다. 트래킹 URL을 여러 광고 구간에 걸쳐 반복 호출해보고 두 번째 구간부터도 값이 제대로 내려오는지 봅니다. CTA가 안 뜨거나 클릭이 안 잡히는 문제는 대부분 이 세 지점 중 하나에서 나왔습니다.

基于 VitePress 构建 · 部署于腾讯云 EdgeOne Pages