如今联网电视(CTV)是视频广告预算的重要去处,也是最难核实花钱效果的地方。一场为德克萨斯观众购买的投放,可能在纽约播出,可能出现在您从未选过的应用里,也可能根本没播,而报告依然显示已投放的展示量。CTV 上的广告验证,就是像每个地区的真实观众那样去观看广告时段。
本指南介绍 CTV 为何难以验证、哪些检查最重要,以及一种查看各地区实际播放广告的实用方法。
为什么 CTV 更难验证
在网页上,验证服务商会在广告旁边运行脚本,读取发生了什么。在电视上,这大多行不通:
- 服务器端广告插入(SSAI)。 很多视频流会在到达电视之前,在服务器上把广告拼接进视频。广告请求来自这台服务器,它通过请求头转发观众的 IP 地址和设备信息。如果欺诈者伪造这台服务器,“观众”就可以凭空捏造。
- 应用内监测有限。 电视应用运行在多种操作系统上,并不都支持网页和移动端常用的监测 SDK,因此可见性和设备检查并不完整。
- 没有 Cookie。 CTV 依赖设备广告 ID 和家庭 IP,两者都可以被重置或伪造。
- 地区由 IP 决定。 大多数流媒体服务根据家庭 IP 的位置决定观众看到哪些广告,往往也决定看到哪些内容。
- 供应链又长又多层。 一次展示在您买到之前,可能经过应用、供应平台和多个转售方。
结果是:CTV 报告描述的是广告服务器被告知的情况,不一定是屏幕上真正播放的内容。
需要检查什么
一套有效的 CTV 验证流程覆盖五个方面:
- 地域。 广告是否只在购买的地区播放?从每个目标地区内部检查,也从外部检查,以发现溢出投放。
- 库存。 是否在卖给您的应用和频道上播放?把应用与发布商的
app-ads.txt以及约定的卖方名单进行比对。 - 素材。 每个市场播放的版本是否正确,包括语言、优惠和法律文字?
- 投放质量。 广告是否完整播放、处在干净的广告时段里,没有黑屏、中断或同一条广告重复?
- 上下文。 广告前后是什么内容?品牌安全在流媒体上和在网页上同样重要。
仅靠投放日志无法回答以上任何一个问题。您需要来自观众一侧的观察。
如何按地区检查流媒体广告
很多带广告的流媒体服务也能在网页浏览器中运行,它们的网页播放器请求广告的方式与电视应用类似。因此,位于本地 IP 后面的浏览器是一个实用的观察点。
1. 制定地区和频道计划
列出投放的地区、购买的服务和频道,以及广告应当播出的时间。再加入一两个未购买的地区,用来发现计划外的投放。
2. 通过住宅 IP 进入每个地区
流媒体服务根据 IP 判断位置,并且经常拒绝或区别对待数据中心流量。使用定位到所需城市的住宅代理,并用粘性会话 ID 在整个观看过程中保持同一个 IP,让服务看到的是一个家庭。
customer-USERNAME-country-us-city-dallas-sid-dal-ctv-01-ttl-1800:PASSWORD
3. 播放视频流并记录广告时段
在真实浏览器中打开网页播放器,开始播放,并采集两样东西:播放器发出和收到的广告请求与响应(通常是 VAST 或 VMAP XML),以及每个广告时段的视频。每条广告记录:素材 ID、广告主、时长、在广告时段中的位置、地区、时间和前后内容。
用 Playwright 做最简单的采集如下:
from playwright.sync_api import sync_playwright
PROXY = {
"server": "http://p.shifter.io:443",
"username": "customer-USERNAME-country-us-city-dallas-sid-dal-ctv-01-ttl-1800",
"password": "PASSWORD",
}
def capture_ad_calls(stream_url, seconds=600):
seen = []
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY, headless=False)
page = browser.new_page()
def on_response(resp):
ctype = resp.headers.get("content-type", "")
if "xml" in ctype and ("vast" in resp.url.lower() or "vmap" in resp.url.lower()):
seen.append({"url": resp.url, "status": resp.status, "body": resp.text()})
page.on("response", on_response)
page.goto(stream_url, wait_until="domcontentloaded")
page.wait_for_timeout(seconds * 1000)
browser.close()
return seen
URL 过滤条件只是起点:每个服务的广告调用命名方式不同,所以先看一次网络面板再调整。如果是服务器端插入,广告已经在视频里,可能没有可采集的 VAST 调用。这时广告时段的屏幕录像就是您的证据。
4. 与计划比对
针对每个地区和每个服务,把实际播放的内容与购买内容对照。标记在购买地区之外出现的广告、在购买地区缺失的广告、素材版本错误,以及出现黑屏或重复的广告时段。
5. 抽查原生应用
对于原生电视应用,把测试设备放在通过代理路由的网络中,重复整个会话。请把它视为抽查:应用可能用自己的方式定位观众。
值得关注的欺诈信号
来自观众一侧的检查,也能暴露大多数 CTV 欺诈背后的模式:
- 在您自己的会话中从未出现过广告的地区,却有已投放的展示量。
- 账单上有、但您找不到的应用,或者在
app-ads.txt中没有列出该卖方的应用。 - 不可能的设备组合,例如大量来自数据中心网络的”电视”流量。
- 比内容允许的更长的广告时段,这是广告位被填塞的迹象。
关于检测方面,我们的实时检测广告欺诈指南对这些信号有更详细的介绍。
实用建议
- 轮换家庭,而不只是城市。 每次观看会话使用新的会话 ID,避免一个 IP 代表整个市场。
- 在正确的时间观看。 很多投放按时段排期,凌晨 3 点的空广告时段说明不了什么。
- 让浏览器与地区匹配。 时区和语言要与 IP 一致,否则服务可能把这次访问视为异常。
- 保留证据。 对每个被标记的广告时段保存录像、广告响应和 IP 位置,让补偿要求站得住脚。
- 展示广告也用同样的方法。 这和在网页上发现伪装广告和地域定向广告是同一套思路。
总结
CTV 报告告诉您的是广告服务器被告知的内容。要知道实际播放了什么,就要从每个地区内部观看广告时段:目标城市的住宅 IP、每次会话一个家庭、每个广告时段的录像,以及与计划的比对。在您购买的地区定期执行,溢出投放、缺失投放和错误素材就会在投放结束前暴露出来。