Расширенная интеграция (InStream API)

InStream API — расширенный API для настройки, управления загрузкой и воспроизведением InStream-рекламы. Позволяет поддержать проигрывание всех типов рекламных вставок, а также использовать свою реализацию плеера. InStream-реклама состоит из рекламных вставок, которые проигрываются автоматически и вручную.

Для автоматического проигрывания вставок с типом Pre-roll, Mid-roll, Post-roll используется InstreamAdBinder API. Для ручного запуска рекламных вставок InstreamAdBreak API соответственно.

Примечание

Доступно одновременное использование InstreamAdBinder API, InstreamAdBreak API при соблюдении определенных условий:

  1. Используйте разные инстансы рекламного плеера.
  2. Не запускайте InstreamAdBreak API для воспроизведения, если через InStreamAdBinder API было приостановлено основное видео.
  3. InstreamAdBreak из InstreamAd используйте типа InstreamAdBreakType.INROLL или InstreamAdBreakType.PAUSEROLL, остальные типы рекламных вставок InstreamAdBinder отрисует самостоятельно

Принципы работы

Загруженный объект InStream-рекламы содержит в себе расписание показа рекламных вставок. Каждая рекламная вставка описывается объектом InstreamAdBreak. Рекламная вставка может иметь один из следующих типов: Pre / Mid / Post / In / Pause-roll. Показать Pre / Mid / Post-Roll вставки можно через InstreamAdBinder API. Показать вставки вручную в том числе Pause-roll и In-roll можно через InstreamAdBreak API соответственно.

Для взаимодействия с основным видеоконтентом используется интерфейс VideoPlayer, а для воспроизведения рекламного видео внутри рекламной вставки — интерфейс InstreamAdPlayer (можно не передавать для использования default player).

InstreamAdBinder отслеживает ход воспроизведения основного видео и показывает рекламные вставки на основе настроек видеоресурса в интерфейсе Рекламной сети Яндекса.

InstreamAdBinder не управляет непосредственно отрисовкой рекламного видео в PlayerView. Воспроизводить рекламное видео необходимо со стороны приложения основываясь на сигналах от интерфейсов плееров, переданных в InstreamAdBinder. InstreamAdBinder сообщает о начале проигрывания рекламной вставки через вызов VideoPlayer.pauseVideo() и об окончании проигрывания рекламной вставки через вызов VideoPlayer.resumeVideo().

В момент вызова VideoPlayer.pauseVideo() со стороны приложения необходимо скрыть контролы управления основным видео, приостановить основное видео и начать воспроизведение рекламного видео. Со стороны рекламного SDK после вызова метода будут показаны рекламные контролы внутри контейнера InstreamAdView и будет вызван метод InstreamAdPlayer.playAd() для старта воспроизведения рекламного видео.

В момент вызова VideoPlayer.resumeVideo() со стороны приложения необходимо вернуть контролы управления основным видео и продолжить воспроизведение основного видео. Со стороны рекламного SDK до вызова метода будут убраны рекламные контролы внутри контейнера InstreamAdView.

InstreamAdBreak API не управляет непосредственно отрисовкой рекламного видео в PlayerView. Воспроизводить рекламное видео необходимо со стороны приложения основываясь на сигналах от интерфейсов плееров, переданных в InstreamAdBreak. InstreamAdBreak сообщает о начале проигрывания рекламной вставки через вызов InstreamAdBreakEventListener.onInstreamAdBreakStarted() и об окончании проигрывания рекламной вставки через вызов InstreamAdBreakEventListener.onInstreamAdBreakCompleted() или InstreamAdBreakEventListener.onInstreamAdBreakError().

В момент вызова InstreamAdBreakEventListener.onInstreamAdBreakStarted() со стороны приложения необходимо скрыть контролы управления основным видео, приостановить основное видео. Со стороны рекламного SDK после вызова метода будут показаны рекламные контролы внутри контейнера InstreamAdView и будет вызван метод InstreamAdPlayer.playAd() для старта воспроизведения рекламного видео.

В момент вызова InstreamAdBreakEventListener.onInstreamAdBreakCompleted() или InstreamAdBreakEventListener.onInstreamAdBreakError() со стороны приложения необходимо вернуть контролы управления основным видео и продолжить воспроизведение основного видео. Со стороны рекламного SDK до вызова методов будут убраны рекламные контролы из контейнера InstreamAdView.

