---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
alternate:
  - https://ads.yandex.com/helpcenter/en/dev/android/instream-advanced.md
  - https://ads.yandex.com/helpcenter/ru/dev/android/instream-advanced.md
  - https://ads.yandex.com/helpcenter/zh/dev/android/instream-advanced.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ads.yandex.com/helpcenter/zh/llms.txt

# 高级集成（视频插播广告 API）



**视频插播广告 API** 是一种高级 API，用于设置和管理广告加载以及播放视频插播广告。它允许您支持播放任何类型的广告插播并使用您自己的播放器实现。视频插播广告由自动和手动播放的视频广告组成。

Pre-roll, Mid-roll 和 Post-roll 广告插播会通过 InStreamAdBinder API 自动播放。要手动播放 In-roll 和 Pause-roll 广告插播，请分别使用 In-roll API 和 Pause-roll API。

{% note info %}

如果满足以下条件，您还可以同时使用 InstreamAdBinder API、In-roll API 和 Pause-roll API：
1. 使用广告播放器的不同实例。
2. 如果主视频通过 InStreamAdBinder API 暂停，请勿启动 Pause-roll 和 In-roll API 来播放广告。

{% endnote %}

## 运作方式

加载的视频插播广告对象包含播放广告插播的时间表。每个广告插播时间均由 InstreamAdBreak 对象描述。广告插播可能具有以下类型之一：  前贴片/中贴片/后贴片/内贴片/暂停时广告。您可以使用 InstreamAdBinder API 播放前/中/后贴片广告插播。要播放内贴片/暂停时广告插播，请分别使用 In-roll API 和 Pause-roll API。

VideoPlayer 接口用于与主视频内容进行交互。要在广告版位内播放广告插播，请使用 InstreamAdPlayer 接口。

{% list tabs %}

- 播放前/中/后贴片视频广告

   InstreamAdBinder 会跟踪主视频的播放进度，并根据 Yandex Advertising Network 界面中的视频资源设置显示广告插播时间点。

   InstreamAdBinder 不直接控制 PlayerView 中视频广告的呈现。视频广告必须根据播放器接口传输到 InstreamAdBinder 的信号在应用端播放。InstreamAdBinder 通过调用 `VideoPlayer.pauseVideo()` 来发出播放广告插播的开始信号，并通过调用 `VideoPlayer.resumeVideo()` 来发出结束信号。

   在应用端调用 `VideoPlayer.pauseVideo()` 时，需要隐藏主视频控件，暂停主视频，然后开始播放视频广告。在广告 SDK 端，调用该方法后，广告控件会显示在 `InstreamAdView` 容器内，并调用 `InstreamAdPlayer.playAd()` 方法开始播放视频广告。

   在应用端调用 `VideoPlayer.resumeVideo()` 时，需要返回主视频控件并继续播放主视频。在广告 SDK 端，在调用该方法之前会移除 `InstreamAdView` 容器内的广告控件。

- 播放内贴片/暂停时视频广告

   内贴片/暂停时广告 API 不直接控制 PlayerView 中视频广告的呈现。视频广告必须根据播放器接口传输到内贴片/暂停时广告的信号在应用端播放。内贴片/暂停时广告通过调用 `InstreamAdBreakEventListener.onInstreamAdBreakStarted()` 来发出播放广告插播的开始信号，并通过调用 `InstreamAdBreakEventListener.onInstreamAdBreakCompleted()` 或 `InstreamAdBreakEventListener.onInstreamAdBreakError()` 来发出结束信号。

   在应用端调用 `InstreamAdBreakEventListener.onInstreamAdBreakStarted()` 时，需要隐藏主视频控件并暂停主视频。在广告 SDK 端，调用该方法后，广告控件会显示在 `InstreamAdView` 容器内，并调用 `InstreamAdPlayer.playAd()` 方法开始播放视频广告。

   在应用端调用 `InstreamAdBreakEventListener.onInstreamAdBreakCompleted()` 或 `InstreamAdBreakEventListener.onInstreamAdBreakError()` 时，返回主视频控件并继续播放主视频。在广告 SDK 端，在调用该方法之前，广告控件会从 `InstreamAdView` 容器中移除。

{% endlist %}

## 加载广告

1. 创建 `InstreamAdLoader` 类的实例以获取视频插播广告。

2. 设置通知（广告加载成功或失败并出现错误）：创建一个 `InstreamAdLoadListener` 实例并将其设置为广告加载器的事件监听器。

