ExoPlayer 是一款适用于 Android 的应用级媒体播放器。本指南介绍了如何使用封装了 IMA DAI SDK 的 ExoPlayer IMA 扩展程序请求和播放包含广告和内容的媒体流。
以下是该扩展程序的一些优势:
- 简化了将 IMA 与功能集成所需的代码。
- 缩短更新到新版 IMA 所需的开发时间。
ExoPlayer IMA 扩展支持 HLS 和 DASH 流式传输协议。这里有 摘要:
ExoPlayer-IMA 扩展程序数据流支持 | ||
---|---|---|
直播 | VOD 视频流 | |
HLS | ||
DASH |
ExoPlayer-IMA 版本 1.1.0 及更高版本支持 DASH 直播。
本指南基于 ExoPlayer
指南,以及
如何创建完整应用并集成扩展程序。请参阅
ExoPlayerExample
起
GitHub 获取示例,
一个完整的示例应用。
前提条件
- Android Studio
- AndroidX Media3 ExoPlayer 版本 1.0.0 或更高版本(适用于 DAI) 联系。
创建新的 Android Studio 项目
如需创建 Android Studio 项目,请完成以下步骤:
- 启动 Android Studio。
- 选择 Start a new Android Studio project。
- 在 Choose your project 页面中,选择 No Activity 模板。
- 点击下一步。
在 Configure your project 页面中,为项目命名,然后选择 Java 作为语言。
点击完成。
将 ExoPlayer IMA 扩展程序添加到您的项目中
将扩展程序的导入添加到应用级 build.gradle 文件的 dependencies
部分。
配置您的应用并启用 multidex。这是必要的,
设置为相应扩展程序的大小,对设置了 minSdkVersion
的应用而言是必需的
Android 4.4W(API 级别)
20) 或更低。
示例如下:
app/build.gradle
android { ... defaultConfig { applicationId "com.google.ads.interactivemedia.v3.samples.videoplayerapp" minSdkVersion 21 targetSdkVersion 34 multiDexEnabled true versionCode 1 versionName "1.0" } ... } dependencies { implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.media3:media3-ui:1.1.1' implementation 'androidx.media3:media3-exoplayer:1.1.1' implementation 'androidx.media3:media3-exoplayer-hls:1.1.1' implementation 'androidx.media3:media3-exoplayer-dash:1.1.1' // Adding the ExoPlayer IMA extension for ads will also include the IMA // SDK as a dependency. implementation 'androidx.media3:media3-exoplayer-ima:1.1.1' }
添加 IMA DAI SDK 请求广告所需的用户权限:
app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.project name"> <!-- Required permissions for the IMA DAI SDK --> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> ... </manifest>
添加 intent 声明
如果您的应用以 Android 11(API 级别 30)或更高版本为目标平台,则 版本的 IMA DAI SDK 都要求明确声明 intent 才能打开网页 链接。将以下代码段添加到应用的清单文件中,以启用广告点击(用户点击了解详情按钮)。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.project name"> ... </application> <queries> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="https" /> </intent> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="http" /> </intent> </queries> </manifest>
设置 ExoPlayer 的界面
创建要供 ExoPlayer 使用的 PlayerView
对象。
将 androidx.constraintlayout.widget.ConstraintLayout
更改为
LinearLayout
,建议对 ExoPlayer IMA 扩展程序使用该方法。
示例如下:
app/src/main/res/layout/activity_my.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:background="@android:color/black" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MyActivity" tools:ignore="MergeRootFrame"> <androidx.media3.ui.PlayerView android:id="@+id/player_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
添加直播参数
如需获取用于测试项目的示例串流资产,请参阅 IMA 示例串流页面。另请参阅有关 DAI 提供的有关如何设置 自己的直播
此步骤演示了如何设置直播,但 ExoPlayer IMA 扩展程序也支持 DAI VOD 直播。请参阅视频点播 (VOD) 串流的步骤,了解您的应用需要进行哪些更改才能处理 VOD 串流。
导入 ExoPlayer IMA 扩展程序
添加 ExoPlayer 扩展程序的 import 语句。
将以下私有变量添加到 MyActivity.java
:
PlayerView
ExoPlayer
ImaServerSideAdInsertionMediaSource.AdsLoader
ImaServerSideAdInsertionMediaSource.AdsLoader.State
添加 Big Buck Bunny (Live) HLS 直播的素材资源键,以便使用此直播进行测试。您可以在 IMA 的示例串流页面上测试更多串流。
创建 KEY_ADS_LOADER_STATE
常量以保存和检索 AdsLoader
状态。
示例如下:
app/src/main/java/com/example/project name/MyActivity.java
import static androidx.media3.common.C.CONTENT_TYPE_HLS; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import androidx.annotation.Nullable; import androidx.annotation.OptIn; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DefaultDataSource; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource; import androidx.media3.exoplayer.ima.ImaServerSideAdInsertionUriBuilder; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.util.EventLogger; import androidx.media3.ui.PlayerView; import androidx.multidex.MultiDex; ... public class MyActivity extends Activity { private static final String KEY_ADS_LOADER_STATE = "ads_loader_state"; private static final String SAMPLE_ASSET_KEY = "c-rArva4ShKVIAkNfy6HUQ"; private PlayerView playerView; private ExoPlayer player; private ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader; private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState; }
创建 adsLoader
实例
覆盖 onCreate
方法以查找 PlayerView
并检查是否有已保存的 AdsLoader.State
,该方法可在启动 adsLoader
对象时使用。
此外,如果应用的方法计数和 minSdkVersion
需要,请启用 MultiDex
(如
第 2 步)。
示例如下:
app/src/main/java/com/example/project name/MyActivity.java
... public class MyActivity extends Activity { private static final String KEY_ADS_LOADER_STATE = "ads_loader_state"; private static final String SAMPLE_ASSET_KEY = "c-rArva4ShKVIAkNfy6HUQ"; private PlayerView playerView; private ExoPlayer player; private ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader; private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); MultiDex.install(this); playerView = findViewById(R.id.player_view); // Checks if there is a saved AdsLoader state to be used later when // initiating the AdsLoader. if (savedInstanceState != null) { Bundle adsLoaderStateBundle = savedInstanceState.getBundle(KEY_ADS_LOADER_STATE); if (adsLoaderStateBundle != null) { adsLoaderState = ImaServerSideAdInsertionMediaSource.AdsLoader.State.fromBundle( adsLoaderStateBundle); } } } }
添加用于初始化播放器的方法
添加用于初始化播放器的方法,并执行以下操作:
- 创建一个
AdsLoader
实例。 - 创建
ExoPlayer
。 - 使用直播的素材资源键创建
MediaItem
。 - 将
MediaItem
设置为您的播放器。
示例如下:
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { ... // Create a server side ad insertion (SSAI) AdsLoader. private ImaServerSideAdInsertionMediaSource.AdsLoader createAdsLoader() { ImaServerSideAdInsertionMediaSource.AdsLoader.Builder adsLoaderBuilder = new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(this, playerView); // Attempt to set the AdsLoader state if available from a previous session. if (adsLoaderState != null) { adsLoaderBuilder.setAdsLoaderState(adsLoaderState); } return adsLoaderBuilder.build(); } private void initializePlayer() { adsLoader = createAdsLoader(); // Set up the factory for media sources, passing the ads loader. DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(this); DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(dataSourceFactory); // MediaSource.Factory to create the ad sources for the current player. ImaServerSideAdInsertionMediaSource.Factory adsMediaSourceFactory = new ImaServerSideAdInsertionMediaSource.Factory(adsLoader, mediaSourceFactory); // 'mediaSourceFactory' is an ExoPlayer component for the DefaultMediaSourceFactory. // 'adsMediaSourceFactory' is an ExoPlayer component for a MediaSource factory for IMA server // side inserted ad streams. mediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory); // Create an ExoPlayer and set it as the player for content and ads. player = new ExoPlayer.Builder(this).setMediaSourceFactory(mediaSourceFactory).build(); playerView.setPlayer(player); adsLoader.setPlayer(player); // Build an IMA SSAI media item to prepare the player with. Uri ssaiLiveUri = new ImaServerSideAdInsertionUriBuilder() .setAssetKey(SAMPLE_ASSET_KEY) .setFormat(CONTENT_TYPE_HLS) // Use CONTENT_TYPE_DASH for dash streams. .build(); // Create the MediaItem to play, specifying the stream URI. MediaItem ssaiMediaItem = MediaItem.fromUri(ssaiLiveUri); // Prepare the content and ad to be played with the ExoPlayer. player.setMediaItem(ssaiMediaItem); player.prepare(); // Set PlayWhenReady. If true, content and ads will autoplay. player.setPlayWhenReady(false); } }
添加用于释放播放器的方法
添加一个按以下顺序释放播放器的方法:
- 将播放器引用设为 null,并释放播放器的资源。
- 释放
adsLoader
的状态。
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { ... private void releasePlayer() { // Set the player references to null and release the player's resources. playerView.setPlayer(null); player.release(); player = null; // Release the adsLoader state so that it can be initiated again. adsLoaderState = adsLoader.release(); }
处理播放器事件
最后,为 activity 的生命周期事件创建回调,以处理流式播放。
如需支持 Android SDK 24 及更高版本,请执行以下操作:
如需支持低于 24 的 Android SDK 版本,请执行以下操作:
- onResume()
- onPause()
onStart()
和 onResume()
映射到 playerView.onResume()
,onStop()
和
onPause()
映射到 playerView.onPause()
。
此步骤还使用 onSaveInstanceState()
事件尝试保存 adsLoaderState
。
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { ... @Override public void onStart() { super.onStart(); if (Util.SDK_INT > 23) { initializePlayer(); if (playerView != null) { playerView.onResume(); } } } @Override public void onResume() { super.onResume(); if (Util.SDK_INT <= 23 || player == null) { initializePlayer(); if (playerView != null) { playerView.onResume(); } } } @Override public void onPause() { super.onPause(); if (Util.SDK_INT <= 23) { if (playerView != null) { playerView.onPause(); } releasePlayer(); } } @Override public void onStop() { super.onStop(); if (Util.SDK_INT > 23) { if (playerView != null) { playerView.onPause(); } releasePlayer(); } } @Override public void onSaveInstanceState(Bundle outState) { // Attempts to save the AdsLoader state to handle app backgrounding. if (adsLoaderState != null) { outState.putBundle(KEY_ADS_LOADER_STATE, adsLoaderState.toBundle()); } } ... }
VOD 视频流设置(可选)
如果您的应用需要在播放 VOD 内容时投放广告,您需要执行以下操作:
- 为 VOD 测试串流添加了
CMS ID
和Video ID
。 - 使用
ImaServerSideAdInsertionUriBuilder()
创建 SSAI VOD URI。 - 将此新 URI 用作播放器的媒体内容。
app/src/main/java/com/example/project name/MyActivity.java
public class MyActivity extends Activity { private static final String KEY_ADS_LOADER_STATE = "ads_loader_state"; private static final String SAMPLE_ASSET_KEY = "c-rArva4ShKVIAkNfy6HUQ"; private static final String SAMPLE_CMS_ID = "2548831"; private static final String SAMPLE_VIDEO_ID = "tears-of-steel"; ... private void initializePlayer() { ... Uri ssaiVodUri = new ImaServerSideAdInsertionUriBuilder() .setContentSourceId(SAMPLE_CMS_ID) .setVideoId(SAMPLE_VIDEO_ID) .setFormat(CONTENT_TYPE_HLS) .build(); // Create the MediaItem to play, specifying the stream URI. MediaItem ssaiMediaItem = MediaItem.fromUri(ssaiVodUri); // Prepare the content and ad to be played with the ExoPlayer. player.setMediaItem(ssaiMediaItem); player.prepare(); // Set PlayWhenReady. If true, content and ads will autoplay. player.setPlayWhenReady(false); }
大功告成!您正在通过 ExoPlayer 请求并播放媒体流 IMA 扩展程序。如需查看完整代码,请参阅 GitHub 上的 Android DAI 示例。