mirror of
https://github.com/samsonjs/media.git
synced 2026-03-26 09:35:47 +00:00
Fix ad progress updates after rebuffering an ad
Issue: #8239 #exofixit #minor-release PiperOrigin-RevId: 344211877
This commit is contained in:
parent
87e141d376
commit
ee36e648e3
3 changed files with 88 additions and 4 deletions
|
|
@ -81,6 +81,9 @@
|
|||
([#7832](https://github.com/google/ExoPlayer/issues/7832)).
|
||||
* Fix a bug that caused multiple ads in an ad pod to be skipped when one
|
||||
ad in the ad pod was skipped.
|
||||
* Fix a bug that caused ad progress not to be updated if the player
|
||||
resumed after buffering during an ad
|
||||
([#8239](https://github.com/google/ExoPlayer/issues/8239)).
|
||||
* Fix passing an ads response to the `ImaAdsLoader` builder.
|
||||
* Set the overlay language based on the device locale by default.
|
||||
* Cronet extension:
|
||||
|
|
|
|||
|
|
@ -769,6 +769,7 @@ import java.util.Map;
|
|||
private void handlePlayerStateChanged(boolean playWhenReady, @Player.State int playbackState) {
|
||||
if (playingAd && imaAdState == IMA_AD_STATE_PLAYING) {
|
||||
if (!bufferingAd && playbackState == Player.STATE_BUFFERING) {
|
||||
bufferingAd = true;
|
||||
AdMediaInfo adMediaInfo = checkNotNull(imaAdMediaInfo);
|
||||
for (int i = 0; i < adCallbacks.size(); i++) {
|
||||
adCallbacks.get(i).onBuffering(adMediaInfo);
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
|
@ -117,6 +119,7 @@ public final class ImaAdsLoaderTest {
|
|||
@Mock private AdsRequest mockAdsRequest;
|
||||
@Mock private AdsManagerLoadedEvent mockAdsManagerLoadedEvent;
|
||||
@Mock private com.google.ads.interactivemedia.v3.api.AdsLoader mockAdsLoader;
|
||||
@Mock private VideoAdPlayer.VideoAdPlayerCallback mockVideoAdPlayerCallback;
|
||||
@Mock private FriendlyObstruction mockFriendlyObstruction;
|
||||
@Mock private ImaFactory mockImaFactory;
|
||||
@Mock private AdPodInfo mockAdPodInfo;
|
||||
|
|
@ -168,6 +171,7 @@ public final class ImaAdsLoaderTest {
|
|||
new ImaAdsLoader.Builder(getApplicationContext())
|
||||
.setImaFactory(mockImaFactory)
|
||||
.setImaSdkSettings(mockImaSdkSettings)
|
||||
.setVideoAdPlayerCallback(mockVideoAdPlayerCallback)
|
||||
.build();
|
||||
imaAdsLoader.setPlayer(fakePlayer);
|
||||
adsMediaSource =
|
||||
|
|
@ -257,7 +261,7 @@ public final class ImaAdsLoaderTest {
|
|||
imaAdsLoader.start(
|
||||
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
|
||||
fakePlayer.setPlayingContentPosition(/* periodIndex= */ 0, /* positionMs= */ 0);
|
||||
fakePlayer.setState(Player.STATE_READY, true);
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
|
||||
// If callbacks are invoked there is no crash.
|
||||
// Note: we can't currently call getContentProgress/getAdProgress as a VerifyError is thrown
|
||||
|
|
@ -295,7 +299,7 @@ public final class ImaAdsLoaderTest {
|
|||
/* adIndexInAdGroup= */ 0,
|
||||
/* position= */ 0,
|
||||
/* contentPosition= */ 0);
|
||||
fakePlayer.setState(Player.STATE_READY, true);
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.STARTED, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.FIRST_QUARTILE, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.MIDPOINT, mockPrerollSingleAd));
|
||||
|
|
@ -441,6 +445,82 @@ public final class ImaAdsLoaderTest {
|
|||
.withAdLoadError(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bufferingDuringAd_callsOnBuffering() {
|
||||
// Load the preroll ad.
|
||||
imaAdsLoader.start(
|
||||
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.LOADED, mockPrerollSingleAd));
|
||||
videoAdPlayer.loadAd(TEST_AD_MEDIA_INFO, mockAdPodInfo);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.CONTENT_PAUSE_REQUESTED, mockPrerollSingleAd));
|
||||
|
||||
// Play the preroll ad then simulate buffering.
|
||||
videoAdPlayer.playAd(TEST_AD_MEDIA_INFO);
|
||||
fakePlayer.setPlayingAdPosition(
|
||||
/* periodIndex= */ 0,
|
||||
/* adGroupIndex= */ 0,
|
||||
/* adIndexInAdGroup= */ 0,
|
||||
/* positionMs= */ 0,
|
||||
/* contentPositionMs= */ 0);
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.STARTED, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.FIRST_QUARTILE, mockPrerollSingleAd));
|
||||
fakePlayer.setPlayingAdPosition(
|
||||
/* periodIndex= */ 0,
|
||||
/* adGroupIndex= */ 0,
|
||||
/* adIndexInAdGroup= */ 0,
|
||||
/* positionMs= */ 1_000,
|
||||
/* contentPositionMs= */ 0);
|
||||
fakePlayer.setState(Player.STATE_BUFFERING, /* playWhenReady= */ true);
|
||||
|
||||
verify(mockVideoAdPlayerCallback).onBuffering(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resumeAfterBufferingDuringAd_updatesPosition() {
|
||||
// Load the preroll ad.
|
||||
imaAdsLoader.start(
|
||||
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.LOADED, mockPrerollSingleAd));
|
||||
videoAdPlayer.loadAd(TEST_AD_MEDIA_INFO, mockAdPodInfo);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.CONTENT_PAUSE_REQUESTED, mockPrerollSingleAd));
|
||||
|
||||
// Play the preroll ad.
|
||||
videoAdPlayer.playAd(TEST_AD_MEDIA_INFO);
|
||||
fakePlayer.setPlayingAdPosition(
|
||||
/* periodIndex= */ 0,
|
||||
/* adGroupIndex= */ 0,
|
||||
/* adIndexInAdGroup= */ 0,
|
||||
/* positionMs= */ 0,
|
||||
/* contentPositionMs= */ 0);
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
|
||||
// Simulate buffering.
|
||||
fakePlayer.setPlayingAdPosition(
|
||||
/* periodIndex= */ 0,
|
||||
/* adGroupIndex= */ 0,
|
||||
/* adIndexInAdGroup= */ 0,
|
||||
/* positionMs= */ 2_000,
|
||||
/* contentPositionMs= */ 0);
|
||||
fakePlayer.setState(Player.STATE_BUFFERING, /* playWhenReady= */ true);
|
||||
|
||||
// Simulate resuming and force pending ad progress updates to happen immediately.
|
||||
int newPlayerPositionMs = 3_000;
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
fakePlayer.setPlayingAdPosition(
|
||||
/* periodIndex= */ 0,
|
||||
/* adGroupIndex= */ 0,
|
||||
/* adIndexInAdGroup= */ 0,
|
||||
newPlayerPositionMs,
|
||||
/* contentPositionMs= */ 0);
|
||||
shadowOf(Looper.getMainLooper()).runToEndOfTasks();
|
||||
|
||||
verify(mockVideoAdPlayerCallback)
|
||||
.onAdProgress(
|
||||
TEST_AD_MEDIA_INFO,
|
||||
new VideoProgressUpdate(newPlayerPositionMs, C.usToMs(TEST_AD_DURATION_US)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resumePlaybackBeforeMidroll_playsPreroll() {
|
||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||
|
|
@ -955,7 +1035,7 @@ public final class ImaAdsLoaderTest {
|
|||
/* adIndexInAdGroup= */ 0,
|
||||
/* position= */ 0,
|
||||
/* contentPosition= */ 0);
|
||||
fakePlayer.setState(Player.STATE_READY, true);
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.STARTED, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.FIRST_QUARTILE, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.MIDPOINT, mockPrerollSingleAd));
|
||||
|
|
@ -1012,7 +1092,7 @@ public final class ImaAdsLoaderTest {
|
|||
/* adIndexInAdGroup= */ 0,
|
||||
/* position= */ 0,
|
||||
/* contentPosition= */ 0);
|
||||
fakePlayer.setState(Player.STATE_READY, true);
|
||||
fakePlayer.setState(Player.STATE_READY, /* playWhenReady= */ true);
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.STARTED, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.FIRST_QUARTILE, mockPrerollSingleAd));
|
||||
adEventListener.onAdEvent(getAdEvent(AdEventType.MIDPOINT, mockPrerollSingleAd));
|
||||
|
|
|
|||
Loading…
Reference in a new issue