3. 使用 `InstreamAdRequestConfiguration.Builder` 类为 `instreamAdRequestConfiguration` 请求创建配置。将来自 Yandex Advertising Network 界面的 `PAGE_ID` 作为请求参数传递。

4. 使用 `InstreamAdLoader.loadInstreamAd` 方法加载广告，并将 `Context` 和 `instreamAdRequestConfiguration` 传递给它。

**代码示例：**

要测试集成，请使用演示 PAGE_ID：`demo-instream-vmap-yandex`。

{% list tabs %}

- Kotlin

   ```kotlin
   val instreamAdLoader = InstreamAdLoader(this)
   instreamAdLoader.setInstreamAdLoadListener(object : InstreamAdLoadListener {
       override fun onInstreamAdLoaded(instreamAd: InstreamAd) {
           // ...
       }

       override fun onInstreamAdFailedToLoad(reason: String) {
           // ...
       }
   })

   val instreamAdRequestConfiguration = InstreamAdRequestConfiguration.Builder(PAGE_ID).build()
   instreamAdLoader.loadInstreamAd(this, instreamAdRequestConfiguration)
   ```

- Java

   ```java
   final InstreamAdLoader instreamAdLoader = new InstreamAdLoader(context);
   instreamAdLoader.setInstreamAdLoadListener(new InstreamAdLoadListener() {
           @override
           public void onInstreamAdLoaded(@NonNull final InstreamAd instreamAd) {
           // ...
           }

           @override
           public void onInstreamAdFailedToLoad(@NonNull final String reason) {
           // ...
           }
       });

   final InstreamAdRequestConfiguration instreamAdRequestConfiguration =
       new InstreamAdRequestConfiguration.Builder(PAGE_ID).build();
   instreamAdLoader.loadInstreamAd(this, instreamAdRequestConfiguration);
   ```
{% endlist %}

## 呈现广告

{% list tabs %}

- 播放前/中/后贴片视频广告

   1. 实施 `InstreamAdPlayer` 和 `VideoPlayer` 接口。

      有关使用和实施适当方法的更多信息，请参阅参考指南部分 `Package com.yandex.mobile.ads.instream.player.ad` 和 `Package com.yandex.mobile.ads.instream.player.content`。此外，请参阅测试实施示例。

      <!-- source: zh/dev/_includes/instream-src.md -->
      {% note tip %}

      为了使实施更容易，我们建议使用不同的播放器实例来播放视频广告和内容。

      {% endnote %}
      <!-- endsource: zh/dev/_includes/instream-src.md -->


   2. 将 InstreamAdView 添加到应用布局。InstreamAdView 必须包含 PlayerView 才能在其中播放视频广告。

      代码示例：

      {% note info "约束" %}

      容器的尺寸必须至少为 300dp x 160dp。

      {% endnote %}

      ```xml
      <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` 对象以及 `VideoPlayer` 和 `InstreamAdPlayer` 实施传递给构建器。

      设置有关广告播放进度的通知（准备播放视频广告、视频广告已播放或播放失败），创建 `InstreamAdListener` 实例并将其设置为 `InstreamAdBinder` 的事件监听器。

      {% list tabs %}

      - Kotlin

         ```kotlin
         instreamAdBinder = InstreamAdBinder(
             this,
             instreamAd,
             checkNotNull(contentVideoPlayer),
             checkNotNull(instreamAdPlayer)
         )
         instreamAdBinder.setInstreamAdListener(...)
         ```

      - Java

         ```java
         mInstreamAdBinder = new InstreamAdBinder(context, mInstreamAd, mContentVideoPlayer, mYandexAdPlayer);
         mInstreamAdBinder.setInstreamAdListener(...);
         ```

      {% endlist %}

   4. 要更快地开始播放 Pre-roll 广告插播，请通过调用 `InstreamAdBinder.prepareAd()` 方法提前预加载广告。

      {% list tabs %}

      - Kotlin

         ```kotlin
         private fun preparePrerollAd(instreamAdBinder: InstreamAdBinder) {
             instreamAdBinder.setInstreamAdListener(object : InstreamAdListener {
                 // ...
                 override fun onInstreamAdPrepared() {
                     addInstreamAdBinderToPreloadedAdQueue(instreamAdBinder)
                 } // ...
             })
             instreamAdBinder.prepareAd()
         }
         ```

      - Java

         ```java
         private void preparePrerollAd(@NonNull final InstreamAdBinder instreamAdBinder) {
             instreamAdBinder.setInstreamAdListener(new InstreamAdListener() {
                 // ...
                 public void onInstreamAdPrepared() {
                     addInstreamAdBinderToPreloadedAdQueue(instreamAdBinder);
                 }
                 // ...
             });
             instreamAdBinder.prepareAd();
         }
         ```

      {% endlist %}

   5. 为创建的 `InstreamAdBinder` 对象调用 `InstreamAdBinder.bind(instreamAdView)` 方法。将 `InstreamAdView` 作为参数传递。之后，视频插播广告 SDK 开始自动跟踪主视频的播放进度并管理视频广告的播放方式。

      {% list tabs %}

      - Kotlin

         ```kotlin
         instreamAdBinder.bind(instreamAdView)
         ```

      - Java

         ```java
         mInstreamAdBinder.bind(mInstreamAdView);
         ```

      {% endlist %}

   6. 在播放列表中的视频插播广告时，当列表中包含广告的单元格失效时，请使用 `InStreamBinder.unbind()` 方法。要实施滚动的播放器重用池，请在重用链接到 `InstreamAdBinder` 的广告播放器时调用 `InstreamAdbinder.invalidateAdPlayer()`，在重用主内容播放器时调用 `InstreamAdBinder.invalidateVideoPlayer()`。

   7. 停止使用 `InStreamAdBinder` 时，请重置状态。

      {% list tabs %}

      - Kotlin

         ```kotlin
         override fun onDestroy() {
             instreamAdBinder.apply {
                 unbind()
                 instreamAdBinder.invalidateVideoPlayer()
                 instreamAdBinder.invalidateAdPlayer()
                 instreamAdBinder.setInstreamAdListener(null)
                 instreamAdBinder.setVideoAdPlaybackListener(null)
             }

             super.onDestroy()
         }
         ```

      - Java

         ```java
         public void onDestroy() {
             instreamAdBinder.unbind();
             instreamAdBinder.invalidateVideoPlayer();
             instreamAdBinder.invalidateAdPlayer();
             instreamAdBinder.setInstreamAdListener(null);
             instreamAdBinder.setVideoAdPlaybackListener(null);

             super.onDestroy();
         }
         ```

      {% endlist %}

