Advanced integration (InStream API)

The InStream API is an advanced API for setting up and managing ad loading and playing InStream ads. It lets you support playing any type of ad break and use your own implementation of a player. InStream ads consist of video ads that are played automatically and manually.

Use the InstreamAdBinder API to automatically play Pre-roll, Mid-roll, and Post-roll ad breaks. For triggering ad breaks manually, use the InstreamAdBreak API instead.

Note

You can use the InstreamAdBinder and InstreamAdBreak APIs at the same time under certain conditions:

  1. Use different instances of the ad player.
  2. Don't trigger playback using the InstreamAdBreak API while the main video is paused via the InstreamAdBinder API.
  3. Use InstreamAdBreak from InstreamAd of the InstreamAdBreakType.INROLL or InstreamAdBreakType.PAUSEROLL types. The InstreamAdBinder will automatically render all other ad break types for you.

How it works

A loaded InStream ad object contains a schedule for playing ad breaks. Each ad break is described by an InstreamAdBreak object. An ad break may have one of the following types: Pre / Mid / Post / In / Pause-roll. You can play Pre-/Mid-/Post-Roll ad breaks using the InstreamAdBinder API. You can use the InstreamAdBreak API to manually play ad breaks, including Pause-roll and In-roll video ads.

The VideoPlayer interface handles interactions with the main video content, while the InstreamAdPlayer interface manages ad video playback within the ad break (you can omit this parameter to use the default player).

InstreamAdBinder tracks the progress of playing the main video and shows ad breaks based on the video resource settings in the Boost interface.

InstreamAdBinder does not directly control the rendering of a video ad in PlayerView. Video ads must be played on the app side based on signals from player interfaces transmitted to InstreamAdBinder. InstreamAdBinder signals the start of playing an ad break by calling VideoPlayer.pauseVideo() and the end by calling VideoPlayer.resumeVideo().

When calling VideoPlayer.pauseVideo() on the app side, it's necessary to hide the main video controls, pause the main video, and start playing the video ad. On the ad SDK side, after calling the method, advertising controls are displayed inside the InstreamAdView container and the InstreamAdPlayer.playAd() method is called to start playing the video ad.

When calling VideoPlayer.resumeVideo() on the app side, it's necessary to return the main video controls and resume playing the main video. On the ad SDK side, ad controls inside the InstreamAdView container are removed before calling the method.

InstreamAdBreak API doesn't directly control the rendering of a video ad in PlayerView. Video ads must be played on the app side based on signals from player interfaces transmitted to InstreamAdBreak. In/Pause-Roll signals the start of playing an ad break by calling InstreamAdBreakEventListener.onInstreamAdBreakStarted() and the end by calling InstreamAdBreakEventListener.onInstreamAdBreakCompleted() or InstreamAdBreakEventListener.onInstreamAdBreakError().

When calling InstreamAdBreakEventListener.onInstreamAdBreakStarted() on the app side, it's necessary to hide the main video controls and pause the main video. On the ad SDK side, after calling the method, advertising controls are displayed inside the InstreamAdView container and the InstreamAdPlayer.playAd() method is called to start playing the video ad.

When calling InstreamAdBreakEventListener.onInstreamAdBreakCompleted() or InstreamAdBreakEventListener.onInstreamAdBreakError() on the app side, return the main video controls and resume playing the main video. On the ad SDK side, ad controls are removed from the InstreamAdView container before calling the methods.

Loading ads

  1. Create an instance of the InstreamAdLoader class to get InStream ads.

  2. Create a request using the InstreamAdRequest.Builder class. Pass PAGE_ID from the Boost interface in the request parameters.

  3. Load the ad using the InstreamAdLoader.loadAd method, passing the instreamAdRequest and an InstreamAdLoadListener instance to receive notifications.

Code example:

To test the integration, use the demo 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){
        // ...
        }
    });

To load a specific AdBreak for manual playback, you can load the ad using PAGE_ID and IMP_ID. This data is stored in the ad unit ID, which is formatted as R-V-PAGE_ID-IMP_ID.

  1. Create an instance of the InstreamAdBreakLoader class.

  2. Create a request using the InstreamAdBreakRequest.Builder class, passing the ad feed URL.

  3. Load the ad using the InstreamAdBreakLoader.loadAd method.

Code example:

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){
        // ...
    }
});