Загрузка рекламных объявлений

  1. Создайте экземпляр класса InstreamAdLoader для получения InStream-рекламы.

  2. Создайте запрос с помощью класса InstreamAdRequest.Builder. В качестве параметров запроса передайте идентификатор страницы (PAGE_ID) из интерфейса Рекламной сети Яндекса.

  3. Загрузите рекламу с помощью метода InstreamAdLoader.loadAd, передайте в него instreamAdRequest и экземпляр InstreamAdLoadListener для получения уведомлений.

Пример кода:

Для тестирования корректности интеграции используйте демонстрационный PAGE_ID: demo-instream-vmap-yandex.

val instreamAdLoader = InstreamAdLoader(this)
val instreamAdRequest = InstreamAdRequest.Builder(PAGE_ID).build()
instreamAdLoader.loadAd(instreamAdRequest, object : InstreamAdLoadListener {
    override fun onInstreamAdLoaded(instreamAd: InstreamAd) {
        // ...
    }

    override fun onInstreamAdFailedToLoad(error: InstreamAdRequestError) {
        // ...
    }
})
final InstreamAdLoader instreamAdLoader = new InstreamAdLoader(context);
final InstreamAdRequest instreamAdRequest =
    new InstreamAdRequest.Builder(PAGE_ID).build();
instreamAdLoader.loadAd(instreamAdRequest, new InstreamAdLoadListener() {
        @Override
        public void onInstreamAdLoaded(@NonNull final InstreamAd instreamAd) {
        // ...
        }

        @Override
        public void onInstreamAdFailedToLoad(@NonNull final InstreamAdRequestError error) {
        // ...
        }
    });

Если вы хотите загрузить конкретный AdBreak для ручного воспроизведения, вы можете загрузить рекламу используя PAGE_ID и IMP_ID. эти данные хранятся в блоке формата R-V-PAGE_ID-IMP_ID

  1. Создайте экземпляр класса InstreamAdBreakLoader.

  2. Создайте запрос с помощью класса InstreamAdBreakRequest.Builder, передав URL рекламного фида.

  3. Загрузите рекламу с помощью метода InstreamAdBreakLoader.loadAd.

Пример кода:

val instreamAdBreakLoader = InstreamAdBreakLoader(this)
val instreamAdBreakRequest = InstreamAdBreakRequest.Builder(PAGE_ID, IMP_ID).build()
instreamAdBreakLoader.loadAd(instreamAdBreakRequest, object : InstreamAdBreakLoadListener {
    override fun onAdLoaded(instreamAdBreak: InstreamAdBreak) {
        // ...
    }

    override fun onAdFailedToLoad(error: InstreamAdBreakRequestError) {
        // ...
    }
})
final InstreamAdBreakLoader instreamAdBreakLoader = new InstreamAdBreakLoader(context);
final InstreamAdBreakRequest instreamAdBreakRequest =
    new InstreamAdBreakRequest.Builder(PAGE_ID, IMP_ID).build();
instreamAdBreakLoader.loadAd(instreamAdBreakRequest, new InstreamAdBreakLoadListener() {
    @Override
    public void onAdLoaded(@NonNull final InstreamAdBreak instreamAdBreak) {
        // ...
    }

    @Override
    public void onAdFailedToLoad(@NonNull final InstreamAdBreakRequestError error) {
        // ...
    }
});