- 播放内贴片/暂停时视频广告

   {% note info %}

   设置播放 Pause-roll 广告插播与 In-roll 广告插播类似。为此，请将 { yan-in-roll }} 类/方法替换为 Pause-roll 类/方法。

   {% endnote %}

   1. 实施 InstreamAdPlayer 接口。

      有关这些方法及其实施的更多信息，请参阅 `Package com.yandex.mobile.ads.instream.player.ad` 参考部分。此外，请参阅测试实施示例。

      <!-- source: zh/dev/_includes/instream-src.md -->
      {% note tip %}

      为了使实施更容易，我们建议使用不同的播放器实例来播放视频广告和内容。

      {% endnote %}
      <!-- endsource: zh/dev/_includes/instream-src.md -->


   2. 将 InstreamAdView 添加到应用布局。InstreamAdView 必须包含 PlayerView 才能在其中播放视频广告。

      代码示例：

      {% note info "约束" %}

      容器的尺寸必须至少为 300dp x 160dp。

      {% endnote %}

      ```xml
      <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. 使用 `InstreamAdLoader` 通过来自 Yandex Advertising Network 界面的 `PAGE_ID` 加载 `InstreamAd` 对象。

   4. InstreamAd 对象包含一组不同类型的广告插播。要获取 In-roll 广告插播，请使用 `InrollQueueProvider`。`InrollQueueProvider` 队列允许您按显示顺序接收 In-roll 对象。

      {% list tabs %}

      - Kotlin

         ```kotlin
         fun onInstreamAdLoaded(instreamAd: InstreamAd) {
             val inrollQueueProvider = InrollQueueProvider(context, instreamAd)
             instreamAdBreakQueue = inrollQueueProvider.queue
         }
         ```

      - Java

         ```java
         public void onInstreamAdLoaded(@NonNull final InstreamAd instreamAd) {
             final InrollQueueProvider inrollQueueProvider = new InrollQueueProvider(context, instreamAd);
             mInstreamAdBreakQueue = inrollQueueProvider.getQueue();
         }
         ```

      {% endlist %}

   5. 要启动接收的 In-roll 视频广告，您需要进行相应准备。未准备好的 In-roll 视频广告将不会启动。

      要准备 In-roll 视频广告，请调用接口 `Inroll.prepare(instreamAdPlayer)` 并将创建的 `InstreamAdPlayer` 实施的实例传递给它。要跟踪广告插播的状态，请设置 `InstreamAdBreakEventListener`。

      {% list tabs %}

      - Kotlin

         ```kotlin
         fun prepare(instreamAdPlayer: SampleInstreamAdPlayer) {
             currentInroll = instreamAdBreakQueue.poll()?.apply {
                 setListener(InrollListener())
                 instreamAdPlayer.let(::prepare)
             }
         }
         ```

      - Java

         ```java
         public void prepare(instreamAdPlayer) {
             currentInroll = mInstreamAdBreakQueue.poll();
             currentInroll.setListener(new InrollListener());
             currentInroll.prepare(instreamAdPlayer);
         }
         ```

      {% endlist %}

   6. 准备好 In-roll 视频广告后，将调用 `InstreamAdBreakEventListener.onInstreamAdBreakPrepared()`。准备好播放的 In-roll 视频广告已经就绪。

      {% note tip %}

      按照从 InstreamAdBreakQueue 收到视频广告的顺序播放广告。如果接收的 In-roll 视频广告以不同的顺序播放，则可能会降低应用的变现能力。

      {% endnote %}

   7. 要播放准备好的 In-roll 视频广告，请调用 `Inroll.play()` 并将 `InstreamAdView` 作为参数传递。

      {% list tabs %}

      - Kotlin

         ```kotlin
         fun onInstreamAdBreakPrepared() {
             currentInroll?.play(instreamAdView)
         }
         ```

      - Java

         ```java
         public void onInstreamAdBreakPrepared() {
             if (currentInroll != null) {
                 currentInroll.play(instreamAdView);
             }
         }
         ```

      {% endlist %}

   8. 广告插播开始播放后，会调用 `InstreamAdBreakEventListener.onInstreamAdBreakStarted()` 方法。调用此方法后，暂停主视频并隐藏其控件。

      {% list tabs %}

      - Kotlin

         ```kotlin
         fun onInstreamAdBreakStarted() {
             contentVideoPlayer?.pauseVideo()
         }
         ```

      - Java

         ```java
         public void onInstreamAdBreakStarted() {
             if (contentVideoPlayer != null) {
                 contentVideoPlayer.pauseVideo();
             }
         }
         ```

      {% endlist %}

   9. 播放广告插播后，继续播放主视频。视频广告可能会成功播放，也可能会失败。这两种情况都需要处理。

      {% list tabs %}

      - Kotlin

         ```kotlin
         override fun onInstreamAdBreakCompleted() {
             handleAdBreakCompleted()
         }

         override fun onInstreamAdBreakError(reason: String) {
             handleAdBreakCompleted()
         }

         private fun handleAdBreakCompleted() {
             currentInroll = null
             contentVideoPlayer?.resumeVideo()
         }
         ```

      - Java

         ```java
         @Override
         public void onInstreamAdBreakCompleted() {
             handleAdBreakCompleted();
         }

         @Override
         public void onInstreamAdBreakError(@NonNull final String reason) {
             handleAdBreakCompleted();
         }

         private void handleAdBreakCompleted() {
             currentInroll = null;
             if (contentVideoPlayer != null) {
                 contentVideoPlayer.resumeVideo();
             }
         }
         ```

      {% endlist %}

   10. 当前 In-roll 视频广告播放完毕后，在 `InstreamAdBreakQueue` 中针对下一个 In-roll 视频广告检查播放队列。

       {% list tabs %}

       - Kotlin

         ```kotlin
         fun prepareNextAd() {
             currentInroll = mInstreamAdBreakQueue.poll()
             currentInroll?.prepareInroll(currentInroll)
         }
         ```

       - Java

         ```java
         public void prepareNextAd() {
             currentInroll = mInstreamAdBreakQueue.poll();
             if (currentInroll != null) {
                 prepareInroll(currentInroll);
             }
         }
         ```

       {% endlist %}

   11. 当您停止使用 In-roll 视频广告时，请重置其状态。

       {% list tabs %}

       - Kotlin

         ```kotlin
         override fun onDestroy() {
             currentInroll?.apply {
                 invalidate()
                 setListener(null)
             }
             super.onDestroy()
         }
         ```

       - Java

         ```java
         public void onDestroy() {
             if (currentInroll != null) {
                 currentInroll.invalidate();
                 currentInroll.setListener(null);
             }
             super.onDestroy();
         }
         ```

       {% endlist %}

{% endlist %}

