ExoPlayer は Android メディア プレーヤーです。このガイドでは、ExoPlayer IMA 拡張機能の使用方法について説明します。この拡張機能は、IMA DAI SDK を使用して、広告とコンテンツの両方を含むメディア ストリームをリクエストして再生します。
この拡張機能のメリットは次のとおりです。
- IMA 機能を統合するために必要なコードを簡素化します。
- 新しい IMA バージョンへの更新に必要な時間を短縮します。
ExoPlayer IMA 拡張機能は、HLS と DASH のストリーミング プロトコルをサポートしています。概要は次のとおりです。
| ExoPlayer-IMA 拡張機能のストリーム サポート | ||
|---|---|---|
| ライブ配信 | VOD ストリーム | |
| HLS | ![]() |
![]() |
| DASH | ![]() |
![]() |
ExoPlayer-IMA バージョン 1.1.0 以降では、DASH ライブ ストリームがサポートされています。
このガイドでは、ExoPlayer ガイドを使用して、完全なアプリを作成し、拡張機能を統合する方法について説明します。完全なサンプルアプリについては、GitHub の ExoPlayerExample をご覧ください。
前提条件
- Android Studio
- DAI をサポートする AndroidX Media3 ExoPlayer バージョン 1.0.0 以降。
新しい Android Studio プロジェクトの作成
Android Studio プロジェクトを作成する手順は次のとおりです。
- Android Studio を起動します。
- [Start a new Android Studio project] を選択します。
- [Choose your project] ページで、[No Activity] テンプレートを選択します。
- [次へ] をクリックします。
- [Configure your project] ページで、プロジェクトに名前を付け、言語として [Java] を選択します。注: IMA DAI SDK は Kotlin で動作しますが、このガイドでは Java の例を使用します。
- [完了] をクリックします。
ExoPlayer IMA 拡張機能をプロジェクトに追加する
ExoPlayer IMA 拡張機能を追加する手順は次のとおりです。
アプリの
build.gradleファイルのdependenciesセクションに次のインポートを含めます。dependencies { def media3_version = "1.9.1" coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.3.0")) implementation("androidx.appcompat:appcompat:1.7.1") implementation("androidx.media3:media3-ui:$media3_version") implementation("androidx.media3:media3-exoplayer:$media3_version") implementation("androidx.media3:media3-exoplayer-hls:$media3_version") implementation("androidx.media3:media3-exoplayer-dash:$media3_version") // The library adds the IMA ExoPlayer integration for ads. implementation("androidx.media3:media3-exoplayer-ima:$media3_version") }IMA DAI SDK が広告をリクエストするために必要なユーザー権限を追加します。
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
ExoPlayer UI を設定する
ExoPlayer UI を設定する手順は次のとおりです。
ExoPlayer の
PlayerViewオブジェクトを作成します。ExoPlayer IMA 拡張機能の推奨に従って、
androidx.constraintlayout.widget.ConstraintLayoutビューをLinearLayoutビューに変更します。<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="wrap_content" /> <!-- UI element for viewing SDK event log --> <TextView android:id="@+id/logText" android:gravity="bottom" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="100" android:scrollbars="vertical" android:textSize="@dimen/font_size"> </TextView> </LinearLayout>
ストリーム パラメータを追加する
プロジェクトをテストするためのサンプル ストリーム アセットについては、IMA サンプル ストリーム ページをご覧ください。独自のストリームを設定するには、DAI のアド マネージャー セクションをご覧ください。
この手順では、ライブ配信を設定します。ExoPlayer IMA 拡張機能は、DAI VOD ストリームもサポートしています。VOD ストリームに必要なアプリの変更については、ビデオ オンデマンド(VOD)ストリームの手順をご覧ください。
ExoPlayer IMA 拡張機能をインポートする
ExoPlayer 拡張機能の次の import ステートメントを追加します。
import static androidx.media3.common.C.CONTENT_TYPE_HLS; import android.annotation.SuppressLint; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.widget.TextView; 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.ui.PlayerView; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.ImaSdkFactory; import com.google.ads.interactivemedia.v3.api.ImaSdkSettings; import java.util.HashMap; import java.util.Map;MyActivity.javaに、次の非公開変数を追加します。PlayerViewExoPlayerImaServerSideAdInsertionMediaSource.AdsLoaderImaServerSideAdInsertionMediaSource.AdsLoader.State
Big Buck Bunny(ライブ)HLS ストリームでテストするには、そのアセットキーを追加します。テスト用のストリームは、IMA のサンプル ストリーム ページで確認できます。
AdsLoader状態を保存して取得するためのKEY_ADS_LOADER_STATE定数を作成します。/** Main Activity. */ @SuppressLint("UnsafeOptInUsageError") /* @SuppressLint is needed for new media3 APIs. */ 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 LOG_TAG = "ImaExoPlayerExample"; private PlayerView playerView; private TextView logText; private ExoPlayer player; private ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader; private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState; private ImaSdkSettings imaSdkSettings;
adsLoader インスタンスを作成する
onCreate メソッドをオーバーライドします。その中で PlayerView を見つけ、保存された AdsLoader.State があるかどうかを確認します。この状態は、adsLoader オブジェクトを初期化するときに使用できます。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Initialize the IMA SDK as early as possible when the app starts. If your app already
// overrides Application.onCreate(), call this method inside the onCreate() method.
// https://developer.android.com/topic/performance/vitals/launch-time#app-creation
ImaSdkFactory.getInstance().initialize(this, getImaSdkSettings());
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);
}
}
}
private ImaSdkSettings getImaSdkSettings() {
if (imaSdkSettings == null) {
imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
// Set any IMA SDK settings here.
}
return imaSdkSettings;
}
プレーヤーを初期化するメソッドを追加する
プレーヤーを初期化するメソッドを追加します。このメソッドは、次の処理を行う必要があります。
AdsLoaderインスタンスを作成します。ExoPlayerを作成します。- ライブ ストリームのアセットキーを使用して
MediaItemを作成します。 - プレーヤーの
MediaItemを設定します。
// Create a server side ad insertion (SSAI) AdsLoader.
private ImaServerSideAdInsertionMediaSource.AdsLoader createAdsLoader() {
ImaServerSideAdInsertionMediaSource.AdsLoader.Builder adsLoaderBuilder =
new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(this, playerView);
// Attempts to set the AdsLoader state if available from a previous session.
if (adsLoaderState != null) {
adsLoaderBuilder.setAdsLoaderState(adsLoaderState);
}
return adsLoaderBuilder
.setAdEventListener(buildAdEventListener())
.setImaSdkSettings(getImaSdkSettings())
.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 a SimpleExoPlayer and set it as the player for content and ads.
player = new ExoPlayer.Builder(this).setMediaSourceFactory(mediaSourceFactory).build();
playerView.setPlayer(player);
adsLoader.setPlayer(player);
// Create the MediaItem to play, specifying the stream URI.
Uri ssaiUri = buildLiveStreamUri(SAMPLE_ASSET_KEY, CONTENT_TYPE_HLS);
MediaItem ssaiMediaItem = MediaItem.fromUri(ssaiUri);
// 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);
}
/**
* Builds an IMA SSAI live stream URI for the given asset key and format.
*
* @param assetKey The asset key of the live stream.
* @param format The format of the live stream request, either {@code CONTENT_TYPE_HLS} or {@code
* CONTENT_TYPE_DASH}.
* @return The URI of the live stream.
*/
public Uri buildLiveStreamUri(String assetKey, int format) {
Map<String, String> adTagParams = new HashMap<String, String>();
// Update the adTagParams map with any parameters.
// For more information, see https://support.google.com/admanager/answer/7320899
return new ImaServerSideAdInsertionUriBuilder()
.setAssetKey(assetKey)
.setFormat(format)
.setAdTagParameters(adTagParams)
.build();
}
プレーヤーを解放するメソッドを追加する
プレーヤーをリリースするメソッドを追加します。このメソッドは、次のアクションを順番に実行する必要があります。
- プレーヤー参照を null に設定し、プレーヤーのリソースを解放します。
adsLoader状態を解放します。
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 API レベル 24 以降では、次のメソッドを使用します。
Android API レベル 24 より前の場合は、次のメソッドを使用します。
onStart() メソッドと onResume() メソッドは playerView.onResume() にマッピングされ、onStop() メソッドと onPause() メソッドは playerView.onPause() にマッピングされます。
このステップでは、onSaveInstanceState() イベントを使用して adsLoaderState を保存します。
@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 コンテンツを再生する必要がある場合は、次の手順に沿って対応してください。
- ビデオ オンデマンド ストリームの
CMS IDとVideo IDを追加します。テストには、次のストリーム パラメータを使用します。- CMS ID:
"2548831" - 動画 ID:
"tears-of-steel"
- CMS ID:
ImaServerSideAdInsertionUriBuilder()メソッドを使用して SSAI VOD URI を作成します。/** * Builds an IMA SSAI VOD stream URI for the given CMS ID, video ID, and format. * * @param cmsId The CMS ID of the VOD stream. * @param videoId The video ID of the VOD stream. * @param format The format of the VOD stream request, either {@code CONTENT_TYPE_HLS} or {@code * CONTENT_TYPE_DASH}. * @return The URI of the VOD stream. */ public Uri buildVodStreamUri(String cmsId, String videoId, int format) { Map<String, String> adTagParams = new HashMap<String, String>(); // Update the adTagParams map with any parameters. // For more information, see https://support.google.com/admanager/answer/7320899 return new ImaServerSideAdInsertionUriBuilder() .setContentSourceId(cmsId) .setVideoId(videoId) .setFormat(format) .setAdTagParameters(adTagParams) .build(); }MediaItem.fromUri()メソッドを使用して、新しい VOD ストリーム URI をプレーヤーのメディア アイテムとして設定します。
成功すると、ExoPlayer IMA 拡張機能を使用してメディア ストリームをリクエストして再生できます。完全な例については、GitHub の Android DAI サンプルをご覧ください。