Rendering ads

  1. Implement the VideoPlayer interfaces.

    For more information about using and implementing the appropriate methods, see the reference guide sections Package com.yandex.mobile.ads.instream.player.ad and Package com.yandex.mobile.ads.instream.player.content. Additionally, see a test implementation example.

    Tip

    To make implementation easier, we recommend using different instances of players to play video ads and content.

  2. Add InstreamAdView to the app layout. InstreamAdView must contain PlayerView to play video ads in.

    Sample code:

    Restriction

    A container must be at least 300dp x 160dp in size.

    <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. Create an InstreamAdBinder object: pass Context, the loaded InstreamAd object, and the VideoPlayer and InstreamAdPlayer implementations to the builder.

    Set up notifications about the ad playing progress (ready to play the video ad, the video ad played or failed to play), create an instance of InstreamAdListener and set it as an event listener for InstreamAdBinder.

    instreamAdBinder = InstreamAdBinder(
        this,
        instreamAd,
        checkNotNull(contentVideoPlayer),
        checkNotNull(instreamAdPlayer)
    )
    instreamAdBinder.setInstreamAdListener(...)
    
    mInstreamAdBinder = new InstreamAdBinder(context, mInstreamAd, mContentVideoPlayer, mYandexAdPlayer);
    mInstreamAdBinder.setInstreamAdListener(...);
    
  4. To start playing a Pre-roll ad break faster, preload it in advance by calling the InstreamAdBinder.prepareAd() method.

    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. Call the InstreamAdBinder.bind(instreamAdView) method for the created InstreamAdBinder object. Pass InstreamAdView as a parameter. After that, the InStream SDK starts to automatically track the progress of playing the main video and manage the way video ads are played.

    instreamAdBinder.bind(instreamAdView)
    
    mInstreamAdBinder.bind(mInstreamAdView);
    
  6. When playing InStream ads in the list, use the InStreamBinder.unbind() method when the cell with the ad is invalidated in the list. To implement a reused pool of players for scrolling, call InstreamAdbinder.invalidateAdPlayer() when reusing the ad player linked to InstreamAdBinder, and InstreamAdBinder.invalidateVideoPlayer() when reusing the main content player.

  7. When you stop using InStreamAdBinder, reset the state.

    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();
    }
    

Note

You can configure playback of any ad break similar to In-roll video ads. To do this, retrieve the type you need from the list of loaded InstreamAdBreak objects.

  1. Add InstreamAdView to the app layout. InstreamAdView must contain PlayerView to play video ads in.

    Sample code:

    Restriction

    A container must be at least 300dp x 160dp in size.

    <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. Use InstreamAdLoader to load an InstreamAd object using the page ID (PAGE_ID) from the Boost interface. Alternatively, use InstreamAdLoader to load an InstreamAdBreak object using the ad break identifiers (PAGE_ID and IMP_ID).

  3. The InstreamAd object contains a set of different types of ad breaks. To get In-roll ad breaks, filter the instreamAd.instreamAdBreaks collection by the InstreamAdBreakType.INROLL type.

    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. To launch the received In-roll video ad, you need to prepare it. Unprepared In-roll video ads won't start.

    To prepare In-roll video ads, call InstreamAdBreak.prepare(). To track the status of the ad break, set 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. Once the In-roll video ad is prepared, InstreamAdBreakEventListener.onInstreamAdBreakPrepared() is called. The prepared In-roll video ad is ready to play.

    Tip

    Play video ads in the order they're retrieved from the instreamAdBreaks collection. If the received In-roll video ads are played in a different order, this may lower your app's monetization.

  6. To play the prepared In-roll video ad, call InstreamAdBreak.play() and pass InstreamAdView as a parameter.

    fun onInstreamAdBreakPrepared() {
        currentInroll?.play(instreamAdView)
    }
    
    public void onInstreamAdBreakPrepared() {
        if (currentInroll != null) {
            currentInroll.play(instreamAdView);
        }
    }
    
  7. After the ad break starts playing, the InstreamAdBreakEventListener.onInstreamAdBreakStarted() method is called. After calling this method, pause the main video and hide its controls.

    fun onInstreamAdBreakStarted() {
        contentVideoPlayer?.pauseVideo()
    }
    
    public void onInstreamAdBreakStarted() {
        if (contentVideoPlayer != null) {
            contentVideoPlayer.pauseVideo();
        }
    }
    
  8. Once the ad break is played, resume playing the main video. A video ad may play successfully or fail. Both situations need to be handled.

    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. After the current In-roll video ad finishes playing, check the play queue for the next In-roll video ad in the 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. When you stop using an In-roll video ad, reset its state.

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