Показ рекламных объявлений

  1. Реализуйте интерфейсы VideoPlayer.

    В разделах справочника Package com.yandex.mobile.ads.instream.player.ad и Package com.yandex.mobile.ads.instream.player.content приведена подробная информация по работе методов и их реализации. Дополнительно рекомендуется ориентироваться на тестовый пример реализации.

    Совет

    Для упрощения реализации, рекомендуется использовать разные инстансы плееров для воспроизведения рекламы и контентного видео.

  2. Добавьте в layout приложения InstreamAdView. InstreamAdView должна содержать в себе PlayerView, в которой будут проигрываться рекламные ролики.

    Пример кода:

    Ограничение

    Размер контейнера должен быть не меньше 300dp x 160dp.

    <com.yandex.mobile.ads.instream.player.ad.InstreamAdView
        android:id="@+id/instream_ad_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
            <PlayerView
                android:id="@+id/player_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
    
    </com.yandex.mobile.ads.instream.player.ad.InstreamAdView>
    
  3. Создайте объект InstreamAdBinder: передайте в конструктор Context, объект загруженной рекламы InstreamAd и реализации плееров InstreamAdPlayer, VideoPlayer.

    Настройте получение уведомлений о ходе воспроизведения рекламы (готовность к проигрыванию видеорекламы, завершение воспроизведения или ошибка в процессе воспроизведения): создайте экземпляр InstreamAdListener и установите его в качестве слушателя событий объекта InstreamAdBinder.

    instreamAdBinder = InstreamAdBinder(
        this,
        instreamAd,
        checkNotNull(contentVideoPlayer)
    )
    instreamAdBinder.setInstreamAdListener(...)
    
    mInstreamAdBinder = new InstreamAdBinder(context, mInstreamAd, mContentVideoPlayer);
    mInstreamAdBinder.setInstreamAdListener(...);
    
  4. Для ускорения старта рекламной вставки с типом Pre-roll, заранее предзагрузите ее через вызов метода InstreamAdBinder.prepareAd().

    private fun preparePrerollAd(instreamAdBinder: InstreamAdBinder) {
        instreamAdBinder.setInstreamAdListener(object : InstreamAdListener {
            // ...
            override fun onInstreamAdPrepared() {
                addInstreamAdBinderToPreloadedAdQueue(instreamAdBinder)
            } // ...
        })
        instreamAdBinder.prepareAd()
    }
    
    private void preparePrerollAd(@NonNull final InstreamAdBinder instreamAdBinder) {
        instreamAdBinder.setInstreamAdListener(new InstreamAdListener() {
            // ...
            public void onInstreamAdPrepared() {
                addInstreamAdBinderToPreloadedAdQueue(instreamAdBinder);
            }
            // ...
        });
        instreamAdBinder.prepareAd();
    }
    
  5. Вызовите метод InstreamAdBinder.bind(instreamAdView) у созданного объекта InstreamAdBinder. В качестве параметра передайте InstreamAdView. После этого InStream SDK начнет автоматически отслеживать прогресс воспроизведения основного видео и возьмет на себя управление проигрыванием рекламных роликов.

    instreamAdBinder.bind(instreamAdView)
    
    mInstreamAdBinder.bind(mInstreamAdView);
    
  6. При реализации проигрывания InStream-рекламы в списке, необходимо использовать метод InStreamBinder.unbind() при инвалидации ячейки с рекламой в списке. При реализации переиспользуемого пула плееров для скролла, необходимо вызывать InstreamAdbinder.invalidateAdPlayer() при переиспользовании плеера рекламы привязанного к InstreamAdBinder, а при переиспользовании плеера основного контента InstreamAdBinder.invalidateVideoPlayer().

  7. При остановке использования InStreamAdBinder необходимо очищать состояние.

    override fun onDestroy() {
        instreamAdBinder.apply {
            unbind()
            instreamAdBinder.invalidateVideoPlayer()
            instreamAdBinder.invalidateAdPlayer()
            instreamAdBinder.setInstreamAdListener(null)
            instreamAdBinder.setVideoAdPlaybackListener(null)
        }
    
        super.onDestroy()
    }
    
    public void onDestroy() {
        instreamAdBinder.unbind();
        instreamAdBinder.invalidateVideoPlayer();
        instreamAdBinder.invalidateAdPlayer();
        instreamAdBinder.setInstreamAdListener(null);
        instreamAdBinder.setVideoAdPlaybackListener(null);
    
        super.onDestroy();
    }
    

Примечание

