Allow playing ads in playlists
- Remove restriction on `AdsMediaSource`s in playlists in `ExoPlayerImpl`. - Allow playing playlists of `AdsMediaSource`s in the demo app. - Add a sample with ads in a playlist in the demo app. Issue: #3750 PiperOrigin-RevId: 344018774
This commit is contained in:
parent
2ddb5b8d94
commit
866c7f85f8
@ -69,6 +69,8 @@
|
|||||||
existing decoder instance for the new format, and if not then the
|
existing decoder instance for the new format, and if not then the
|
||||||
reasons why.
|
reasons why.
|
||||||
* IMA extension:
|
* IMA extension:
|
||||||
|
* Add support for playback of ads in playlists
|
||||||
|
([#3750](https://github.com/google/ExoPlayer/issues/3750)).
|
||||||
* Upgrade IMA SDK dependency to 3.21.0, and release the `AdsLoader`
|
* Upgrade IMA SDK dependency to 3.21.0, and release the `AdsLoader`
|
||||||
([#7344](https://github.com/google/ExoPlayer/issues/7344)).
|
([#7344](https://github.com/google/ExoPlayer/issues/7344)).
|
||||||
* Improve handling of ad tags with unsupported VPAID ads
|
* Improve handling of ad tags with unsupported VPAID ads
|
||||||
@ -76,6 +78,7 @@
|
|||||||
* Fix a bug that caused multiple ads in an ad pod to be skipped when one
|
* Fix a bug that caused multiple ads in an ad pod to be skipped when one
|
||||||
ad in the ad pod was skipped.
|
ad in the ad pod was skipped.
|
||||||
* Fix passing an ads response to the `ImaAdsLoader` builder.
|
* Fix passing an ads response to the `ImaAdsLoader` builder.
|
||||||
|
* Set the overlay language based on the device locale by default.
|
||||||
* Cronet extension:
|
* Cronet extension:
|
||||||
* Fix handling of HTTP status code 200 when making unbounded length range
|
* Fix handling of HTTP status code 200 when making unbounded length range
|
||||||
requests ([#8090](https://github.com/google/ExoPlayer/issues/8090)).
|
requests ([#8090](https://github.com/google/ExoPlayer/issues/8090)).
|
||||||
@ -88,8 +91,6 @@
|
|||||||
* Notify onBufferingEnded when the state of origin player becomes
|
* Notify onBufferingEnded when the state of origin player becomes
|
||||||
STATE_IDLE or STATE_ENDED.
|
STATE_IDLE or STATE_ENDED.
|
||||||
* Allow to remove all playlist items that makes the player reset.
|
* Allow to remove all playlist items that makes the player reset.
|
||||||
* IMA extension:
|
|
||||||
* Set the overlay language based on the device locale by default.
|
|
||||||
|
|
||||||
### 2.12.1 (2020-10-23) ###
|
### 2.12.1 (2020-10-23) ###
|
||||||
|
|
||||||
|
@ -502,6 +502,23 @@
|
|||||||
"name": "VMAP midroll ad pod at 5 s with 10 skippable ads",
|
"name": "VMAP midroll ad pod at 5 s with 10 skippable ads",
|
||||||
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/frame-counter-one-hour.mp4",
|
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/frame-counter-one-hour.mp4",
|
||||||
"ad_tag_uri": "https://vastsynthesizer.appspot.com/midroll-10-skippable-ads"
|
"ad_tag_uri": "https://vastsynthesizer.appspot.com/midroll-10-skippable-ads"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Playlist with three ad tags",
|
||||||
|
"playlist": [
|
||||||
|
{
|
||||||
|
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/android-screens-10s.mp4",
|
||||||
|
"ad_tag_uri": "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/android-screens-25s.mp4",
|
||||||
|
"ad_tag_uri": "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/frame-counter-one-hour.mp4",
|
||||||
|
"ad_tag_uri": "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&cmsid=496&vid=short_tencue&correlator="
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -355,11 +355,6 @@ public class PlayerActivity extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private AdsLoader getAdsLoader(MediaItem.AdsConfiguration adsConfiguration) {
|
private AdsLoader getAdsLoader(MediaItem.AdsConfiguration adsConfiguration) {
|
||||||
if (mediaItems.size() > 1) {
|
|
||||||
showToast(R.string.unsupported_ads_in_playlist);
|
|
||||||
releaseAdsLoader();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// The ads loader is reused for multiple playbacks, so that ad playback can resume.
|
// The ads loader is reused for multiple playbacks, so that ad playback can resume.
|
||||||
if (adsLoader == null) {
|
if (adsLoader == null) {
|
||||||
adsLoader = new ImaAdsLoader.Builder(/* context= */ this).build();
|
adsLoader = new ImaAdsLoader.Builder(/* context= */ this).build();
|
||||||
|
@ -45,8 +45,6 @@
|
|||||||
|
|
||||||
<string name="sample_list_load_error">One or more sample lists failed to load</string>
|
<string name="sample_list_load_error">One or more sample lists failed to load</string>
|
||||||
|
|
||||||
<string name="unsupported_ads_in_playlist">Playing without ads, as ads are not supported in playlists</string>
|
|
||||||
|
|
||||||
<string name="download_start_error">Failed to start download</string>
|
<string name="download_start_error">Failed to start download</string>
|
||||||
|
|
||||||
<string name="download_start_error_offline_license">Failed to obtain offline license</string>
|
<string name="download_start_error_offline_license">Failed to obtain offline license</string>
|
||||||
|
@ -34,7 +34,6 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||||||
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
||||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||||
@ -92,7 +91,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
private SeekParameters seekParameters;
|
private SeekParameters seekParameters;
|
||||||
private ShuffleOrder shuffleOrder;
|
private ShuffleOrder shuffleOrder;
|
||||||
private boolean pauseAtEndOfMediaItems;
|
private boolean pauseAtEndOfMediaItems;
|
||||||
private boolean hasAdsMediaSource;
|
|
||||||
|
|
||||||
// Playback information when there is no pending seek/set source operation.
|
// Playback information when there is no pending seek/set source operation.
|
||||||
private PlaybackInfo playbackInfo;
|
private PlaybackInfo playbackInfo;
|
||||||
@ -435,7 +433,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
@Override
|
@Override
|
||||||
public void addMediaSources(int index, List<MediaSource> mediaSources) {
|
public void addMediaSources(int index, List<MediaSource> mediaSources) {
|
||||||
Assertions.checkArgument(index >= 0);
|
Assertions.checkArgument(index >= 0);
|
||||||
validateMediaSources(mediaSources, /* mediaSourceReplacement= */ false);
|
|
||||||
Timeline oldTimeline = getCurrentTimeline();
|
Timeline oldTimeline = getCurrentTimeline();
|
||||||
pendingOperationAcks++;
|
pendingOperationAcks++;
|
||||||
List<MediaSourceList.MediaSourceHolder> holders = addMediaSourceHolders(index, mediaSources);
|
List<MediaSourceList.MediaSourceHolder> holders = addMediaSourceHolders(index, mediaSources);
|
||||||
@ -1140,7 +1137,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
int startWindowIndex,
|
int startWindowIndex,
|
||||||
long startPositionMs,
|
long startPositionMs,
|
||||||
boolean resetToDefaultPosition) {
|
boolean resetToDefaultPosition) {
|
||||||
validateMediaSources(mediaSources, /* mediaSourceReplacement= */ true);
|
|
||||||
int currentWindowIndex = getCurrentWindowIndexInternal();
|
int currentWindowIndex = getCurrentWindowIndexInternal();
|
||||||
long currentPositionMs = getCurrentPosition();
|
long currentPositionMs = getCurrentPosition();
|
||||||
pendingOperationAcks++;
|
pendingOperationAcks++;
|
||||||
@ -1239,39 +1235,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
mediaSourceHolderSnapshots.remove(i);
|
mediaSourceHolderSnapshots.remove(i);
|
||||||
}
|
}
|
||||||
shuffleOrder = shuffleOrder.cloneAndRemove(fromIndex, toIndexExclusive);
|
shuffleOrder = shuffleOrder.cloneAndRemove(fromIndex, toIndexExclusive);
|
||||||
if (mediaSourceHolderSnapshots.isEmpty()) {
|
|
||||||
hasAdsMediaSource = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates media sources before any modification of the existing list of media sources is made.
|
|
||||||
* This way we can throw an exception before changing the state of the player in case of a
|
|
||||||
* validation failure.
|
|
||||||
*
|
|
||||||
* @param mediaSources The media sources to set or add.
|
|
||||||
* @param mediaSourceReplacement Whether the given media sources will replace existing ones.
|
|
||||||
*/
|
|
||||||
private void validateMediaSources(
|
|
||||||
List<MediaSource> mediaSources, boolean mediaSourceReplacement) {
|
|
||||||
if (hasAdsMediaSource && !mediaSourceReplacement && !mediaSources.isEmpty()) {
|
|
||||||
// Adding media sources to an ads media source is not allowed
|
|
||||||
// (see https://github.com/google/ExoPlayer/issues/3750).
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
int sizeAfterModification =
|
|
||||||
mediaSources.size() + (mediaSourceReplacement ? 0 : mediaSourceHolderSnapshots.size());
|
|
||||||
for (int i = 0; i < mediaSources.size(); i++) {
|
|
||||||
MediaSource mediaSource = checkNotNull(mediaSources.get(i));
|
|
||||||
if (mediaSource instanceof AdsMediaSource) {
|
|
||||||
if (sizeAfterModification > 1) {
|
|
||||||
// Ads media sources only allowed with a single source
|
|
||||||
// (see https://github.com/google/ExoPlayer/issues/3750).
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
hasAdsMediaSource = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Timeline createMaskingTimeline() {
|
private Timeline createMaskingTimeline() {
|
||||||
|
@ -47,7 +47,6 @@ import android.media.AudioManager;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
@ -65,7 +64,6 @@ import com.google.android.exoplayer2.robolectric.TestPlayerRunHelper;
|
|||||||
import com.google.android.exoplayer2.source.ClippingMediaSource;
|
import com.google.android.exoplayer2.source.ClippingMediaSource;
|
||||||
import com.google.android.exoplayer2.source.CompositeMediaSource;
|
import com.google.android.exoplayer2.source.CompositeMediaSource;
|
||||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
|
||||||
import com.google.android.exoplayer2.source.LoopingMediaSource;
|
import com.google.android.exoplayer2.source.LoopingMediaSource;
|
||||||
import com.google.android.exoplayer2.source.MaskingMediaSource;
|
import com.google.android.exoplayer2.source.MaskingMediaSource;
|
||||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||||
@ -77,8 +75,6 @@ import com.google.android.exoplayer2.source.SilenceMediaSource;
|
|||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
||||||
import com.google.android.exoplayer2.source.ads.AdsLoader;
|
|
||||||
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
|
||||||
import com.google.android.exoplayer2.testutil.Action;
|
import com.google.android.exoplayer2.testutil.Action;
|
||||||
import com.google.android.exoplayer2.testutil.ActionSchedule;
|
import com.google.android.exoplayer2.testutil.ActionSchedule;
|
||||||
import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable;
|
import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable;
|
||||||
@ -106,7 +102,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.upstream.Allocation;
|
import com.google.android.exoplayer2.upstream.Allocation;
|
||||||
import com.google.android.exoplayer2.upstream.Allocator;
|
import com.google.android.exoplayer2.upstream.Allocator;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
|
||||||
import com.google.android.exoplayer2.upstream.Loader;
|
import com.google.android.exoplayer2.upstream.Loader;
|
||||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
@ -5571,124 +5566,6 @@ public final class ExoPlayerTest {
|
|||||||
assertThat(positionAfterSetShuffleOrder.get()).isAtLeast(5000);
|
assertThat(positionAfterSetShuffleOrder.get()).isAtLeast(5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setMediaSources_secondAdMediaSource_throws() throws Exception {
|
|
||||||
AdsMediaSource adsMediaSource =
|
|
||||||
new AdsMediaSource(
|
|
||||||
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1)),
|
|
||||||
/* adTagDataSpec= */ new DataSpec(Uri.EMPTY),
|
|
||||||
/* adsId= */ new Object(),
|
|
||||||
new DefaultMediaSourceFactory(context),
|
|
||||||
new FakeAdsLoader(),
|
|
||||||
new FakeAdViewProvider());
|
|
||||||
Exception[] exception = {null};
|
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder(TAG)
|
|
||||||
.executeRunnable(
|
|
||||||
new PlayerRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run(SimpleExoPlayer player) {
|
|
||||||
try {
|
|
||||||
player.setMediaSource(adsMediaSource);
|
|
||||||
player.addMediaSource(adsMediaSource);
|
|
||||||
} catch (Exception e) {
|
|
||||||
exception[0] = e;
|
|
||||||
}
|
|
||||||
player.prepare();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
|
|
||||||
new ExoPlayerTestRunner.Builder(context)
|
|
||||||
.setActionSchedule(actionSchedule)
|
|
||||||
.build()
|
|
||||||
.start(/* doPrepare= */ false)
|
|
||||||
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
|
||||||
|
|
||||||
assertThat(exception[0]).isInstanceOf(IllegalStateException.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setMediaSources_multipleMediaSourcesWithAd_throws() throws Exception {
|
|
||||||
MediaSource mediaSource = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1));
|
|
||||||
AdsMediaSource adsMediaSource =
|
|
||||||
new AdsMediaSource(
|
|
||||||
mediaSource,
|
|
||||||
/* adTagDataSpec= */ new DataSpec(Uri.EMPTY),
|
|
||||||
/* adsId= */ new Object(),
|
|
||||||
new DefaultMediaSourceFactory(context),
|
|
||||||
new FakeAdsLoader(),
|
|
||||||
new FakeAdViewProvider());
|
|
||||||
final Exception[] exception = {null};
|
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder(TAG)
|
|
||||||
.executeRunnable(
|
|
||||||
new PlayerRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run(SimpleExoPlayer player) {
|
|
||||||
try {
|
|
||||||
List<MediaSource> sources = new ArrayList<>();
|
|
||||||
sources.add(mediaSource);
|
|
||||||
sources.add(adsMediaSource);
|
|
||||||
player.setMediaSources(sources);
|
|
||||||
} catch (Exception e) {
|
|
||||||
exception[0] = e;
|
|
||||||
}
|
|
||||||
player.prepare();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
|
|
||||||
new ExoPlayerTestRunner.Builder(context)
|
|
||||||
.setActionSchedule(actionSchedule)
|
|
||||||
.build()
|
|
||||||
.start(/* doPrepare= */ false)
|
|
||||||
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
|
||||||
|
|
||||||
assertThat(exception[0]).isInstanceOf(IllegalArgumentException.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void setMediaSources_addingMediaSourcesWithAdToNonEmptyPlaylist_throws() throws Exception {
|
|
||||||
MediaSource mediaSource = new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1));
|
|
||||||
AdsMediaSource adsMediaSource =
|
|
||||||
new AdsMediaSource(
|
|
||||||
mediaSource,
|
|
||||||
/* adTagDataSpec= */ new DataSpec(Uri.EMPTY),
|
|
||||||
/* adsId= */ new Object(),
|
|
||||||
new DefaultMediaSourceFactory(context),
|
|
||||||
new FakeAdsLoader(),
|
|
||||||
new FakeAdViewProvider());
|
|
||||||
final Exception[] exception = {null};
|
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder(TAG)
|
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
|
||||||
.executeRunnable(
|
|
||||||
new PlayerRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run(SimpleExoPlayer player) {
|
|
||||||
try {
|
|
||||||
player.addMediaSource(adsMediaSource);
|
|
||||||
} catch (Exception e) {
|
|
||||||
exception[0] = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
|
|
||||||
new ExoPlayerTestRunner.Builder(context)
|
|
||||||
.setMediaSources(mediaSource)
|
|
||||||
.setActionSchedule(actionSchedule)
|
|
||||||
.build()
|
|
||||||
.start()
|
|
||||||
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
|
||||||
|
|
||||||
assertThat(exception[0]).isInstanceOf(IllegalArgumentException.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setMediaSources_empty_whenEmpty_correctMaskingWindowIndex() throws Exception {
|
public void setMediaSources_empty_whenEmpty_correctMaskingWindowIndex() throws Exception {
|
||||||
Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 1);
|
Timeline secondTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||||
@ -9117,53 +8994,6 @@ public final class ExoPlayerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FakeAdsLoader implements AdsLoader {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayer(@Nullable Player player) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSupportedContentTypes(int... contentTypes) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(
|
|
||||||
AdsMediaSource adsMediaSource,
|
|
||||||
DataSpec adTagDataSpec,
|
|
||||||
Object adsId,
|
|
||||||
AdViewProvider adViewProvider,
|
|
||||||
AdsLoader.EventListener eventListener) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(AdsMediaSource adsMediaSource) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handlePrepareComplete(
|
|
||||||
AdsMediaSource adsMediaSource, int adGroupIndex, int adIndexInAdGroup) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handlePrepareError(
|
|
||||||
AdsMediaSource adsMediaSource,
|
|
||||||
int adGroupIndex,
|
|
||||||
int adIndexInAdGroup,
|
|
||||||
IOException exception) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FakeAdViewProvider implements AdsLoader.AdViewProvider {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ViewGroup getAdViewGroup() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImmutableList<AdsLoader.OverlayInfo> getAdOverlayInfos() {
|
|
||||||
return ImmutableList.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an argument matcher for {@link Timeline} instances that ignores period and window uids.
|
* Returns an argument matcher for {@link Timeline} instances that ignores period and window uids.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user