Basic integration (ExoPlayer AdsLoader API)

YandexAdsLoader is a simplified API for integrating InStream ads through Media3 and ExoPlayer. YandexAdsLoader supports the playback of ad insertions of the Pre-roll, Mid-roll, and Post-roll types.

This type of integration is suitable for apps that do not require the advanced InStream API functionality.

Integration using Gradle

Add the following dependencies at the app level of the build.gradle file:

dependencies {
          ...
          implementation 'com.yandex.android:mobileads:7.9.0'
          implementation 'androidx.media3:media3-exoplayer:1.4.1'
          implementation 'androidx.media3:media3-ui:1.4.1'
}
dependencies {
          ...
          implementation 'com.yandex.android:mobileads:7.9.0'
          implementation 'com.google.android.exoplayer:exoplayer-core:2.18.1'
}

Ad rendering

  1. Add PlayerView to your app's layout:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <androidx.media3.ui.PlayerView
            android:id="@+id/player_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />
    
    </FrameLayout>
    
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <com.google.android.exoplayer2.ui.PlayerView
            android:id="@+id/player_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />
    
    </FrameLayout>
    
  2. Create an instreamAdRequestConfiguration request configuration using the InstreamAdRequestConfiguration.Builder class. In the request parameters, pass the page ID (PAGE_ID) from the Yandex Advertising Network Partner interface.

    val configuration = InstreamAdRequestConfiguration
                .Builder(PAGE_ID)
                .build()
    
    InstreamAdRequestConfiguration configuration = new InstreamAdRequestConfiguration
                .Builder(PAGE_ID)
                .build();
    
  3. Create a YandexAdsLoader instance using the onCreate() method of the Activity cycle to render and load InStream ads.

    Note

    To use YandexAdsLoader with Media3, import it from the com.yandex.mobile.ads.instream.media3 package. To use it with ExoPlayer2, import it from the com.yandex.mobile.ads.instream.exoplayer package.

    yandexAdsLoader = YandexAdsLoader(context, configuration)
    
    yandexAdsLoader = new YandexAdsLoader(context, configuration);
    
  4. Add a function for creating ExoPlayer. Inside the function, create a DefaultMediaSourceFactory instance and add to it your YandexAdsLoader and PlayerView instances.

    private fun createPlayer(): Player {
        val mediaSourceFactory = DefaultMediaSourceFactory(context)
            .setLocalAdInsertionComponents({ yandexAdsLoader }, playerView)
    
        val player = ExoPlayer.Builder(context)
            .setMediaSourceFactory(mediaSourceFactory)
            .build()
    
        return player
    }
    
    private YandexAdsLoader yandexAdsLoader;
    
    ...
    
    private class YandexAdsLoaderProvider implements AdsLoader.Provider {
        @Nullable
        @Override
        public AdsLoader getAdsLoader(@NonNull MediaItem.AdsConfiguration adsConfiguration) {
            return yandexAdsLoader;
        }
    }
    
    private Player createPlayer() {
        AdsLoader.Provider yandexAdsLoaderProvider = new YandexAdsLoaderProvider();
        DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(context)
                .setLocalAdInsertionComponents(yandexAdsLoaderProvider, playerView);
    
        Player player = new ExoPlayer.Builder(context)
                .setMediaSourceFactory(mediaSourceFactory)
                .build();
    
        return player;
    }
    
  5. Add a function for creating MediaItem.

    private fun getMediaItem(): MediaItem {
        val contentVideoUrl = CONTENT_URL
        val adTagUri = Uri.parse(YandexAdsLoader.AD_TAG_URI)
        val mediaItem = MediaItem.Builder()
            .setUri(contentVideoUrl)
            .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).build())
            .build()
        return mediaItem
    }
    
    private MediaItem getMediaItem() {
        String contentVideoUrl = CONTENT_URL;
        Uri adTagUri = Uri.parse(YandexAdsLoader.AD_TAG_URI);
        MediaItem mediaItem = new MediaItem.Builder()
                .setUri(contentVideoUrl)
                .setAdsConfiguration(new MediaItem.AdsConfiguration.Builder(adTagUri).build())
                .build();
        return mediaItem;
    }
    
  6. Add a function for initializing ExoPlayer and state recovery.

    private var rememberedPlayerPosition = 0L
    private var rememberedPlayWhenReady = false
    private var player: Player? = null
    
    ...
    
    private fun initPlayer() {
        val mediaItem = getMediaItem()
        player = createPlayer().also {
            playerView.player = it
            yandexAdsLoader.setPlayer(it)
            it.setMediaItem(mediaItem)
            it.playWhenReady = rememberedPlayWhenReady
            it.seekTo(rememberedPlayerPosition)
            it.prepare()
        }
    }
    
    private Long rememberedPlayerPosition = 0L;
    private Boolean rememberedPlayWhenReady = false;
    private Player player = null;
    
    ...
    
    private void initPlayer() {
        MediaItem mediaItem = getMediaItem();
        Player player = createPlayer();
        playerView.setPlayer(player);
        yandexAdsLoader.setPlayer(player);
        player.setMediaItem(mediaItem);
        player.setPlayWhenReady(rememberedPlayWhenReady);
        player.seekTo(rememberedPlayerPosition);
        player.prepare();
        this.player = player;
    }
    
  7. Add a function for calling the release() method and saving the ExoPlayer state.

    private var rememberedPlayerPosition = 0L
    private var rememberedPlayWhenReady = false
    private var player: Player? = null
    
    ...
    
    private fun releasePlayer() {
        yandexAdsLoader.setPlayer(null)
        playerView.player = null
        player?.also {
            rememberedPlayerPosition = it.contentPosition
            rememberedPlayWhenReady = it.playWhenReady
            it.release()
        }
        player = null
    }
    
    private Long rememberedPlayerPosition = 0L;
    private Boolean rememberedPlayWhenReady = false;
    private Player player = null;
    
    ...
    
    private void releasePlayer() {
        yandexAdsLoader.setPlayer(null);
        playerView.setPlayer(null);
        Player player = this.player;
        if (player != null) {
            rememberedPlayerPosition = player.getContentPosition();
            rememberedPlayWhenReady = player.getPlayWhenReady();
           player.release();
        }
        this.player = null;
    }
    
  8. Rewrite the onStart(), onResume(), onPause(), and onStop() methods using the functions you created. For the API version 23 and lower, call the created functions in the onPause() and onResume() methods. In newer API versions, call them from the onStop() and onStart() methods.

    override fun onStart() {
        super.onStart()
        if (Build.VERSION.SDK_INT > 23) {
            initPlayer()
            playerView.onResume()
        }
    }
    
    override fun onStop() {
        super.onStop()
        if (Build.VERSION.SDK_INT > 23) {
            playerView.onPause()
            releasePlayer()
        }
    }
    
    override fun onResume() {
        super.onResume()
        if (Build.VERSION.SDK_INT <= 23) {
            initPlayer()
            playerView.onResume()
        }
    }
    
    override fun onPause() {
        super.onPause()
        if (Build.VERSION.SDK_INT <= 23) {
            playerView.onPause()
            releasePlayer()
        }
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        if (Build.VERSION.SDK_INT > 23) {
            initPlayer();
            playerView.onResume();
        }
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        if (Build.VERSION.SDK_INT > 23) {
            playerView.onPause();
            releasePlayer();
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        if (Build.VERSION.SDK_INT <= 23) {
            initPlayer();
            playerView.onResume();
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        if (Build.VERSION.SDK_INT <= 23) {
            playerView.onPause();
            releasePlayer();
        }
    }
    
  9. Call the release() method on YandexAdsLoader when you no longer need it.

    override fun onDestroy() {
        releasePlayer()
        yandexAdsLoader.release()
        super.onDestroy()
    }
    
    @Override
    protected void onDestroy() {
        releasePlayer();
        yandexAdsLoader.release();
        super.onDestroy();
    }