diff --git a/AdvancedExample/app/build.gradle b/AdvancedExample/app/build.gradle index 96a0c99..dc834da 100644 --- a/AdvancedExample/app/build.gradle +++ b/AdvancedExample/app/build.gradle @@ -32,7 +32,7 @@ repositories { } dependencies { - def media3_version = "1.3.1" + def media3_version = "1.4.1" implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' @@ -42,5 +42,5 @@ dependencies { implementation "androidx.media3:media3-exoplayer-dash:$media3_version" implementation 'androidx.mediarouter:mediarouter:1.7.0' implementation 'androidx.recyclerview:recyclerview:1.3.2' - implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.34.0' + implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1' } diff --git a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java index 3c8c6d4..154687c 100644 --- a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java +++ b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java @@ -62,9 +62,6 @@ public interface SampleVideoPlayerCallback extends VideoStreamPlayer.VideoStream private ExoPlayer player; private final PlayerView playerView; private SampleVideoPlayerCallback playerCallback; - - @C.ContentType private int currentlyPlayingStreamType = C.CONTENT_TYPE_OTHER; - private String streamUrl; private Boolean streamRequested; private boolean canSeek; @@ -121,10 +118,9 @@ public void play() { DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(context); MediaSource mediaSource; - currentlyPlayingStreamType = Util.inferContentType(Uri.parse(streamUrl)); Uri streamUri = Uri.parse(streamUrl); MediaItem mediaItem = new MediaItem.Builder().setUri(streamUri).build(); - switch (currentlyPlayingStreamType) { + switch (Util.inferContentType(Uri.parse(streamUrl))) { case C.CONTENT_TYPE_HLS: mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem); break; @@ -148,16 +144,14 @@ public void play() { public void onMetadata(Metadata metadata) { for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); - if (entry instanceof TextInformationFrame) { - TextInformationFrame textFrame = (TextInformationFrame) entry; + if (entry instanceof TextInformationFrame textFrame) { if ("TXXX".equals(textFrame.id)) { - Log.d(LOG_TAG, "Received user text: " + textFrame.value); + Log.d(LOG_TAG, "Received user text: " + textFrame.values.get(0)); if (playerCallback != null) { - playerCallback.onUserTextReceived(textFrame.value); + playerCallback.onUserTextReceived(textFrame.values.get(0)); } } - } else if (entry instanceof EventMessage) { - EventMessage eventMessage = (EventMessage) entry; + } else if (entry instanceof EventMessage eventMessage) { String eventMessageValue = new String(eventMessage.messageData); Log.d(LOG_TAG, "Received user text: " + eventMessageValue); if (playerCallback != null) { diff --git a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java index cd18577..a30d5c7 100644 --- a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java +++ b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java @@ -44,14 +44,14 @@ public class MyActivity extends AppCompatActivity { private static final String VIDEO_FRAGMENT_TAG = "video_example_fragment_tag"; private static final String FALLBACK_STREAM_URL = - "https://storage.googleapis.com/testtopbox-public/video_content/bbb/master.m3u8"; + "https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8"; private static final String APP_LOG_TAG = "ImaDaiExample"; private SampleVideoPlayer videoPlayer; private SampleAdsWrapper sampleAdsWrapper; private ImageButton playButton; - private HashMap bookmarks = new HashMap<>(); + private final HashMap bookmarks = new HashMap<>(); private VideoListFragment.VideoListItem videoListItem; private boolean contentHasStarted = false; @@ -132,9 +132,8 @@ public void onResume() { } public void hidePlayButton() { - ImageButton button = (ImageButton) findViewById(R.id.playButton); - if (button != null) { - button.setVisibility(View.INVISIBLE); + if (playButton != null) { + playButton.setVisibility(View.INVISIBLE); } } @@ -158,7 +157,7 @@ public void onVideoSelected(VideoListFragment.VideoListItem videoItem) { } }; - private VideoFragmentListener mVideoFragmentListener = + private final VideoFragmentListener mVideoFragmentListener = new VideoFragmentListener() { @Override public void onVideoFragmentCreated(View rootView) { @@ -166,15 +165,13 @@ public void onVideoFragmentCreated(View rootView) { // to be set to false here, in the case where multiple test cases are watched in // single session. contentHasStarted = false; - playButton = (ImageButton) rootView.findViewById(R.id.playButton); + playButton = rootView.findViewById(R.id.playButton); videoPlayer = new SampleVideoPlayer(rootView.getContext(), rootView.findViewById(R.id.videoView)); videoPlayer.enableControls(false); sampleAdsWrapper = new SampleAdsWrapper( - rootView.getContext(), - videoPlayer, - (ViewGroup) rootView.findViewById(R.id.adUiContainer)); + rootView.getContext(), videoPlayer, rootView.findViewById(R.id.adUiContainer)); sampleAdsWrapper.setFallbackUrl(FALLBACK_STREAM_URL); final TextView descTextView = rootView.findViewById(R.id.playerDescription); @@ -198,35 +195,29 @@ public void onVideoFragmentCreated(View rootView) { forceHeight.applyTo(constraintLayout); sampleAdsWrapper.setLogger( - new SampleAdsWrapper.Logger() { - @Override - public void log(String logMessage) { - Log.i(APP_LOG_TAG, logMessage); - if (logTextView != null) { - logTextView.append(logMessage); - } + logMessage -> { + Log.i(APP_LOG_TAG, logMessage); + if (logTextView != null) { + logTextView.append(logMessage); } }); // Set up play button listener to play video then hide play button. playButton.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View view) { - hidePlayButton(); - if (contentHasStarted) { - videoPlayer.play(); - return; - } - contentHasStarted = true; - long bookMarkTime = 0; - if (bookmarks.containsKey(videoListItem.getId())) { - bookMarkTime = bookmarks.get(videoListItem.getId()); - } - videoPlayer.enableControls(true); - videoPlayer.setCanSeek(true); - sampleAdsWrapper.requestAndPlayAds(videoListItem, bookMarkTime); + view -> { + hidePlayButton(); + if (contentHasStarted) { + videoPlayer.play(); + return; } + contentHasStarted = true; + long bookMarkTime = 0; + if (bookmarks.containsKey(videoListItem.getId())) { + bookMarkTime = bookmarks.get(videoListItem.getId()); + } + videoPlayer.enableControls(true); + videoPlayer.setCanSeek(true); + sampleAdsWrapper.requestAndPlayAds(videoListItem, bookMarkTime); }); orientVideoDescription(getResources().getConfiguration().orientation); diff --git a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java index f414a0c..5e983f5 100644 --- a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java +++ b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java @@ -19,7 +19,6 @@ import android.content.Context; import android.util.Log; import android.view.ViewGroup; -import androidx.annotation.NonNull; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdsLoader; @@ -89,7 +88,7 @@ private void createAdsLoader() { videoPlayer.setSampleVideoPlayerCallback( new SampleVideoPlayer.SampleVideoPlayerCallback() { @Override - public void onUserTextReceived(@NonNull String userText) { + public void onUserTextReceived(String userText) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onUserTextReceived(userText); } @@ -185,7 +184,7 @@ private StreamRequest buildStreamRequest(VideoListFragment.VideoListItem videoLi private VideoStreamPlayer createVideoStreamPlayer() { return new VideoStreamPlayer() { @Override - public void loadUrl(@NonNull String url, @NonNull List> subtitles) { + public void loadUrl(String url, List> subtitles) { videoPlayer.setStreamUrl(url); videoPlayer.play(); @@ -215,12 +214,12 @@ public int getVolume() { } @Override - public void addCallback(@NonNull VideoStreamPlayerCallback videoStreamPlayerCallback) { + public void addCallback(VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.add(videoStreamPlayerCallback); } @Override - public void removeCallback(@NonNull VideoStreamPlayerCallback videoStreamPlayerCallback) { + public void removeCallback(VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.remove(videoStreamPlayerCallback); } @@ -264,7 +263,6 @@ public void seek(long timeMs) { videoPlayer.seekTo(timeMs); } - @NonNull @Override public VideoProgressUpdate getContentProgress() { if (videoPlayer == null) { diff --git a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/VideoListFragment.java b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/VideoListFragment.java index 46c0a0a..dfd9e4c 100644 --- a/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/VideoListFragment.java +++ b/AdvancedExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/VideoListFragment.java @@ -21,7 +21,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; @@ -162,19 +161,16 @@ public View onCreateView( LayoutInflater layoutInflater, final ViewGroup viewGroup, Bundle bundle) { View rootView = layoutInflater.inflate(R.layout.fragment_video_list, viewGroup, false); - final ListView listView = (ListView) rootView.findViewById(R.id.videoListView); + final ListView listView = rootView.findViewById(R.id.videoListView); VideoListAdapter videoListAdapter = new VideoListAdapter(rootView.getContext(), R.layout.video_item, getVideoListItems()); listView.setAdapter(videoListAdapter); listView.setOnItemClickListener( - new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - VideoListItem item = (VideoListItem) listView.getItemAtPosition(position); - if (listener != null && item != null) { - listener.onVideoSelected(item); - } + (parent, view, position, id) -> { + VideoListItem item = (VideoListItem) listView.getItemAtPosition(position); + if (listener != null && item != null) { + listener.onVideoSelected(item); } }); @@ -197,7 +193,7 @@ public View getView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.video_item, parent, false); } // Lookup view for data population - TextView titleText = (TextView) convertView.findViewById(R.id.videoItemText); + TextView titleText = convertView.findViewById(R.id.videoItemText); // Populate the data into the template view using the data object titleText.setText(videoListItem.title); diff --git a/AdvancedExample/app/src/main/res/layout/fragment_video.xml b/AdvancedExample/app/src/main/res/layout/fragment_video.xml index 3462fd3..83d9e82 100644 --- a/AdvancedExample/app/src/main/res/layout/fragment_video.xml +++ b/AdvancedExample/app/src/main/res/layout/fragment_video.xml @@ -34,7 +34,7 @@ android:layout_height="match_parent" /> + android:layout_alignParentEnd="true" + android:paddingStart="10dp" + android:paddingEnd="10dp" /> diff --git a/AdvancedExample/app/src/main/res/layout/fragment_video_list.xml b/AdvancedExample/app/src/main/res/layout/fragment_video_list.xml index ce0d022..815e0f8 100644 --- a/AdvancedExample/app/src/main/res/layout/fragment_video_list.xml +++ b/AdvancedExample/app/src/main/res/layout/fragment_video_list.xml @@ -22,7 +22,6 @@ android:layout_margin="5dp" android:numColumns="1" android:verticalSpacing="10dp" - android:layout_centerHorizontal="true" android:horizontalSpacing="10dp" android:stretchMode="columnWidth" /> diff --git a/AdvancedExample/app/src/main/res/values/strings.xml b/AdvancedExample/app/src/main/res/values/strings.xml index 0258bad..eef32ad 100644 --- a/AdvancedExample/app/src/main/res/values/strings.xml +++ b/AdvancedExample/app/src/main/res/values/strings.xml @@ -1,12 +1,13 @@ - IMA Sample Video Player Settings - Sample Video Stream - Sample Videos 8EE292C4 - Menu + IMA Sample Video Player #000000 + Menu + Play button + Sample Videos + Sample Video Stream diff --git a/AdvancedExample/build.gradle b/AdvancedExample/build.gradle index cb3f981..e15036c 100644 --- a/AdvancedExample/build.gradle +++ b/AdvancedExample/build.gradle @@ -6,6 +6,6 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.0' } } diff --git a/AdvancedExample/gradle/wrapper/gradle-wrapper.properties b/AdvancedExample/gradle/wrapper/gradle-wrapper.properties index 5d6560a..348c409 100644 --- a/AdvancedExample/gradle/wrapper/gradle-wrapper.properties +++ b/AdvancedExample/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip diff --git a/BasicExample/app/build.gradle b/BasicExample/app/build.gradle index de2af98..e9696d6 100644 --- a/BasicExample/app/build.gradle +++ b/BasicExample/app/build.gradle @@ -32,7 +32,7 @@ repositories { } dependencies { - def media3_version = "1.3.1" + def media3_version = "1.4.1" implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) implementation 'androidx.appcompat:appcompat:1.7.0' implementation "androidx.media3:media3-ui:$media3_version" @@ -40,5 +40,5 @@ dependencies { implementation "androidx.media3:media3-exoplayer-hls:$media3_version" implementation "androidx.media3:media3-exoplayer-dash:$media3_version" implementation 'androidx.mediarouter:mediarouter:1.7.0' - implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.34.0' + implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1' } diff --git a/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java b/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java index fd0ef91..6943889 100644 --- a/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java +++ b/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java @@ -18,7 +18,6 @@ import static androidx.media3.common.C.CONTENT_TYPE_DASH; import static androidx.media3.common.C.CONTENT_TYPE_HLS; -import static androidx.media3.common.C.CONTENT_TYPE_OTHER; import static androidx.media3.common.C.TIME_UNSET; import android.annotation.SuppressLint; @@ -64,9 +63,6 @@ public interface SampleVideoPlayerCallback extends VideoStreamPlayer.VideoStream private ExoPlayer player; private final PlayerView playerView; private SampleVideoPlayerCallback playerCallback; - - @ContentType private int currentlyPlayingStreamType = CONTENT_TYPE_OTHER; - private String streamUrl; private Boolean streamRequested; private boolean canSeek; @@ -130,7 +126,7 @@ public void play() { MediaItem mediaItem = new MediaItem.Builder().setUri(contentUri).build(); MediaSource mediaSource; - currentlyPlayingStreamType = Util.inferContentType(Uri.parse(streamUrl)); + @ContentType int currentlyPlayingStreamType = Util.inferContentType(Uri.parse(streamUrl)); switch (currentlyPlayingStreamType) { case CONTENT_TYPE_HLS: mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem); @@ -155,16 +151,14 @@ public void play() { public void onMetadata(Metadata metadata) { for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); - if (entry instanceof TextInformationFrame) { - TextInformationFrame textFrame = (TextInformationFrame) entry; + if (entry instanceof TextInformationFrame textFrame) { if ("TXXX".equals(textFrame.id)) { - Log.d(LOG_TAG, "Received user text: " + textFrame.value); + Log.d(LOG_TAG, "Received user text: " + textFrame.values.get(0)); if (playerCallback != null) { - playerCallback.onUserTextReceived(textFrame.value); + playerCallback.onUserTextReceived(textFrame.values.get(0)); } } - } else if (entry instanceof EventMessage) { - EventMessage eventMessage = (EventMessage) entry; + } else if (entry instanceof EventMessage eventMessage) { String eventMessageValue = new String(eventMessage.messageData); Log.d(LOG_TAG, "Received user text: " + eventMessageValue); if (playerCallback != null) { diff --git a/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java b/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java index 5c5ee93..fe82471 100644 --- a/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java +++ b/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java @@ -22,11 +22,9 @@ import android.os.Bundle; import android.util.Log; import android.view.View; -import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ScrollView; import android.widget.TextView; -import androidx.media3.ui.PlayerView; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer; /** Main Activity that plays media using {@link SampleVideoPlayer}. */ @@ -49,52 +47,38 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_my); View rootView = findViewById(R.id.videoLayout); sampleVideoPlayer = - new SampleVideoPlayer( - rootView.getContext(), (PlayerView) rootView.findViewById(R.id.playerView)); + new SampleVideoPlayer(rootView.getContext(), rootView.findViewById(R.id.playerView)); sampleVideoPlayer.enableControls(false); - playButton = (ImageButton) rootView.findViewById(R.id.playButton); + playButton = rootView.findViewById(R.id.playButton); final SampleAdsWrapper sampleAdsWrapper = - new SampleAdsWrapper( - this, sampleVideoPlayer, (ViewGroup) rootView.findViewById(R.id.adUiContainer)); + new SampleAdsWrapper(this, sampleVideoPlayer, rootView.findViewById(R.id.adUiContainer)); sampleAdsWrapper.setFallbackUrl(DEFAULT_STREAM_URL); - final ScrollView scrollView = (ScrollView) findViewById(R.id.logScroll); - final TextView textView = (TextView) findViewById(R.id.logText); + final ScrollView scrollView = findViewById(R.id.logScroll); + final TextView textView = findViewById(R.id.logText); sampleAdsWrapper.setLogger( - new SampleAdsWrapper.Logger() { - @Override - public void log(String logMessage) { - Log.i(APP_LOG_TAG, logMessage); - if (textView != null) { - textView.append(logMessage); - } - if (scrollView != null) { - scrollView.post( - new Runnable() { - @Override - public void run() { - scrollView.fullScroll(View.FOCUS_DOWN); - } - }); - } + logMessage -> { + Log.i(APP_LOG_TAG, logMessage); + if (textView != null) { + textView.append(logMessage); + } + if (scrollView != null) { + scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN)); } }); // Set up play button listener to play video then hide play button. playButton.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View view) { - if (contentHasStarted) { - sampleVideoPlayer.play(); - } else { - contentHasStarted = true; - sampleVideoPlayer.enableControls(true); - sampleAdsWrapper.requestAndPlayAds(); - } - playButton.setVisibility(View.GONE); + view -> { + if (contentHasStarted) { + sampleVideoPlayer.play(); + } else { + contentHasStarted = true; + sampleVideoPlayer.enableControls(true); + sampleAdsWrapper.requestAndPlayAds(); } + playButton.setVisibility(View.GONE); }); orientVideoDescription(getResources().getConfiguration().orientation); } diff --git a/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java b/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java index 918e0fb..a22fa24 100644 --- a/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java +++ b/BasicExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java @@ -18,7 +18,6 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.os.Build; import android.view.ViewGroup; import android.webkit.WebView; import androidx.annotation.Nullable; @@ -80,7 +79,6 @@ public interface Logger { private final ImaSdkFactory sdkFactory; private AdsLoader adsLoader; - private StreamDisplayContainer displayContainer; private StreamManager streamManager; private final List playerCallbacks; @@ -108,9 +106,7 @@ public SampleAdsWrapper(Context context, SampleVideoPlayer videoPlayer, ViewGrou } private void enableWebViewDebugging() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - WebView.setWebContentsDebuggingEnabled(true); - } + WebView.setWebContentsDebuggingEnabled(true); } private void createAdsLoader() { @@ -119,7 +115,8 @@ private void createAdsLoader() { settings.setPlayerType(PLAYER_TYPE); enableWebViewDebugging(); VideoStreamPlayer videoStreamPlayer = createVideoStreamPlayer(); - displayContainer = ImaSdkFactory.createStreamDisplayContainer(adUiContainer, videoStreamPlayer); + StreamDisplayContainer displayContainer = + ImaSdkFactory.createStreamDisplayContainer(adUiContainer, videoStreamPlayer); videoPlayer.setSampleVideoPlayerCallback( new SampleVideoPlayerCallback() { @Override diff --git a/BasicExample/app/src/main/res/layout/activity_my.xml b/BasicExample/app/src/main/res/layout/activity_my.xml index 6ddd50e..6a6d071 100644 --- a/BasicExample/app/src/main/res/layout/activity_my.xml +++ b/BasicExample/app/src/main/res/layout/activity_my.xml @@ -24,7 +24,7 @@ android:layout_height="match_parent" /> - IMA Sample Video Player Settings - Sample Video Stream + IMA Sample Video Player #000000 + Play button + Sample Video Stream diff --git a/BasicExample/build.gradle b/BasicExample/build.gradle index 72e8e2f..2e50183 100644 --- a/BasicExample/build.gradle +++ b/BasicExample/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/BasicExample/gradle/wrapper/gradle-wrapper.properties b/BasicExample/gradle/wrapper/gradle-wrapper.properties index 5d6560a..c76805b 100644 --- a/BasicExample/gradle/wrapper/gradle-wrapper.properties +++ b/BasicExample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +org.gradle.jvmargs=-Xmx4608m zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip diff --git a/CloudVideoStitcherExample/app/build.gradle b/CloudVideoStitcherExample/app/build.gradle index cb4732d..9f9ddb2 100644 --- a/CloudVideoStitcherExample/app/build.gradle +++ b/CloudVideoStitcherExample/app/build.gradle @@ -31,7 +31,7 @@ repositories { } dependencies { - def media3_version = "1.3.1" + def media3_version = "1.4.1" implementation platform("org.jetbrains.kotlin:kotlin-bom:1.8.0") implementation 'androidx.appcompat:appcompat:1.7.0' implementation "androidx.media3:media3-ui:$media3_version" @@ -39,5 +39,5 @@ dependencies { implementation "androidx.media3:media3-exoplayer-hls:$media3_version" implementation "androidx.media3:media3-exoplayer-dash:$media3_version" implementation 'androidx.mediarouter:mediarouter:1.7.0' - implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.34.0' + implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1' } diff --git a/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java b/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java index 7895308..3b691c0 100644 --- a/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java +++ b/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java @@ -18,14 +18,12 @@ import static androidx.media3.common.C.CONTENT_TYPE_DASH; import static androidx.media3.common.C.CONTENT_TYPE_HLS; -import static androidx.media3.common.C.CONTENT_TYPE_OTHER; import static androidx.media3.common.C.TIME_UNSET; import android.annotation.SuppressLint; import android.content.Context; import android.net.Uri; import android.util.Log; -import androidx.media3.common.C.ContentType; import androidx.media3.common.ForwardingPlayer; import androidx.media3.common.MediaItem; import androidx.media3.common.Metadata; @@ -64,9 +62,6 @@ public interface SampleVideoPlayerCallback extends VideoStreamPlayer.VideoStream private ExoPlayer player; private final PlayerView playerView; private SampleVideoPlayerCallback playerCallback; - - @ContentType private int currentlyPlayingStreamType = CONTENT_TYPE_OTHER; - private String streamUrl; private Boolean streamRequested; private boolean canSeek; @@ -130,8 +125,7 @@ public void play() { MediaItem mediaItem = new MediaItem.Builder().setUri(contentUri).build(); MediaSource mediaSource; - currentlyPlayingStreamType = Util.inferContentType(Uri.parse(streamUrl)); - switch (currentlyPlayingStreamType) { + switch (Util.inferContentType(Uri.parse(streamUrl))) { case CONTENT_TYPE_HLS: mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem); break; @@ -155,16 +149,14 @@ public void play() { public void onMetadata(Metadata metadata) { for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); - if (entry instanceof TextInformationFrame) { - TextInformationFrame textFrame = (TextInformationFrame) entry; + if (entry instanceof TextInformationFrame textFrame) { if ("TXXX".equals(textFrame.id)) { Log.d(LOG_TAG, "Received user text: " + textFrame.values.get(0)); if (playerCallback != null) { playerCallback.onUserTextReceived(textFrame.values.get(0)); } } - } else if (entry instanceof EventMessage) { - EventMessage eventMessage = (EventMessage) entry; + } else if (entry instanceof EventMessage eventMessage) { String eventMessageValue = new String(eventMessage.messageData); Log.d(LOG_TAG, "Received user text: " + eventMessageValue); if (playerCallback != null) { diff --git a/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java b/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java index ab32d4a..39bc653 100644 --- a/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java +++ b/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java @@ -25,7 +25,6 @@ import android.widget.ImageButton; import android.widget.ScrollView; import android.widget.TextView; -import androidx.annotation.NonNull; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer; /** Main Activity that plays media using {@link SampleVideoPlayer}. */ @@ -88,7 +87,7 @@ protected void onCreate(Bundle savedInstanceState) { } @Override - public void onConfigurationChanged(@NonNull Configuration configuration) { + public void onConfigurationChanged(Configuration configuration) { super.onConfigurationChanged(configuration); // Hide the extra content when in landscape so the video is as large as possible. updateVideoDescriptionVisibility(); diff --git a/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java b/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java index bbb46fe..d9874a4 100644 --- a/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java +++ b/CloudVideoStitcherExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java @@ -19,7 +19,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.view.ViewGroup; -import androidx.annotation.NonNull; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdsLoader; @@ -89,10 +88,7 @@ private enum StreamType { * @param logger Logger to log messages to. */ public SampleAdsWrapper( - @NonNull Context context, - @NonNull SampleVideoPlayer videoPlayer, - @NonNull ViewGroup adUiContainer, - @NonNull Logger logger) { + Context context, SampleVideoPlayer videoPlayer, ViewGroup adUiContainer, Logger logger) { this.context = context; this.videoPlayer = videoPlayer; this.adUiContainer = adUiContainer; @@ -112,7 +108,7 @@ private AdsLoader createAdsLoader() { videoPlayer.setSampleVideoPlayerCallback( new SampleVideoPlayerCallback() { @Override - public void onUserTextReceived(@NonNull String userText) { + public void onUserTextReceived(String userText) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onUserTextReceived(userText); } @@ -190,8 +186,7 @@ public void requestAndPlayAds() { private VideoStreamPlayer createVideoStreamPlayer() { return new VideoStreamPlayer() { @Override - public void loadUrl( - @NonNull String streamUrl, @NonNull List> subtitles) { + public void loadUrl(String streamUrl, List> subtitles) { videoPlayer.setStreamUrl(streamUrl); videoPlayer.play(); } @@ -215,12 +210,12 @@ public int getVolume() { } @Override - public void addCallback(@NonNull VideoStreamPlayerCallback videoStreamPlayerCallback) { + public void addCallback(VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.add(videoStreamPlayerCallback); } @Override - public void removeCallback(@NonNull VideoStreamPlayerCallback videoStreamPlayerCallback) { + public void removeCallback(VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.remove(videoStreamPlayerCallback); } @@ -251,13 +246,12 @@ public void onAdPeriodEnded() { } @Override - public void seek(@NonNull long timeMs) { + public void seek(long timeMs) { // An ad was skipped. Skip to the content time. videoPlayer.seekTo(timeMs); logger.log("seek\n"); } - @NonNull @Override public VideoProgressUpdate getContentProgress() { return new VideoProgressUpdate( @@ -268,7 +262,7 @@ public VideoProgressUpdate getContentProgress() { /** AdErrorListener implementation */ @Override - public void onAdError(@NonNull AdErrorEvent event) { + public void onAdError(AdErrorEvent event) { logger.log(String.format("Error: %s\n", event.getError().getMessage())); // play fallback URL. logger.log("Playing fallback Url\n"); @@ -279,7 +273,7 @@ public void onAdError(@NonNull AdErrorEvent event) { /** AdEventListener implementation */ @Override - public void onAdEvent(@NonNull AdEvent event) { + public void onAdEvent(AdEvent event) { switch (event.getType()) { case AD_PROGRESS: // Do nothing or else log will be filled by these messages. @@ -292,7 +286,7 @@ public void onAdEvent(@NonNull AdEvent event) { /** AdsLoadedListener implementation */ @Override - public void onAdsManagerLoaded(@NonNull AdsManagerLoadedEvent event) { + public void onAdsManagerLoaded(AdsManagerLoadedEvent event) { streamManager = event.getStreamManager(); streamManager.addAdErrorListener(this); streamManager.addAdEventListener(this); diff --git a/CloudVideoStitcherExample/app/src/main/res/layout/activity_my.xml b/CloudVideoStitcherExample/app/src/main/res/layout/activity_my.xml index 356ca91..6abba67 100644 --- a/CloudVideoStitcherExample/app/src/main/res/layout/activity_my.xml +++ b/CloudVideoStitcherExample/app/src/main/res/layout/activity_my.xml @@ -24,7 +24,7 @@ android:layout_height="match_parent" /> - IMA Sample Cloud Video Stitcher app Settings - Sample Video Stream + IMA Sample Cloud Video Stitcher app #000000 + Play button + Sample Video Stream diff --git a/CloudVideoStitcherExample/build.gradle b/CloudVideoStitcherExample/build.gradle index 72e8e2f..2e50183 100644 --- a/CloudVideoStitcherExample/build.gradle +++ b/CloudVideoStitcherExample/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/CloudVideoStitcherExample/gradle/wrapper/gradle-wrapper.properties b/CloudVideoStitcherExample/gradle/wrapper/gradle-wrapper.properties index 17655d0..2fa91c5 100644 --- a/CloudVideoStitcherExample/gradle/wrapper/gradle-wrapper.properties +++ b/CloudVideoStitcherExample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/ExoPlayerExample/app/build.gradle b/ExoPlayerExample/app/build.gradle index 83b0a96..0dee06d 100644 --- a/ExoPlayerExample/app/build.gradle +++ b/ExoPlayerExample/app/build.gradle @@ -32,7 +32,7 @@ repositories { } dependencies { - def media3_version = "1.3.1" + def media3_version = "1.4.1" implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.appcompat:appcompat:1.7.0' diff --git a/ExoPlayerExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java b/ExoPlayerExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java index 0f49c45..ceb4b6b 100644 --- a/ExoPlayerExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java +++ b/ExoPlayerExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java @@ -9,8 +9,6 @@ import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSource; @@ -39,7 +37,7 @@ public class MyActivity extends Activity { private ImaServerSideAdInsertionMediaSource.AdsLoader.State adsLoaderState; @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { + protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); MultiDex.install(this); @@ -101,7 +99,7 @@ public void onStop() { } @Override - public void onSaveInstanceState(@NonNull Bundle outState) { + 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()); @@ -135,20 +133,17 @@ public AdEvent.AdEventListener buildAdEventListener() { logText = findViewById(R.id.logText); logText.setMovementMethod(new ScrollingMovementMethod()); - AdEvent.AdEventListener imaAdEventListener = - event -> { - AdEvent.AdEventType eventType = event.getType(); - if (eventType == AdEvent.AdEventType.AD_PROGRESS) { - return; - } - String log = "IMA event: " + eventType; - if (logText != null) { - logText.append(log + "\n"); - } - Log.i(LOG_TAG, log); - }; - - return imaAdEventListener; + return event -> { + AdEvent.AdEventType eventType = event.getType(); + if (eventType == AdEvent.AdEventType.AD_PROGRESS) { + return; + } + String log = "IMA event: " + eventType; + if (logText != null) { + logText.append(log + "\n"); + } + Log.i(LOG_TAG, log); + }; } private void initializePlayer() { diff --git a/ExoPlayerExample/app/src/main/res/values/dimens.xml b/ExoPlayerExample/app/src/main/res/values/dimens.xml index b48e5d0..186f1bb 100644 --- a/ExoPlayerExample/app/src/main/res/values/dimens.xml +++ b/ExoPlayerExample/app/src/main/res/values/dimens.xml @@ -2,5 +2,5 @@ 16dp 16dp - 16dp + 16sp diff --git a/ExoPlayerExample/build.gradle b/ExoPlayerExample/build.gradle index 72e8e2f..2e50183 100644 --- a/ExoPlayerExample/build.gradle +++ b/ExoPlayerExample/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/ExoPlayerExample/gradle/wrapper/gradle-wrapper.properties b/ExoPlayerExample/gradle/wrapper/gradle-wrapper.properties index 5d6560a..c76805b 100644 --- a/ExoPlayerExample/gradle/wrapper/gradle-wrapper.properties +++ b/ExoPlayerExample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +org.gradle.jvmargs=-Xmx4608m zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip diff --git a/PodServingExample/app/build.gradle b/PodServingExample/app/build.gradle index cb4732d..9f9ddb2 100644 --- a/PodServingExample/app/build.gradle +++ b/PodServingExample/app/build.gradle @@ -31,7 +31,7 @@ repositories { } dependencies { - def media3_version = "1.3.1" + def media3_version = "1.4.1" implementation platform("org.jetbrains.kotlin:kotlin-bom:1.8.0") implementation 'androidx.appcompat:appcompat:1.7.0' implementation "androidx.media3:media3-ui:$media3_version" @@ -39,5 +39,5 @@ dependencies { implementation "androidx.media3:media3-exoplayer-hls:$media3_version" implementation "androidx.media3:media3-exoplayer-dash:$media3_version" implementation 'androidx.mediarouter:mediarouter:1.7.0' - implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.34.0' + implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.35.1' } diff --git a/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java b/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java index 7895308..3b691c0 100644 --- a/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java +++ b/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java @@ -18,14 +18,12 @@ import static androidx.media3.common.C.CONTENT_TYPE_DASH; import static androidx.media3.common.C.CONTENT_TYPE_HLS; -import static androidx.media3.common.C.CONTENT_TYPE_OTHER; import static androidx.media3.common.C.TIME_UNSET; import android.annotation.SuppressLint; import android.content.Context; import android.net.Uri; import android.util.Log; -import androidx.media3.common.C.ContentType; import androidx.media3.common.ForwardingPlayer; import androidx.media3.common.MediaItem; import androidx.media3.common.Metadata; @@ -64,9 +62,6 @@ public interface SampleVideoPlayerCallback extends VideoStreamPlayer.VideoStream private ExoPlayer player; private final PlayerView playerView; private SampleVideoPlayerCallback playerCallback; - - @ContentType private int currentlyPlayingStreamType = CONTENT_TYPE_OTHER; - private String streamUrl; private Boolean streamRequested; private boolean canSeek; @@ -130,8 +125,7 @@ public void play() { MediaItem mediaItem = new MediaItem.Builder().setUri(contentUri).build(); MediaSource mediaSource; - currentlyPlayingStreamType = Util.inferContentType(Uri.parse(streamUrl)); - switch (currentlyPlayingStreamType) { + switch (Util.inferContentType(Uri.parse(streamUrl))) { case CONTENT_TYPE_HLS: mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem); break; @@ -155,16 +149,14 @@ public void play() { public void onMetadata(Metadata metadata) { for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); - if (entry instanceof TextInformationFrame) { - TextInformationFrame textFrame = (TextInformationFrame) entry; + if (entry instanceof TextInformationFrame textFrame) { if ("TXXX".equals(textFrame.id)) { Log.d(LOG_TAG, "Received user text: " + textFrame.values.get(0)); if (playerCallback != null) { playerCallback.onUserTextReceived(textFrame.values.get(0)); } } - } else if (entry instanceof EventMessage) { - EventMessage eventMessage = (EventMessage) entry; + } else if (entry instanceof EventMessage eventMessage) { String eventMessageValue = new String(eventMessage.messageData); Log.d(LOG_TAG, "Received user text: " + eventMessageValue); if (playerCallback != null) { diff --git a/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java b/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java index ab32d4a..39bc653 100644 --- a/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java +++ b/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java @@ -25,7 +25,6 @@ import android.widget.ImageButton; import android.widget.ScrollView; import android.widget.TextView; -import androidx.annotation.NonNull; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer; /** Main Activity that plays media using {@link SampleVideoPlayer}. */ @@ -88,7 +87,7 @@ protected void onCreate(Bundle savedInstanceState) { } @Override - public void onConfigurationChanged(@NonNull Configuration configuration) { + public void onConfigurationChanged(Configuration configuration) { super.onConfigurationChanged(configuration); // Hide the extra content when in landscape so the video is as large as possible. updateVideoDescriptionVisibility(); diff --git a/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java b/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java index d45fd68..79bf175 100644 --- a/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java +++ b/PodServingExample/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/SampleAdsWrapper.java @@ -19,7 +19,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.view.ViewGroup; -import androidx.annotation.NonNull; import com.google.ads.interactivemedia.v3.api.AdErrorEvent; import com.google.ads.interactivemedia.v3.api.AdEvent; import com.google.ads.interactivemedia.v3.api.AdsLoader; @@ -83,10 +82,7 @@ private enum StreamType { * @param logger Logger to log messages to. */ public SampleAdsWrapper( - @NonNull Context context, - @NonNull SampleVideoPlayer videoPlayer, - @NonNull ViewGroup adUiContainer, - @NonNull Logger logger) { + Context context, SampleVideoPlayer videoPlayer, ViewGroup adUiContainer, Logger logger) { this.context = context; this.videoPlayer = videoPlayer; this.adUiContainer = adUiContainer; @@ -106,7 +102,7 @@ private AdsLoader createAdsLoader() { videoPlayer.setSampleVideoPlayerCallback( new SampleVideoPlayerCallback() { @Override - public void onUserTextReceived(@NonNull String userText) { + public void onUserTextReceived(String userText) { for (VideoStreamPlayer.VideoStreamPlayerCallback callback : playerCallbacks) { callback.onUserTextReceived(userText); } @@ -180,12 +176,8 @@ public void requestAndPlayAds() { private VideoStreamPlayer createVideoStreamPlayer() { return new VideoStreamPlayer() { @Override - public void loadUrl( - @NonNull String streamUrl, @NonNull List> subtitles) { - // For VOD stream only, the IMA DAI SDK calls loadUrl() when it completes - // loading the ad metadata. - videoPlayer.setStreamUrl(streamUrl); - videoPlayer.play(); + public void loadUrl(String url, List> subtitles) { + // When pod serving is enabled, IMA doesn't make calls to VideoStreamPlayer.loadUrl(). } @Override @@ -207,12 +199,12 @@ public int getVolume() { } @Override - public void addCallback(@NonNull VideoStreamPlayerCallback videoStreamPlayerCallback) { + public void addCallback(VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.add(videoStreamPlayerCallback); } @Override - public void removeCallback(@NonNull VideoStreamPlayerCallback videoStreamPlayerCallback) { + public void removeCallback(VideoStreamPlayerCallback videoStreamPlayerCallback) { playerCallbacks.remove(videoStreamPlayerCallback); } @@ -243,13 +235,12 @@ public void onAdPeriodEnded() { } @Override - public void seek(@NonNull long timeMs) { + public void seek(long timeMs) { // An ad was skipped. Skip to the content time. videoPlayer.seekTo(timeMs); logger.log("seek\n"); } - @NonNull @Override public VideoProgressUpdate getContentProgress() { return new VideoProgressUpdate( @@ -260,7 +251,7 @@ public VideoProgressUpdate getContentProgress() { /** AdErrorListener implementation */ @Override - public void onAdError(@NonNull AdErrorEvent event) { + public void onAdError(AdErrorEvent event) { logger.log(String.format("Error: %s\n", event.getError().getMessage())); // play fallback URL. logger.log("Playing fallback Url\n"); @@ -271,7 +262,7 @@ public void onAdError(@NonNull AdErrorEvent event) { /** AdEventListener implementation */ @Override - public void onAdEvent(@NonNull AdEvent event) { + public void onAdEvent(AdEvent event) { switch (event.getType()) { case AD_PROGRESS: // Do nothing or else log will be filled by these messages. @@ -284,7 +275,7 @@ public void onAdEvent(@NonNull AdEvent event) { /** AdsLoadedListener implementation */ @Override - public void onAdsManagerLoaded(@NonNull AdsManagerLoadedEvent event) { + public void onAdsManagerLoaded(AdsManagerLoadedEvent event) { streamManager = event.getStreamManager(); streamManager.addAdErrorListener(this); streamManager.addAdEventListener(this); diff --git a/PodServingExample/app/src/main/res/values/strings.xml b/PodServingExample/app/src/main/res/values/strings.xml index 78e3298..260acac 100644 --- a/PodServingExample/app/src/main/res/values/strings.xml +++ b/PodServingExample/app/src/main/res/values/strings.xml @@ -1,9 +1,10 @@ - IMA Sample Pod Serving app Settings - Sample Video Stream + IMA Sample Video Player #000000 + Play button + Sample Video Stream diff --git a/PodServingExample/build.gradle b/PodServingExample/build.gradle index 72e8e2f..2e50183 100644 --- a/PodServingExample/build.gradle +++ b/PodServingExample/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/PodServingExample/gradle/wrapper/gradle-wrapper.properties b/PodServingExample/gradle/wrapper/gradle-wrapper.properties index 17655d0..e064bb4 100644 --- a/PodServingExample/gradle/wrapper/gradle-wrapper.properties +++ b/PodServingExample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +org.gradle.jvmargs=-Xmx4608m zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/SampleVideoPlayer/app/build.gradle b/SampleVideoPlayer/app/build.gradle index b482d22..5bfaf59 100644 --- a/SampleVideoPlayer/app/build.gradle +++ b/SampleVideoPlayer/app/build.gradle @@ -32,7 +32,7 @@ repositories { } dependencies { - def media3_version = "1.3.1" + def media3_version = "1.4.1" implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0")) implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.appcompat:appcompat:1.7.0' diff --git a/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java b/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java index 211a68b..d3bb3c9 100644 --- a/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java +++ b/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/samplevideoplayer/SampleVideoPlayer.java @@ -16,8 +16,12 @@ package com.google.ads.interactivemedia.v3.samples.samplevideoplayer; +import static androidx.media3.common.C.CONTENT_TYPE_DASH; +import static androidx.media3.common.C.CONTENT_TYPE_HLS; + import android.annotation.SuppressLint; import android.content.Context; +import android.net.Uri; import android.util.Log; import androidx.media3.common.C; import androidx.media3.common.ForwardingPlayer; @@ -25,10 +29,15 @@ import androidx.media3.common.Metadata; import androidx.media3.common.Player; import androidx.media3.common.Timeline; +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.dash.DashMediaSource; +import androidx.media3.exoplayer.dash.DefaultDashChunkSource; +import androidx.media3.exoplayer.hls.HlsMediaSource; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; +import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.extractor.metadata.emsg.EventMessage; import androidx.media3.extractor.metadata.id3.TextInformationFrame; import androidx.media3.ui.PlayerView; @@ -53,8 +62,6 @@ public interface SampleVideoPlayerCallback { private ExoPlayer player; private SampleVideoPlayerCallback playerCallback; - @C.ContentType private int currentlyPlayingStreamType = C.CONTENT_TYPE_OTHER; - private String streamUrl; private Boolean streamRequested; private boolean canSeek; @@ -100,6 +107,39 @@ public void seekTo(int windowIndex, long positionMs) { } } }); + } + + public void play() { + if (streamRequested) { + // Stream requested, just resume. + player.setPlayWhenReady(true); + return; + } + initPlayer(); + + DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(context); + + // Create the MediaItem to play, specifying the content URI. + Uri contentUri = Uri.parse(streamUrl); + MediaItem mediaItem = new MediaItem.Builder().setUri(contentUri).build(); + + MediaSource mediaSource; + switch (Util.inferContentType(contentUri)) { + case CONTENT_TYPE_HLS: + mediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItem); + break; + case CONTENT_TYPE_DASH: + mediaSource = + new DashMediaSource.Factory( + new DefaultDashChunkSource.Factory(dataSourceFactory), dataSourceFactory) + .createMediaSource(mediaItem); + break; + default: + throw new UnsupportedOperationException("Unknown stream type."); + } + + player.setMediaSource(mediaSource); + player.prepare(); // Register for ID3 events. player.addListener( @@ -108,16 +148,14 @@ public void seekTo(int windowIndex, long positionMs) { public void onMetadata(Metadata metadata) { for (int i = 0; i < metadata.length(); i++) { Metadata.Entry entry = metadata.get(i); - if (entry instanceof TextInformationFrame) { - TextInformationFrame textFrame = (TextInformationFrame) entry; + if (entry instanceof TextInformationFrame textFrame) { if ("TXXX".equals(textFrame.id)) { - Log.d(LOG_TAG, "Received user text: " + textFrame.value); + Log.d(LOG_TAG, "Received user text: " + textFrame.values.get(0)); if (playerCallback != null) { - playerCallback.onUserTextReceived(textFrame.value); + playerCallback.onUserTextReceived(textFrame.values.get(0)); } } - } else if (entry instanceof EventMessage) { - EventMessage eventMessage = (EventMessage) entry; + } else if (entry instanceof EventMessage eventMessage) { String eventMessageValue = new String(eventMessage.messageData); Log.d(LOG_TAG, "Received user text: " + eventMessageValue); if (playerCallback != null) { @@ -127,18 +165,7 @@ public void onMetadata(Metadata metadata) { } } }); - } - public void play() { - if (streamRequested) { - // Stream requested, just resume. - player.setPlayWhenReady(true); - return; - } - initPlayer(); - - player.setMediaItem(MediaItem.fromUri(streamUrl)); - player.prepare(); player.setPlayWhenReady(true); streamRequested = true; } diff --git a/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java b/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java index 582a17a..3b49113 100644 --- a/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java +++ b/SampleVideoPlayer/app/src/main/java/com/google/ads/interactivemedia/v3/samples/videoplayerapp/MyActivity.java @@ -22,7 +22,6 @@ import android.view.View; import android.widget.ImageButton; import androidx.appcompat.app.AppCompatActivity; -import androidx.media3.ui.PlayerView; import androidx.multidex.MultiDex; import com.google.ads.interactivemedia.v3.samples.samplevideoplayer.SampleVideoPlayer; @@ -46,21 +45,17 @@ protected void onCreate(Bundle savedInstanceState) { MultiDex.install(rootView.getContext()); sampleVideoPlayer = - new SampleVideoPlayer( - rootView.getContext(), (PlayerView) rootView.findViewById(R.id.playerView)); + new SampleVideoPlayer(rootView.getContext(), rootView.findViewById(R.id.playerView)); sampleVideoPlayer.enableControls(false); sampleVideoPlayer.setStreamUrl(DEFAULT_STREAM_URL); playButton = rootView.findViewById(R.id.playButton); // Set up play button listener to play video then hide play button. playButton.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View view) { - sampleVideoPlayer.enableControls(true); - sampleVideoPlayer.play(); - playButton.setVisibility(View.GONE); - } + view -> { + sampleVideoPlayer.enableControls(true); + sampleVideoPlayer.play(); + playButton.setVisibility(View.GONE); }); orientVideoDescription(getResources().getConfiguration().orientation); } diff --git a/SampleVideoPlayer/app/src/main/res/layout/activity_my.xml b/SampleVideoPlayer/app/src/main/res/layout/activity_my.xml index bb72afb..41afdab 100644 --- a/SampleVideoPlayer/app/src/main/res/layout/activity_my.xml +++ b/SampleVideoPlayer/app/src/main/res/layout/activity_my.xml @@ -24,7 +24,7 @@ android:layout_height="match_parent" /> - IMA Sample Video Player Settings + IMA Sample Video Player + Play button Sample Video Stream diff --git a/SampleVideoPlayer/build.gradle b/SampleVideoPlayer/build.gradle index 72e8e2f..2e50183 100644 --- a/SampleVideoPlayer/build.gradle +++ b/SampleVideoPlayer/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.7.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/SampleVideoPlayer/gradle/wrapper/gradle-wrapper.properties b/SampleVideoPlayer/gradle/wrapper/gradle-wrapper.properties index d54cd5d..3e2a00a 100644 --- a/SampleVideoPlayer/gradle/wrapper/gradle-wrapper.properties +++ b/SampleVideoPlayer/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip \ No newline at end of file +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip \ No newline at end of file