Skip to content

SCTE35-IN 마커가 END-DATE보다 먼저 나타나는 원인 ​

광고 종료 마커가 선언된 시각보다 평균 2.2초 일찍 매니페스트에 등장했습니다. IN을 아무리 뜯어봐도 답이 없었고, 답은 OUT 쪽에 있었습니다.

먼저 매니페스트를 눈으로 봅니다 ​

광고 브레이크의 시작과 끝을 EXT-X-DATERANGE로 선언하고, 끝나는 지점에서 SCTE35-IN을 내보내는 구조입니다. OUT을 발행할 때 END-DATE를 이미 계산해서 넣어두기 때문에, IN은 그 END-DATE 시각에 맞춰 나오는 게 정상입니다.

그런데 실제로는 이렇게 나왔습니다.

m3u8
#EXT-X-DATERANGE:ID="<ad-break-id>",START-DATE="2026-03-11T04:21:12.900Z",END-DATE="2026-03-11T04:29:40.900Z",DURATION=508.000,SCTE35-OUT=0xFC302F00...

... (광고 segment 들) ...

#EXT-X-PROGRAM-DATE-TIME:2026-03-11T04:29:38.700Z
#EXT-X-DATERANGE:ID="<ad-break-id>",START-DATE="2026-03-11T04:29:38.700Z",SCTE35-IN=0xFC3025000...
#EXT-X-DISCONTINUITY
#EXTINF:4.000,
segment_<channel-id>_10609.ts

산수는 단순합니다.

text
선언된 END-DATE          2026-03-11T04:29:40.900Z
IN 마커가 실제로 찍힌 PDT  2026-03-11T04:29:38.700Z
--------------------------------------------------
Delta                                    -2.200s

광고가 선언보다 2.2초 일찍 끝난 것처럼 보입니다. 광고를 끝까지 안 틀고 잘라버린 것처럼 읽히니, 처음 보면 꽤 놀랍습니다.

49개 샘플에서 나온 패턴 ​

한 건으로 판단할 수 없으니 브레이크를 모았습니다. 49개 샘플의 결과입니다.

마커PDT Delta 평균최대 이탈렌디션 간 차이
OUT0.000초0.000초없음
IN-2.2초-4.7초없음

이 표에서 읽어야 할 게 세 가지 있습니다.

1) OUT은 0.000초입니다. 소수점 세 자리까지 0입니다. 즉 OUT 마커가 찍힌 PDT와 선언된 START-DATE는 완벽히 일치합니다. 파이프라인이 시각을 잘못 계산하고 있는 게 아닙니다.

2) IN은 항상 음수입니다. 늦게 나오는 게 아니라 항상 일찍 나옵니다. 부호가 한 방향으로만 쏠려 있으면 랜덤 오차가 아니라 구조적 원인이 있다는 뜻입니다.

3) 모든 렌디션에서 Delta가 같습니다. 1080p, 720p, 480p 전부 같은 값이 나왔습니다. 특정 비트레이트의 트랜스코딩 타이밍 문제라면 렌디션마다 흔들려야 하는데 그렇지 않았습니다. 렌디션보다 상위, 즉 광고 구간의 좌표계를 잡는 단계에서 결정된다는 신호입니다.

참고: 여러 렌디션에서 오차가 똑같이 나오면 렌디션 레벨을 뒤질 필요가 없습니다. 공통 상위 단계에서 이미 값이 정해진 것입니다. 이 관찰 하나로 조사 범위가 반으로 줄었습니다.

원인은 OUT 태그가 밀리는 지연입니다 ​

핵심은 DATERANGE의 시각 값과, 그 태그가 매니페스트 안에서 놓이는 위치는 별개라는 점입니다.

  • START-DATE, END-DATE: 계산해서 써넣는 값입니다. 이 값 자체는 맞게 나옵니다.
  • 태그가 매니페스트의 몇 번째 줄에 들어가는가: splice 지점을 세그먼트 경계에 정렬하면서 결정되는 위치입니다. 여기가 밀립니다.

OUT이 세그먼트 경계 정렬 때문에 원래 있어야 할 자리보다 뒤로 밀려 들어가면, 광고 구간 전체가 뒤로 밀립니다. 광고 소재의 총 길이는 그대로인데 시작점만 밀렸으니, 끝나는 지점은 END-DATE에 도달하기 전에 와버립니다.

START-DATE와 END-DATE는 고정 값인데 OUT 태그 배치가 지연되면서 실제 광고 구간이 늦게 시작해 END-DATE보다 일찍 끝나는 구조

즉 IN 마커는 자기 일을 제대로 했습니다. 광고 소재가 끝난 지점에 정확히 붙었습니다. 문제는 그 광고 소재가 시작부터 밀려 있었다는 것입니다. END-DATE는 OUT 발행 시점에 계산해서 고정된 값이라 뒤늦게 따라 움직이지 않습니다. 그래서 둘 사이에 틈이 생깁니다.