Показ любой рекламной вставки настраивается по аналогии с In-roll. Для этого замените получилите из списка загрженных InstreamAdBreak нужный вам тип

  1. Добавьте в layout приложения InstreamAdView. InstreamAdView должна содержать в себе PlayerView, в которой будут проигрываться рекламные ролики.

    Пример кода:

    Ограничение

    Размер контейнера должен быть не меньше 300dp x 160dp.

    <com.yandex.mobile.ads.instream.player.ad.InstreamAdView
        android:id="@+id/instream_ad_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
            <PlayerView
                android:id="@+id/player_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
    
    </com.yandex.mobile.ads.instream.player.ad.InstreamAdView>
    
  2. Загрузите через InstreamAdLoader объект InstreamAd с помощью идентификатора страницы (PAGE_ID) из интерфейса Рекламной сети Яндекса или объект InstreamAdBreak через InstreamAdLoader с помощью идентификаторов рекламной вставки (PAGE_ID и IMP_ID).

  3. InstreamAd содержит в себе набор рекламных вставок разных типов. Чтобы получить рекламные вставки In-roll, отфильтруйте коллекцию instreamAd.instreamAdBreaks по типу InstreamAdBreakType.INROLL.

    fun onInstreamAdLoaded(instreamAd: InstreamAd) {
        instreamAdBreaks = instreamAd.instreamAdBreaks.filter {
            it.adBreakData.type == InstreamAdBreakType.INROLL
        }
    }
    
    public void onInstreamAdLoaded(@NonNull final InstreamAd instreamAd) {
        mInstreamAdBreaks = new ArrayList<>();
        for (InstreamAdBreak adBreak : instreamAd.getInstreamAdBreaks()) {
            if (adBreak.getAdBreakData().getType() == InstreamAdBreakType.INROLL) {
                mInstreamAdBreaks.add(adBreak);
            }
        }
    }
    
  4. Для запуска полученного In-roll, необходимо его подготовить. Без подготовки In-roll не запустится.

    Чтобы подготовить In-roll, вызовите InstreamAdBreak.prepare(). Для отслеживания состояния рекламной вставки установите слушатель InstreamAdBreakEventListener.

    fun prepare() {
        currentInroll = instreamAdBreaks.getOrNull(currentIndex++)?.apply {
            setListener(InrollListener())
            prepare()
        }
    }
    
    public void prepare() {
        if (mCurrentIndex < mInstreamAdBreaks.size()) {
            currentInroll = mInstreamAdBreaks.get(mCurrentIndex++);
            currentInroll.setListener(new InrollListener());
            currentInroll.prepare();
        }
    }
    
  5. По окончанию подготовки In-roll будет вызван InstreamAdBreakEventListener.onInstreamAdBreakPrepared(). Подготовленный In-roll готов к показу.

    Совет

    Показывайте объявления в порядке их получения из коллекции instreamAdBreaks. Показ полученных In-roll в другом порядке может снизить монетизацию вашего приложения.

  6. Чтобы показать подготовленный In-roll, вызовите InstreamAdBreak.play() и передайте в качестве параметра InstreamAdView.

    fun onInstreamAdBreakPrepared() {
        currentInroll?.play(instreamAdView)
    }
    
    public void onInstreamAdBreakPrepared() {
        if (currentInroll != null) {
            currentInroll.play(instreamAdView);
        }
    }
    
  7. После начала проигрывания рекламной вставки, будет вызван метод InstreamAdBreakEventListener.onInstreamAdBreakStarted(). По вызову этого метода необходимо поставить на паузу проигрывание основного видео и скрыть контролы управления основного видео.

    fun onInstreamAdBreakStarted() {
        contentVideoPlayer?.pauseVideo()
    }
    
    public void onInstreamAdBreakStarted() {
        if (contentVideoPlayer != null) {
            contentVideoPlayer.pauseVideo();
        }
    }
    
  8. После проигрывания рекламной вставки необходимо продолжить воспроизведение основного видео. Проигрывание рекламной вставки может завершиться успешно или с ошибкой, эти две ситуации необходимо обрабатывать.

    override fun onInstreamAdBreakCompleted() {
        handleAdBreakCompleted()
    }
    
    override fun onInstreamAdBreakError(reason: String) {
        handleAdBreakCompleted()
    }
    
    private fun handleAdBreakCompleted() {
        currentInroll = null
        contentVideoPlayer?.resumeVideo()
    }
    
    @Override
    public void onInstreamAdBreakCompleted() {
        handleAdBreakCompleted();
    }
    
    @Override
    public void onInstreamAdBreakError(@NonNull final String reason) {
        handleAdBreakCompleted();
    }
    
    private void handleAdBreakCompleted() {
        currentInroll = null;
        if (contentVideoPlayer != null) {
            contentVideoPlayer.resumeVideo();
        }
    }
    
  9. После завершения проигрывания текущего InRoll проверьте очередь воспроизведения на наличие следующего In-roll в InstreamAdBreakQueue.

    fun prepareNextAd() {
        currentInroll = instreamAdBreaks.getOrNull(currentIndex++)
        currentInroll?.let { prepareInroll(it) }
    }
    
    public void prepareNextAd() {
        if (mCurrentIndex < mInstreamAdBreaks.size()) {
            currentInroll = mInstreamAdBreaks.get(mCurrentIndex++);
            prepareInroll(currentInroll);
        }
    }
    
  10. При остановке использования In-roll необходимо очищать его состояние.

    override fun onDestroy() {
        currentInroll?.apply {
            invalidate()
            setListener(null)
        }
        super.onDestroy()
    }
    
    public void onDestroy() {
        if (currentInroll != null) {
            currentInroll.invalidate();
            currentInroll.setListener(null);
        }
        super.onDestroy();
    }