VP Ad SDK предоставляет возможность показывать in-stream видео-рекламу в своем приложении, во время просмотра видео. Реклама может быть показана перед началом показа видео (preroll), во время показа (midroll) и после показа (postroll). SDK загружает данные и предоставляет приложению возможность показывать рекламу как в своем видео-плеере, так и в плеере приложения.
Инициализация
Для показа рекламного видео в вашем приложении необходимо создать экземпляр класса InstreamAd. Для создания экземпляра InstreamAd необходимо указать ваш slotId. Для каждого видео в приложении требуется создавать свой экземпляр класса InstreamAd.
private InstreamAd ad;private void initAd(){ // Включение режима отладки // MyTargetManager.setDebugMode(true); // Создаем экземпляр InstreamAd ad = new InstreamAd(YOUR_SLOT_ID, this);}
Выбор плеера
Плеер SDK
VK Ad SDK предоставляет типовой плеер для проигрывания видео-рекламы.
private InstreamAd ad;private void initAd(){ // Создаем экземпляр InstreamAd ad = new InstreamAd(YOUR_SLOT_ID, this); // Устанавливаем плеер SDK ad.useDefaultPlayer(true); // используется ExoPlayer, можно просто вызвать ad.useDefaultPlayer() // ad.useDefaultPlayer(false); // используется стандартный плеер Android SDK // Добавляем плеер на экран layout.addView(ad.getPlayer().getView());}
Плеер приложения и InstreamAdPlayer
Для проигрывания рекламы в плеере приложения, он должен реализовывать интерфейс InstreamAdPlayer и уведомлять установленный ему слушатель AdPlayerListener. Для использования своего плеера надо вызвать метод setPlayer(InstreamAdPlayer player) у созданного экземпляра InstreamAd.
private InstreamAd ad;private void initAd(){ // Создаем экземпляр InstreamAd ad = new InstreamAd(YOUR_SLOT_ID, this); // Устанавливаем плеер MyAdPlayer appPlayer = new MyAdPlayer(); ad.setPlayer(appPlayer);}
Библиотечный класс InstreamAd сам вызывает методы интерфейса InstreamAdPlayer.
В ответ приложение должно вызывать методы обратного вызова интерфейса InstreamAdPlayer.AdPlayerListener.
class MyAdPlayer implements InstreamAdPlayer{ private @Nullable AdPlayerListener listener; private MyVideoPlayer myVideoPlayer; private void SomeMethod() { ... // При ошибках воспроизведения видео надо вызвать соответствующий метод слушателя. if (errorMessage != null && listener != null) { listener.onAdVideoError(errorMessage); } } private void OtherMethod() { ... // Когда воспроизведение видео завершилось, надо вызвать соответствующий метод слушателя. if (videoIsEnded && listener != null) { listener.onAdVideoCompleted(); } } @Override public @Nullable AdPlayerListener getAdPlayerListener() { // Вернуть сохранённый слушатель плеера. return listener; } @Override public float getAdVideoDuration() { // Вернуть длительность рекламного видео. return myVideoPlayer.getDuration(); } @Override public float getAdVideoPosition() { // Вернуть текущую позицию рекламного видео. // Метод вызывается многократно во время воспроизведения рекламного видео и должен отдавать актуальное значение в секундах. return myVideoPlayer.getPositionInSeconds(); } @Override public @NonNull View getView() { // Визуальное представление плеера, обычно this. return myVideoPlayer.getView(); } @Override public void setAdPlayerListener(@Nullable AdPlayerListener listener) { // Сохранить слушатель плеера. this.listener = listener; } @Override public void playAdVideo(@NonNull Uri uri, int width, int height) { // Начать воспроизведение рекламного видео. // uri - путь к видео // width - ширина видео в пикселях // height - высота видео в пикселях // Начать воспроизведение в другом потоке, чтобы не блокировать SDK. someExecutor.execute(() -> { ... // Когда воспроизведение начнётся успешно, надо вызвать соответствующий метод слушателя. if (listener != null) { listener.onAdVideoStarted(); } }); } @Override public void playAdVideo(@NonNull Uri uri, int width, int height, float position) { // Начать воспроизведение рекламного видео. // uri - путь к видео // width - ширина видео в пикселях // height - высота видео в пикселях // position - начать с этой позиции. Используется после swap // Начать воспроизведение в другом потоке, чтобы не блокировать SDK. someExecutor.execute(() -> { ... // Когда воспроизведение начнётся успешно, надо вызвать соответствующий метод слушателя. if (listener != null) { listener.onAdVideoStarted(); } }); } @Override public void pauseAdVideo() { // Приостановить воспроизведение рекламного видео. // Начать паузу в другом потоке, чтобы не блокировать SDK. someExecutor.execute(() -> { ... // Когда воспроизведение успешно станет на паузу, надо вызвать соответствующий метод слушателя. if (listener != null) { listener.onAdVideoPaused(); } }); } @Override public void resumeAdVideo() { // Продолжить воспроизведение рекламного видео. // Продолжить в другом потоке, чтобы не блокировать SDK. someExecutor.execute(() -> { ... // Когда воспроизведение успешно продолжится, надо вызвать соответствующий метод слушателя. if (listener != null) { listener.onAdVideoResumed(); } }); } @Override public void stopAdVideo() { // Остановить воспроизведение рекламного видео. // Останавливаем в другом потоке, чтобы не блокировать SDK. someExecutor.execute(() -> { ... // Когда воспроизведение будет успешно остановлено, надо вызвать соответствующий метод слушателя. if (listener != null) { listener.onAdVideoStopped(); } }); } @Override public void destroy() { // Закрыть все сетевые подключения, освободить ресурсы. } @Override public void setVolume(float volume) { // Изменить громкость, от 0.0 до 1.0. // Изменяем громкость в другом потоке, чтобы не блокировать SDK. someExecutor.execute(() -> { ... // Когда громкость будет изменена успешно, надо вызвать соответствующий метод слушателя. if (listener != null) { listener.onVolumeChanged(volume); } }); }}
VideoMotion-плеер приложения
Для проигрывания videoMotion-рекламы в плеере приложения, он должен реализовывать интерфейс InstreamAdVideoMotionPlayer и уведомлять установленный ему слушатель VideoMotionPlayerListener. Для использования плеера надо вызвать метод setVideoMotionPlayer(InstreamAdVideoMotionPlayer player) у созданного экземпляра InstreamAd.
private InstreamAd ad;private void initAd(){ // Создаем экземпляр InstreamAd ad = new InstreamAd(YOUR_SLOT_ID, this); // Устанавливаем плеер ad.setPlayer(YOUR_PLAYER); // Устанавливаем videoMotion-плеер ad.setVideoMotionPlayer(YOUR_VIDEO_MOTION_PLAYER)}
Загрузка рекламных объявлений
Для получения уведомлений (таких как успешная загрузка данных или ошибка загрузки, показ рекламного объявления) необходимо создать экземпляр InstreamAdListener и установить его в качестве слушателя событий, после чего можно запустить загрузку данных.
private InstreamAd ad;private void initAd(){ // Создаем экземпляр InstreamAd ad = new InstreamAd(YOUR_SLOT_ID, context); // Обязательно устанавливаем слушатель событий ad.setListener(new InstreamAd.InstreamAdListener() { @Override public void onLoad(InstreamAd instreamAd) { // Данные успешно загружены. // Можно отображать рекламу на экране. } @Override public void onNoAd(IAdLoadingError adLoadingError, InstreamAd instreamAd) { // Данные не получены } @Override public void onError(String reason, InstreamAd ad) { // При проигрывании рекламного видео произошла ошибка } @Override public void onBannerStart(InstreamAd ad, InstreamAd.InstreamAdBanner instreamAdBanner) { // Началось проигрывание рекламного видео } @Override public void onPostViewStart() { // Началось проигрывание пост-вью } @Override public void onVideoMotionBannerStart( InstreamAd ad, InstreamAd.InstreamAdVideoMotionBanner instreamAdVideoMotionBanner) { // Началось проигрывание videoMotion-баннера } @Override public void onVideoMotionBannerComplete( @NonNull InstreamAd ad, @NonNull InstreamAd.InstreamAdVideoMotionBanner banner) { // Видео для motion banner завершилось } @Override public void onBannerPause(InstreamAd ad, InstreamAd.InstreamAdBanner instreamAdBanner) { // Проигрывание рекламного видео приостановлено } @Override public void onBannerResume(InstreamAd ad, InstreamAd.InstreamAdBanner instreamAdBanner) { // Проигрывание рекламного видео возобновлено } @Override public void onPostViewComplete() { // Пост-вью завершилось } @Override public void onBannerComplete(InstreamAd ad, InstreamAd.InstreamAdBanner instreamAdBanner) { // Проигрывание рекламного видео завершено } @Override public void onBannerTimeLeftChange(float timeLeft, float duration, InstreamAd ad) { // Вызывается многократно во время воспроизведения рекламного видео, // используется для обновления таймера до окончания показа рекламного видео } @Override public void onComplete(String section, InstreamAd ad) { // Проигрывание всех рекламных видео в рекламной секции завершено } @Override public void onBannerShouldClose() { // Вызывается в момент выбора соответствующей опции из меню adChoices, например "Пожаловаться". // В этот момент контент нужно скрыть. Необходимо вызвать ad.skip метод. } @Override public void onVideoMotionBannerShouldClose( @NonNull InstreamAd ad, @NonNull InstreamAd.InstreamAdVideoMotionBanner banner) { // Вызывается в момент выбора соответствующей опции из меню adChoices, например "Пожаловаться". // В этот момент контент нужно скрыть. Необходимо вызвать videoMotionPlayerListener.onCloseByUser() метод. } }); // Запускаем загрузку данных ad.load();}
Показ рекламных объявлений
После успешной загрузки данных вы можете запустить показ рекламных секций. Каждая секция может содержать несколько рекламных видео, после начала проигрывания каждого будет вызван метод onBannerStart в установленном слушателе InstreamAdListener, после завершения проигрывания каждого видео будет вызван метод onBannerComplete.
После завершения проигрывания всех рекламных видео в запущенной секции будет вызван метод onComplete - именно его следует использовать для дальнейших действий, он будет вызван даже если в процессе проигрывания произошла ошибка и был вызван метод onError.
Показ preroll и postroll секций
Для показа preroll секции необходимо перед началом показа видео вызвать метод startPreroll у экземпляра InstreamAd, для показа postroll секции необходимо после окончания показа видео вызвать метод startPostroll.
// Перед началом показа основного видеоad.startPreroll(); // После показа основного видеоad.startPostroll();
Показ midroll секции
Для показа midroll секции в какой-то позиции видео, необходимо после создания экземпляра InstreamAd задать массив позиций, на которых планируется показ midroll секции. Позиции можно задавать как в секундах, так и в процентах от длительности видео.
После успешной загрузки данных станет доступен массив позиций, для которых есть рекламные видео. То есть, если были заданы позиции на первой и пятой секунде, а рекламные видео в загруженных данных есть только для первой, то в доступном массиве будет только одна первая позиция. Если позиции не были заданы приложением, они будут установлены сервером.
Если массив позиций после загрузки оказался пустой, значит данных для показа midroll секции нет.
private InstreamAd ad;private float videoDuration;private void initAd(){ // Создаем экземпляр InstreamAd ad = new InstreamAd(YOUR_SLOT_ID, context); // Устанавливаем позиции на первой и пятой секунде видео ad.configureMidpoints(videoDuration, new float[]{ 5.0f, 15.0f }); // или в процентах, на 10% и 50% видео // ad.configureMidpointsPercents(videoDuration, new float[] { 10.0f, 50.0f }); // Устанавливаем слушатель событий ad.setListener(new InstreamAd.InstreamAdListener() { @Override public void onLoad(InstreamAd instreamAd) { // Данные успешно загружены // Массив позиций (в секундах), доступных для показа midroll секции adPositions = ad.getMidPoints(); } @Override public void onNoAd(@NonNull IAdLoadingError adLoadingError, @NonNull InstreamAd ad) { // В этом объекте InstreamAd рекламы не будет } ... // прочие методы интерфейса InstreamAd.InstreamAdListener }); // Запускаем загрузку данных ad.load();}
При достижении основным видео одной из позиций для midroll секции, необходимо вызвать метод startMidroll и передать в него в качестве параметра эту позицию.
// В случае успешной загрузки рекламы следует получить список мидпойнтов// В нашем примере здесь будет две точки - на 5 и на 25 секундfloat[] midPoints = ad.getMidPoints();// Играется основное видео// Через 5 секунд воспроизведения видео начинаем первый мидролл// (этот код следует вызывать асинхронно, здесь показано только для примера)ad.startMidroll(midPoints[0]);
Обработка кликов
Приложение должно самостоятельно отслеживать клики по рекламному видео (как правило, по cta кнопке) и вызывать метод handleClick в экземпляре InstreamAd для обработки клика и перехода на рекламируемый сайт или приложение.
// Это метод приложения, который обрабатывает клики в инстрим-рекламеprivate void onAdClick(){ // ad - это объект InstreamAd ad.handleClick();}
Управление состоянием
У экземпляра InstreamAd доступны следующие методы управления.
// Приостанавливает проигрывание рекламного видео.public void pause()// Возобновляет проигрывание рекламного видео.public void resume()// Останавливает показ рекламной секции.public void stop()// Останавливает показ рекламной секции, если это было сделано пользователем// (нажатие на кнопку "Пропустить" или "Закрыть").public void skip()// Останавливает текущее рекламное видео и переходит к следующему,// если это было сделано пользователем (нажатие на кнопку "Пропустить" или "Закрыть").public void skipBanner()// Устанавливает громкость от 0 до 1.public void setVolume(float volume)// Устанавливает таймаут на загрузку рекламы в секундах.// В случае, если по истечению указанного интервала не удалось получить баннеры,// будет вызван коллбек onNoAd.// Значение по-умолчанию 10 секунд, минимальное значение - 5 секунд.public void setLoadingTimeout(int loadingTimeout)
Доступные свойства рекламного видео
В методы onBannerStart и onBannerComplete слушателя InstreamAdListener передается экземпляр InstreamAdBanner, содержащий информацию о текущем рекламном видео, которая может быть использована приложением.
class InstreamAdBanner{ // Длительность текущего рекламного видео в секундах. public final float duration; // Разрешено ли закрывать рекламное видео во время проигрывания. // Используется для управления показом кнопки "Закрыть" или "Пропустить". public final boolean allowClose; // Время в секундах, через которое рекламное видео может быть закрыто. // Используется для управления показом кнопки "Закрыть" или "Пропустить". public final float allowCloseDelay; // Ширина рекламного видео. public final int videoWidth; // Высота рекламного видео. public final int videoHeight; // Моделька для описания CTA - текст, цвета и так далее. // Например, callToACtionData.getButtonText() можно использовать, // чтобы получить текст для кнопки. public final @NotNull CallToActionData callToActionData; // Флаг аличия адчойсов. public final boolean hasAdChoices; // Рекламный заголовок. public final @NonNull String advertisingLabel; // Иконка адчойса public final @Nullable ImageData adChoicesIcon; ... // Прочие свойства инстрим-баннера}
Меню adChoices
Кнопка adChoices
Разработчик должен сам отрисовать кнопку adChoices так как ему необходимо. Так же необходимо вызывать метод ad.handleAdChoicesClick(context) для обработки нажатия на адчойсы. По умолчанию для InstreamAd кнопка adChoices не отображается.
customAdChoicesView.setOnClickListener(v -> { ad.handleAdChoicesClick(context); });
Кастомизация отрисовки опций adChoices
Для изменения дизайна отрисовки опций adChoices необходимо в конструкторе InstreamAd передать объект, реализующий интерфейс MenuFactory, который, в свою очередь, должен возвращать объект реализующий интерфейс Menu. Если параметр не передать, то SDK по умолчанию будет отображать стандартную реализацию показа опций меню adChoices.
MenuFactory menuFactory = new MenuFactory(){ @Override @NonNull public Menu createMenu() { return new Menu() { @Override public void setListener(@Nullable Listener listener) { // Слушатель, у которого нужно вызвать метод onActionClick(menuAction) // при нажатии на тот элемент UI, который был отрисован с соответствующим // заголовком menuAction } @Override public void addAction(@NonNull MenuAction menuAction) { // Это объект который содержит в себе заголовок и тип опции адчойсов, // а также другие атрибуты отдельных пунктов меню адчойсов. // Эти menuItem нужно нужно использовать при отрисовке пунктов меню. } @Override public void addAboutCompanyInfo(@NonNull String aboutCompanyInfo) { // Пвседопункт меню, в котором отображается информация о рекламируемой компании // Обычно находится в верхней части меню адчойсов } @Override public void present(@NonNull Context context) { // Данный метод вызывается когда необходимо отобразить меню // адчойсов с теми menuAction, которые были ранее переданы в вызовах // метода addAction(MenuAction) } @Override public void dismiss() { // Данный метод вызывается когда необходимо скрыть меню адчойсов } }; }};...ad = new InstreamAd(YOUR_SLOT_ID, menuFactory, this);ad.load();
Реализация класса QrCtaPlayer
Класс QrCtaPlayer предназначен для отображения и скрытия кнопки-действия (CTA, call-to-action) в формате QR в тех случаях, когда использование стандартного Cta не представляется возможным (например, на Android TV).
QrCta является моделью, на основе которой строится UI-представление Cta формата Qr. QrCta описывает все необходимые для отображения данные:
public class QrCta{ public final @NonNull ImageData qrImage; // Картинка Qr-кода public final @Nullable QrIcon qrIcon; // Иконка, расположенная поверх Qr-кода. Имеет свою собственную позицию public final @Nullable ImageData additionalImage; // Доплнительная рекламная картинка public final @NonNull String title; // Текст заголовка public final @NonNull String additionalText; // Дополнительный текст public final @NonNull Position position; // Позиция View Qr-кода на экране public final @ColorScheme int colorScheme; // Цветовая схема. // Возможные значения @ColorScheme: WHITE | BLUE | TURQUOISE | GREEN | YELLOW | RED | PINK | PURPLE}public class QrIcon{ public final @NonNull ImageData iconImage; // Картинка иконки public final @NonNull Position position; // Позиция иконки в рамках Qr-кода}public class Position{ public final @HorizontalPosition int horizontalPosition; // Возможные значения @HorizontalPosition: LEFT, CENTER, RIGHT public final @VerticalPosition int verticalPosition; // Возможные значения @VerticalPosition: TOP, CENTER, BOTTOM}
Библиотечный класс InstreamAd сам вызывает методы класса QrCtaPlayer.
public class CustomQrCtaPlayer extends QrCtaPlayer{ @Override public void show(@NonNull QrCta qrCta) { // В методе show выполняется вся необходимая работа от создания, // до добавления View QR-кода в иерархию вьюшек для отображения на экране QrCtaView qrCtaView = new QrCtaView(context); // Кроме того, приложение может расположить вьюшку QR-кода на экране, руководствуясь QrCta::position. FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); // Необходимо рассчитать Gravity в соответствии с Position, указанной в QrCta params.gravity = calculateGravityByPosition(qrCta.position); qrCtaView.setLayoutParams(params); qrCtaView.setQrCta(qrCta); rootView.addView(qrCtaView); } @Override public void hide() { // Вьюшку QR-кода можно скрыть или удалить rootView.removeAllViews(); } private int calculateGravityByPosition(Position position) { final int verticalGravity; switch (position.verticalPosition) { case Position.VerticalPosition.TOP: verticalGravity = Gravity.TOP; break; case Position.VerticalPosition.CENTER: verticalGravity = Gravity.CENTER_VERTICAL; break; default: verticalGravity = Gravity.BOTTOM; break; } final int horizontalGravity; switch (position.horizontalPosition) { case Position.HorizontalPosition.LEFT: horizontalGravity = Gravity.START; break; case Position.HorizontalPosition.CENTER: horizontalGravity = Gravity.CENTER_HORIZONTAL; break; default: horizontalGravity = Gravity.END; break; } return verticalGravity | horizontalGravity; }}
После реализации класса, необходимо передать ее экземпляру InstreamAd:
instreamAd.setQrCtaPlayer(new CustomQrCtaPlayer());
Кроме того, библиотека предоставляет класс QrCtaView, стандартную реализацию View для отображения QrCta.
QrCtaView необходимо установить через QrCtaView::setQrCta(QrCta qrCta) модель QrCta для отображения.
Помимо этого QrCtaView предоставляет пользователю возможность изменения стилей текста заголовка и дополнительного текста, путем передачи ему стилей текста через публичные методы класса.
QrCtaView qrCtaView = new QrCtaView(context);qrCtaView.setQrCtaTitleTextStyle(R.style.style_title_text);qrCtaView.setQrCtaAdditionalTextStyle(R.style.style_additional_text);
Баннеры Video Motion
Интерфейс InstreamAdVideoMotionPlayer
InstreamAdVideoMotionPlayer – интерфейс, который должно реализовать приложение для проигрывания video motion баннеров.
Методы интерфейса будут вызваны из объекта InstreamAd.
public interface InstreamAdVideoMotionPlayer{ // Проиграть video motion баннер. void playVideoMotionBanner(InstreamAdVideoMotionBanner instreamAdVideoMotionBanner); // VideoMotionPlayerListener - интерфейс, методы которого следует вызывать после // выполнения соответствующих действий при воспроизведении instreamAdVideoMotionBanner void setVideoMotionPlayerListener(VideoMotionPlayerListener videoMotionPlayerListener);}
Интерфейс VideoMotionPlayerListener
Для уведомления InstreamAd приложение должно вызывать методы интерфейса VideoMotionPlayerListener
interface VideoMotionPlayerListener{ // Метод должен быть вызван после успешного показа баннера. void onBannerShow(final @NonNull Context context); // Метод должен быть вызван при завершении показа баннера. void onBannerComplete(final @NonNull Context context); // Метод должен быть вызван при клике на заголовок баннера. void onHeaderClick(final @NonNull Context context); // Метод должен быть вызван после показа карточки с идентификатором itemId. void onItemShow(final @NonNull String id, final @NonNull Context context); // Метод должен быть вызван при клике по карточке с идентификатором itemId. void onItemClick(final @NonNull String id, final @NonNull Context context); // Метод должен быть вызван при возникновении какой-либо ошибки. void onError(final @NonNull String message, final @NonNull Context context); // Метод должен быть вызван при закрытии баннера пользователем. void onCloseByUser(final @NonNull Context context);}
Модель InstreamAdVideoMotionBanner
Модель, содержащая информацию о video motion баннере.
class InstreamAdVideoMotionBanner{ // Модель данных (см. ниже). public final @NonNull VideoMotionData videoMotionData; // Флаг, разрешающий пропускать баннер. public final boolean allowClose; // Время в секундах, через которое баннер может быть пропущен. public final float allowCloseDelay; // Длительность video motion баннера. public final float duration; // Иконка adChoices. public final boolean hasAdChoices; // Флаг, сообщающий что у баннера есть adChoices. public final @Nullable ImageData adChoicesIcon;}
Модель VideoMotionData
class VideoMotionData{ // Заголовок баннера. public final @NonNull Header header; // Массив карточек. public final @NonNull List<VideoMotionItem> videoMotionItemList; // Дисклеймер. public final @Nullable Disclaimer disclaimer;}
Модель Header
class Header{ // УРЛ иконки. public final @NonNull String icon; // Заголовок. public final @NonNull String title; // Текстовая ссылка. public final @NonNull String linkText; // Возрастное ограничение. public final @NonNull String ageRestrictionText; // Дисклеймер "реклама". public final @NonNull String adDisclaimerText;}
Модель InstreamAdVideoMotionItem
class VideoMotionItem{ // Идентификатор карточки. public final @NonNull String id; // Цена новая. public final @Nullable String price; // Цена старая. public final @Nullable String oldPrice; // Валюта. public final @NonNull String currency; // Картинка. public final @NonNull String image; // Описание. public final @NonNull String text; // Текст для кнопки. public final @NonNull String ctaText;}
Модель Disclaimer
class Disclaimer{ // Текстовое описание. public final @NonNull String text;}