Каждый день мы в том или ином виде сталкиваемся с рекламой: на сайтах — с тизерной, в блогах — c нативной, во ВКонтакте и Яндекс.Музыке — c аудиорекламой, на YouTube, стриминговых сервисах и в онлайн-кинотеатрах — с видео. О последней и пойдет речь.
В этой статье я расскажу, как работает видеореклама в интернете, и какими спецификациями она описывается.
Что такое VAST?
Прежде чем начать описывать спецификацию, давайте прикинем, как вообще мы можем показать видеорекламу на сайте? Первое, что приходит в голову – залить файл с рекламным роликом куда-нибудь на сервер, и попросить владельца сайта, у которого мы будем рекламироваться, вставить на страницу тег video со ссылкой на наш рекламный ролик:
<video id="ourVideoAd" src="https://ourhosting.dev/ourVideoAd.mp4"></video>
Неплохо, но как понять, сколько человек его посмотрело? Посмотрело ли вообще? Досмотрели ли они его до конца? Скольких людей заинтересовала реклама? Как нам отправить их на лендинг?
Ответ на все эти вопросы и дает VAST — Video Ad Serving Template, спецификация, разрабатываемая Interactive Advertising Bureau (IAB) и содержащая в себе всю информацию о рекламе: ее физическое нахождение, формат, урлы, которые будут вызываться при наступлении разных событий и т.д.
Ремарка: VAST — это обычный XML.
VAST в дикой природе
Вы можете попробовать сами найти реальный VAST, для этого нужно просто зайти на любой популярный ресурс, на котором была замечена видеореклама, открыть network консоль, и поискать что-нибудь вроде vast или vpaid. У меня получилось найти на rbc.ru, VAST пришел с домена ad.mail.ru/vast/
Из чего состоит VAST?
Последняя версия спецификации в настоящий момент — 4.2, но в реальности, все, в том числе и Google, используют версию 3.0, по ней и будем строить наш пример.
Итак, всё начинается с тега VAST с атрибутом version:
<VAST version="3.0"></VAST>
У тега VAST есть дочерние узлы Error и Ad. Error используется в случае, если сервер не вернул рекламу. Если есть нода Error, то других дочерних узлов у VAST быть не должно:
<VAST version="3.0">
<Error><![CDATA[http://ouradserver.com/noadhandler?error=true]]></Error>
</VAST>
Тег Ad — родительский элемент для узлов InLine или Wrapper.
Атрибуты:
— id: строковый индетификатор
— sequence: целое число больше нуля. Позволяет объединять рекламу в так называемые Ad Pods. Зачем это нужно? Например, рекламный видеоплеер поддерживает показ двух креативов подряд. Или, если по каким-то причинам креатив не показывается, плеер может перейти к следующему. Или, вы нацелены на Smart TV, в котором плеер несколько раз прерывает воспроизведения основного контента. В целом, тут нет однозначного поведения, очень многое зависит от конкретного плеера, в которым показывается ваш VAST.
Пример с Ad Pods:
<VAST version="3.0">
<Ad id="aGVscA" sequence="1">...</Ad>
<Ad id="aGVscB" sequence="2">...</Ad>
<Ad id="aGVscC" sequence="3">...</Ad>
...
<Ad id="aGVscD" sequence="99">...</Ad>
</VAST>
Итак, если рекламный сервер не вернул ошибку, то VAST может быть с тегом InLine:
<VAST version="3.0">
<Ad id="aGVscA">
<InLine>
...
</InLine>
</Ad>
</VAST>
либо c тегом Wrapper:
<VAST version="3.0">
<Ad id="SWFt">
<Wrapper>
...
</Wrapper>
</Ad>
</VAST>
В чем разница между InLine и Wrapper? Тег InLine содержит все, что необходимо для запуска VAST «прямо сейчас», то есть, рекламные креативы, трекинг-урлы и так далее. Wrapper — содержит ссылку на другой VAST. Если в этом месте вам показалось, что запахло рекурсией, то вам не показалось. Чуть позже расскажу подробнее, зачем нужно использовать Wrapper, а сейчас рассмотрим структуру тега InLine.
InLine
Обязательные ноды:
- AdSystem: название рекламной системы, которая предоставила VAST
- AdTitle: заголовок VAST'a
- Impression: ссылка, которая дернется, когда наступит событие impression
- Creatives: контейнер для тегов Creative
Ремарка: событие impression наступает, когда показан первый фрейм креатива.
Может возникнуть вопрос, почему теги AdSystem, и AdTitle являются обязательными. Отчасти, из-за фрода. Дело в том, что в качестве креатива может быть произвольный js-код, забегая вперед скажу, что такие креативы называются VPAID креативами. Т.е., произвольный js-код, который выполняется на миллионах клиентских машин. Если кто-то из владельцев сайтов начнет жаловаться, что реклама вдруг стала перенаправлять пользователей на сомнительные сайты с мобильными подписками, то наличие этих тегов облегчит поиски виновного.
Итак, VAST c нодой InLine:
<VAST version="3.0">
<Ad id="aGVscA">
<InLine>
<AdSystem>Our AdSystem</AdSystem>
<AdTitle>Our video ad</AdTitle>
<AdServingId>a532d16d-4d7f-4440-bd29-2ec05553fc80</AdServingId>
<Impression><![CDATA[https://adserver.com/track/impression]]></Impression>
<Creatives>
...
</Creatives>
</InLine>
</Ad>
</VAST>
Как я уже сказал выше, тег Creatives является контейнером для тегов Creative, у которых есть атрибуты:
- id: id рекламного сервера, которой предоставил VAST
- sequence: порядковый номер, показывающий, каким по счету воcпроизводить креатив. Не нужно путать с атрибутом sequence в теге Ad.
- apiFramework: API Framework, согласно протоколу openRTB
Элемент Creatives может содержать ноды Linear, NonLinearAds или CompanionAds.
Что такое Linear, NonLinearAds и CompanionAds креативы?
Linear – обычный видео креатив. Может показываться сам по себе, или вместе с основным контентом, например, перед началом, тогда это называют pre-roll, в середине или в конце, mid-roll и post-roll соответственно. Это 99% видеорекламы в Интернете. NonLinearAds — показывается во время основного контента, не прерывая его. Может кто-нибудь видел рекламные баннеры, которые всплывают внизу плеера во время воспроизведения ролика на YouTube? Вот, это NonLinearAds. CompanionAds — показывается где-то рядом с основным контентом.
Так как 99% рекламы в Интернете — Linear креативы, то дальше будем рассматривать только их.
Linear — имеет обязательный атрибут skipoffset — через сколько времени можно пропустить креатив, в формате hh:mm:ss.
Обязательные ноды Linear:
- Duration — продолжительность креатива, в формате hh:mm:ss:mmm. Миллисекунды опциональны.
- MediaFiles — содержит ноды MediaFile, не менее одной.
Нода MediaFile — содержит информацию о медиафайле, который будет воспроизводиться. Имеет следующие атрибуты:
- id: id креатива
- delivery: progressive для протоколов последовательного скачивания, например, HTTP, streaming для стриминговых
- type: MIME type файла. Например, video/mp4, video/webm, etc.
- bitrate, либо minBitrate и maxBitrate: битрейт.
- width: ширина креатива
- height: высота креатива
- scalable: булевое значение, указывающее, предназначен ли медиафайл для масштабирования до больших размеров.
- mantainAspectRation булевое значение, указывающее, должно ли сохраняться соотношение сторон, при масштабировании креатива.
- codec: кодек, в соответствии с RFC 4281
- apiFramework: API Framework, согласно протоколу openRTB
Атрибуты delivery, type, width и height, являются обязательными, остальные — нет. Для файлов, у которых нет ширины и высоты, например, если это аудио-файл, можно указывать ноль в качестве значений width и height.
Получается так:
<VAST version="3.0">
<Ad id="aGVscA">
<InLine>
<AdSystem>Our AdSystem</AdSystem>
<AdTitle>Our video ad</AdTitle>
<AdServingId>a532d16d-4d7f-4440-bd29-2ec05553fc80</AdServingId>
<Impression><![CDATA[https://adserver.com/track/impression]]></Impression>
<Creatives>
<Creative>
<Linear skipoffset="00:00:05">
<Duration>00:00:20</Duration>
<MediaFiles>
<MediaFile
delivery="progressive"
type="video/mp4"
width="672"
height="480">
<![CDATA[{mediafile url}]]>
</MediaFile>
</MediaFiles>
</Linear>
</Creative>
</Creatives>
</InLine>
</Ad>
</VAST>
Хорошо, сейчас мы собрали валидный VAST, в который можно подставить свои значения и хоть сейчас запускать в рекламные сети. Но, к сожалению, в нём отсутствует ссылки для статистики и лендинга. Давайте это исправим, и рассмотрим двe необязательные по спецификации ноды – TrackingEvents и VideoClicks.
TrackingEvents — фактически, тут перечисляются урлы, который должен дергать плеер во время наступления различных событий. Урлы находятся в теге Tracking с атрибутом event, значениeм которого является строка с названием события. Например, событие start будет выглядеть так:
<Tracking type="start"><![CDATA[https://adserver.com/track/start]]></Tracking>
Список основных событий:
- start: креатив загрузился и начал воспроизводиться
- creativeView: вообще, креатив может состоять из нескольких креативов, или показываться на одних платформах, и не показываться на других. creativeView позволяет отслеживать, какой креатив просматривается, и, следовательно, какие платформы более распространены.
- firstQuartile: было воспроизведено 25% продолжительности креатива
- midpoint: было воспроизведено 50% продолжительности
- thirdQuartile: было воспроизведено 75% продолжительности
- complete: креатив был полностью воспроизведен
- mute: пользователь убрал звук у креатива
- unmute: пользователь включил креативу звук
- pause: пользователь поставил креатив на паузу
- rewind: пользователь почему-то решил перемотать креатив назад
- resume: пользователь снял воспроизведение креатива с паузы
- fullscreen: пользователь открыл креатив на полный экран
- exitFullscreen: пользователь решил выйти из режима fullscreen
- expand: пользователь нажал кнопочку «expand»
- collapse: пользователь нажал кнопочку «collapse»
- skip: пользователь пропустил креатив (на ютубе очень популярна эта опция)
В реальной жизни, поддержка тех или иных событий лежит на плеере. Например, он может не поддерживать события fullscreen, или skip. Плеер также может не иметь панель управления воспроизведением, т.е., у него могут отсутствововать кнопки типа expand, collapse, rewind, etc. Критически важные события — start, creativeView, firstQuartile, midpoint, thirdQuartile, complete.
Давайте добавим в наш VAST TrackingEvents:
<VAST version="3.0">
<Ad id="aGVscA">
<InLine>
<AdSystem>Our AdSystem</AdSystem>
<AdTitle>Our video ad</AdTitle>
<AdServingId>a532d16d-4d7f-4440-bd29-2ec05553fc80</AdServingId>
<Impression><![CDATA[https://adserver.com/track/impression]]></Impression>
<TrackingEvents>
<Tracking type="start"><![CDATA[{your url}]]></Tracking>
<Tracking type="creativeView"><![CDATA[{your url}]]></Tracking>
<Tracking type="firstQuartile"><![CDATA[{your url}]]></Tracking>
<Tracking type="midpoint"><![CDATA[{your url}]]></Tracking>
<Tracking type="thirdQuartile"><![CDATA[{your url}]]></Tracking>
<Tracking type="complete"><![CDATA[{your url}]]></Tracking>
<Tracking type="skip"><![CDATA[{your url}]]></Tracking>
<Tracking type="close"><![CDATA[{your url}]]></Tracking>
</TrackingEvents>
<Creatives>
<Creative>
<Linear skipoffset="00:00:05">
<Duration>00:00:20</Duration>
<MediaFiles>
<MediaFile
delivery="progressive"
type="video/mp4"
width="672"
height="480">
<![CDATA[{mediafile url}]]>
</MediaFile>
</MediaFiles>
</Linear>
</Creative>
</Creatives>
</InLine>
</Ad>
</VAST>
Тег VideoClicks может содержать три ноды:
- ClickThrough: урл, на который плеер должен отправить пользователя при клике на креатив. Грубо говоря, ссылка на лендинг, со всякими get-параметрами.
- ClickTracking: урл, который трекает сам факт clickthrough, т.е., клик по креативу или по явной ссылке
- CustomClick: урл, который трекает всякие другие клики (non-clickthrough)
В 90% вастов используются первые два тега.
В итоге, у нас получился вот такой InLine VAST:
<VAST version="3.0">
<Ad id="aGVscA">
<InLine>
<AdSystem>Our AdSystem</AdSystem>
<AdTitle>Our video ad</AdTitle>
<AdServingId>a532d16d-4d7f-4440-bd29-2ec05553fc80</AdServingId>
<Impression><![CDATA[https://adserver.com/track/impression]]></Impression>
<TrackingEvents>
<Tracking type="start"><![CDATA[{your url}]]></Tracking>
<Tracking type="creativeView"><![CDATA[{your url}]]></Tracking>
<Tracking type="firstQuartile"><![CDATA[{your url}]]></Tracking>
<Tracking type="midpoint"><![CDATA[{your url}]]></Tracking>
<Tracking type="thirdQuartile"><![CDATA[{your url}]]></Tracking>
<Tracking type="complete"><![CDATA[{your url}]]></Tracking>
<Tracking type="skip"><![CDATA[{your url}]]></Tracking>
<Tracking type="close"><![CDATA[{your url}]]></Tracking>
</TrackingEvents>
<VideoClicks>
<ClickThrough><![CDATA[{your landing}]]></ClickThrough>
<ClickTracking><![CDATA[{your url}]]></ClickTracking>
</VideoClicks>
<Creatives>
<Creative>
<Linear skipoffset="00:00:05">
<Duration>00:00:20</Duration>
<MediaFiles>
<MediaFile
delivery="progressive"
type="video/mp4"
width="672"
height="480">
<![CDATA[{mediafile url}]]>
</MediaFile>
</MediaFiles>
</Linear>
</Creative>
</Creatives>
</InLine>
</Ad>
</VAST>
Wrapper
Как я уже писал выше, если вы видите тег Wrapper в васте, это значит, что этот VAST содержит в себе ссылку на другой VAST. А тот, в свою очередь, также может содержать в себе ссылку на другой VAST. А тот, в свою очередь ..., ну вы поняли.
Зачем нужен тег Wrapper? Его используют, например, когда одна рекламная сеть продает траффик другой рекламной сети, та, в свою очередь, тоже продает траффик в другую рекламную сеть и ваш VAST гуляют по Интернету, пока не найдется релевантный пользователь, которому покажут ваш креатив. Но на каждом этапе, все участники этой схемы вставляют трекинг-пиксели, чтобы вести свою статистику.
Небольшой иллюстрирующий пример
Давайте представим условного Васю. Вася — собственник рекламного агенства «Четвертый круг». К Васе приходит Маша, которая представляет компанию «Лакшери Карс», и просит показать рекламный ролик сто тысяч раз пользователям, у которых месячный доход не ниже полумиллиона рублей в месяц. Всё таки, «Лакшери Карс», уточняет Маша.
Маша предлагает Васе за это хорошие деньги. Вася с Машей бьют по рукам, подписывают кучу бумаг, и Вася приступает к работе. Вася подключен к одной крупной рекламной сети. Для полноты картины, нам потребуются еще действующие лица.
Степан – владелец блога о женском здоровье, а Оля – его постоянная читательница. Что происходит, когда Оля заходит на сайт к Степану? JS cкрипт рекламной сети, который установлен на сайте Степана, отправляет на свой сервер куку с информацией о Маше: ее предположительный возраст, интересы, уровень дохода. После чего, рекламная сеть опрашивает ребят, типа нашего Васи, интересна ли кому-нибудь Оля? Если Оля интересна Васе как пользователь, которого заинтересует реклама «Лакшери Карс», то Вася отправит рекламной сети специальный ответ, в котором будет содержаться ставка и VAST с элементом InLine, ведь креатив хранится на сервере Васи. Если ставка Васи перебьет предложения от других ребят, то Оля увидит ролик «Лакшери Карс».
Вроде все очевидно, но давайте представим ситуацию:
Тогда Петя пойдет к Васе, и скажет, мол, смотри, тут есть Оля, ее интересует блог о здоровье, и ее доход больше 500 тысяч в месяц, она тебе интересна?
Вася, конечно, ответит утвердительно, ведь Оля именно та самая целевая аудитория для «Лакшери Карс». Тогда Вася отдаст VAST Пете, Петя обернет его в свой VAST с тегом Wrapper, своими трекинг-урлами и ссылкой на VAST Васи.
Маша предлагает Васе за это хорошие деньги. Вася с Машей бьют по рукам, подписывают кучу бумаг, и Вася приступает к работе. Вася подключен к одной крупной рекламной сети. Для полноты картины, нам потребуются еще действующие лица.
Степан – владелец блога о женском здоровье, а Оля – его постоянная читательница. Что происходит, когда Оля заходит на сайт к Степану? JS cкрипт рекламной сети, который установлен на сайте Степана, отправляет на свой сервер куку с информацией о Маше: ее предположительный возраст, интересы, уровень дохода. После чего, рекламная сеть опрашивает ребят, типа нашего Васи, интересна ли кому-нибудь Оля? Если Оля интересна Васе как пользователь, которого заинтересует реклама «Лакшери Карс», то Вася отправит рекламной сети специальный ответ, в котором будет содержаться ставка и VAST с элементом InLine, ведь креатив хранится на сервере Васи. Если ставка Васи перебьет предложения от других ребят, то Оля увидит ролик «Лакшери Карс».
Вроде все очевидно, но давайте представим ситуацию:
- В Васину рекламную сеть не входит блог Степана.
- Но есть владелец другой рекламной сети — Петя, в которую входит блог Степана.
- Петя знает о Васе.
- Пете приходит запрос с информацией о Оле, но у него самого нет для нее рекламного предложения.
Тогда Петя пойдет к Васе, и скажет, мол, смотри, тут есть Оля, ее интересует блог о здоровье, и ее доход больше 500 тысяч в месяц, она тебе интересна?
Вася, конечно, ответит утвердительно, ведь Оля именно та самая целевая аудитория для «Лакшери Карс». Тогда Вася отдаст VAST Пете, Петя обернет его в свой VAST с тегом Wrapper, своими трекинг-урлами и ссылкой на VAST Васи.
Ремарка: спецификация не рекомендует использовать более пяти уровней вложенности, но, как я писал, каждый плеер может вести себя по-своему.
Итак, Wrapper обязательно должен содержать ноды AdSystem, VASTAdTagURI и Impression. Про AdSystem и Impression мы уже говорили, а в теге VASTAdTagURI как раз и содержится ссылка на следующий VAST:
VAST с тегом Wrapper:
<VAST version="3.0">
<Ad id="SWFt">
<Wrapper>
<AdSystem>Our AdSystem</AdSystem>
<Impression><![CDATA[https://adserver.com/track/impression]]></Impression>
<VASTAdTagURI><![CDATA[https://adserver.com/anotherVAST.xml]]></VASTAdTagURI>
</Wrapper>
</Ad>
</VAST>
Ремарка: VAST может содержать либо тег InLine, либо Wrapper, но не оба тега сразу.
Заключение
В этой статье мы с вами шаг за шагом построили VAST и рассмотрели основные теги, которые он содержит. Вы можете подставить свои урлы и проверить его валидность, например, в Video Suite Inspector от Google.
Полезные ссылки:
- Спецификация VAST 3.0 от IAB
- Примеры VAST'ов на гитхабе IAB