참고: "IN이 일찍 나온다"는 증상 서술을 그대로 믿고 IN 발행 로직만 파면 답이 안 나옵니다. DATERANGE는 구간을 선언하는 태그이고, 선언과 배치는 다른 단계에서 결정됩니다. 증상이 나타난 곳과 원인이 있는 곳이 다른 전형적인 예입니다.

최대 -4.7초는 어디서 오는가 ​

평균 -2.2초에 최대 -4.7초, 이 범위는 OUT 태그가 세그먼트 경계에 맞춰 밀리는 지연의 크기와 맞물립니다. 이 지연 자체는 실측상 0초에서 5초 사이로 흔들리는 것으로 확인됐고, IN 마커의 이탈량은 그 지연을 거의 그대로 물려받습니다.

관측값범위대응되는 원인
IN 마커 이탈0초에서 -4.7초실제 삽입 지연 0초에서 약 5초
IN 마커 평균-2.2초세그먼트 경계 정렬로 평균적으로 밀리는 양

세그먼트 길이가 4초 전후인 환경에서 splice 지점이 경계 안 어디에 걸릴지는 균등하게 흩어집니다. 그러면 평균 밀림량은 세그먼트 길이의 절반 근처가 되고, 최대는 세그먼트 하나 길이를 조금 넘는 지점에서 형성됩니다. 관측된 평균 -2.2초와 최대 -4.7초가 정확히 그 모양입니다.

이건 좋은 신호입니다. 두 현상의 수치가 같은 분포를 공유한다면, 원인이 하나라는 강한 증거입니다.

주의: 반대로 두 현상의 분포가 달랐다면 원인을 하나로 묶으면 안 됩니다. "둘 다 광고 구간에서 발생한다"는 이유만으로 합쳐서 보다가 진짜 두 번째 원인을 놓치는 경우가 흔합니다. 분포를 맞춰보는 과정을 생략하지 말아야 합니다.

매니페스트 내부 값 기준 측정 ​

이번 측정은 외부 시계를 끌어올 필요가 없었습니다. 비교 대상이 둘 다 매니페스트 안에 있기 때문입니다.

text
비교 대상 1: EXT-X-DATERANGE 의 END-DATE      (매니페스트 내부)
비교 대상 2: IN 마커 직전의 PROGRAM-DATE-TIME (매니페스트 내부)

외부 시계에 의존하지 않으니 NTP 상태, 리전, 관측 지점 같은 변수가 아예 개입하지 않습니다. 그래서 이 -2.2초는 논쟁의 여지가 없는 값입니다.

참고: 가능하면 측정을 한 파일 안에서 닫는 편이 좋습니다. 매니페스트 안의 두 값을 비교하는 검증은 재현이 쉽고, "네 시계가 틀린 거 아니냐"는 반박을 원천적으로 차단합니다.

곁가지 하나: 광고 세그먼트의 PDT 누락 ​

측정을 자동화하다가 부딪힌 문제가 있습니다. 광고 구간의 세그먼트 중 20에서 30% 정도에만 PDT가 붙어 있고 나머지에는 없었습니다.

m3u8
#EXT-X-PROGRAM-DATE-TIME:2026-03-11T04:21:12.900Z    <- 광고 첫 segment: 있음
#EXTINF:15.000,
ad_<creative-id>_001.ts
#EXTINF:15.000,
ad_<creative-id>_002.ts                              <- PDT 없음
#EXTINF:15.000,
ad_<creative-id>_003.ts                              <- PDT 없음

이건 IN 마커 이탈과는 별개 사안입니다. 광고 구간에서는 시작과 끝에만 PDT를 넣는 구현이라 그렇습니다. 필요하면 모든 광고 세그먼트에 PDT를 붙이도록 설정을 바꿀 수 있습니다.

다만 이 누락 때문에 측정 스크립트는 PDT가 없는 구간을 EXTINF 누적으로 채워서 계산해야 했습니다. 그리고 그 과정에서 PDT 간격과 EXTINF 합이 안 맞는 별개의 현상을 발견했는데, 이 부분은 다른 글에서 따로 정리하겠습니다.

정리 ​

  • 광고 종료를 알리는 SCTE35-IN 마커가 선언된 END-DATE보다 평균 2.2초, 최대 4.7초 일찍 매니페스트에 나타났습니다.
  • 49개 샘플에서 OUT의 PDT Delta는 0.000초였고 IN만 항상 음수였습니다. 모든 렌디션에서 값이 동일했습니다.
  • 원인은 IN 발행 로직이 아니라 OUT 태그가 세그먼트 경계에 맞춰 밀리는 배치 지연입니다. OUT이 밀리면 광고 구간 전체가 밀리지만 END-DATE는 고정값이라 함께 움직이지 않습니다.
  • 이탈량의 분포(평균 약 세그먼트 절반, 최대 약 세그먼트 하나)가 OUT 지연의 분포와 일치한다는 점이 원인이 하나라는 증거입니다.
  • 측정을 매니페스트 내부 값끼리로 닫으면 외부 시계 변수가 사라져서, 수치를 두고 다툴 일이 없어집니다.

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