mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Make AdsMediaSource reusable.
Also fixes a bug where deferred media periods were kept in the list for an unprepared media source although the media period was already released. Issue:#3498 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=183800889
This commit is contained in:
parent
6709dc7f64
commit
17edae6528
1 changed files with 54 additions and 32 deletions
|
|
@ -102,14 +102,11 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
@Nullable private final Handler eventHandler;
|
@Nullable private final Handler eventHandler;
|
||||||
@Nullable private final EventListener eventListener;
|
@Nullable private final EventListener eventListener;
|
||||||
private final Handler mainHandler;
|
private final Handler mainHandler;
|
||||||
private final ComponentListener componentListener;
|
|
||||||
private final Map<MediaSource, List<DeferredMediaPeriod>> deferredMediaPeriodByAdMediaSource;
|
private final Map<MediaSource, List<DeferredMediaPeriod>> deferredMediaPeriodByAdMediaSource;
|
||||||
private final Timeline.Period period;
|
private final Timeline.Period period;
|
||||||
|
|
||||||
private Handler playerHandler;
|
|
||||||
private volatile boolean released;
|
|
||||||
|
|
||||||
// Accessed on the player thread.
|
// Accessed on the player thread.
|
||||||
|
private ComponentListener componentListener;
|
||||||
private Timeline contentTimeline;
|
private Timeline contentTimeline;
|
||||||
private Object contentManifest;
|
private Object contentManifest;
|
||||||
private AdPlaybackState adPlaybackState;
|
private AdPlaybackState adPlaybackState;
|
||||||
|
|
@ -192,7 +189,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
this.eventHandler = eventHandler;
|
this.eventHandler = eventHandler;
|
||||||
this.eventListener = eventListener;
|
this.eventListener = eventListener;
|
||||||
mainHandler = new Handler(Looper.getMainLooper());
|
mainHandler = new Handler(Looper.getMainLooper());
|
||||||
componentListener = new ComponentListener();
|
|
||||||
deferredMediaPeriodByAdMediaSource = new HashMap<>();
|
deferredMediaPeriodByAdMediaSource = new HashMap<>();
|
||||||
period = new Timeline.Period();
|
period = new Timeline.Period();
|
||||||
adGroupMediaSources = new MediaSource[0][];
|
adGroupMediaSources = new MediaSource[0][];
|
||||||
|
|
@ -204,9 +200,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
public void prepareSource(final ExoPlayer player, boolean isTopLevelSource, Listener listener) {
|
public void prepareSource(final ExoPlayer player, boolean isTopLevelSource, Listener listener) {
|
||||||
super.prepareSource(player, isTopLevelSource, listener);
|
super.prepareSource(player, isTopLevelSource, listener);
|
||||||
Assertions.checkArgument(isTopLevelSource);
|
Assertions.checkArgument(isTopLevelSource);
|
||||||
Assertions.checkState(this.listener == null, MEDIA_SOURCE_REUSED_ERROR_MESSAGE);
|
final ComponentListener componentListener = new ComponentListener();
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
playerHandler = new Handler();
|
this.componentListener = componentListener;
|
||||||
prepareChildSource(new MediaPeriodId(/* periodIndex= */ 0), contentMediaSource);
|
prepareChildSource(new MediaPeriodId(/* periodIndex= */ 0), contentMediaSource);
|
||||||
mainHandler.post(new Runnable() {
|
mainHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -258,13 +254,27 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releasePeriod(MediaPeriod mediaPeriod) {
|
public void releasePeriod(MediaPeriod mediaPeriod) {
|
||||||
((DeferredMediaPeriod) mediaPeriod).releasePeriod();
|
DeferredMediaPeriod deferredMediaPeriod = (DeferredMediaPeriod) mediaPeriod;
|
||||||
|
List<DeferredMediaPeriod> mediaPeriods =
|
||||||
|
deferredMediaPeriodByAdMediaSource.get(deferredMediaPeriod.mediaSource);
|
||||||
|
if (mediaPeriods != null) {
|
||||||
|
mediaPeriods.remove(deferredMediaPeriod);
|
||||||
|
}
|
||||||
|
deferredMediaPeriod.releasePeriod();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseSource() {
|
public void releaseSource() {
|
||||||
super.releaseSource();
|
super.releaseSource();
|
||||||
released = true;
|
componentListener.release();
|
||||||
|
componentListener = null;
|
||||||
|
deferredMediaPeriodByAdMediaSource.clear();
|
||||||
|
contentTimeline = null;
|
||||||
|
contentManifest = null;
|
||||||
|
adPlaybackState = null;
|
||||||
|
adGroupMediaSources = new MediaSource[0][];
|
||||||
|
adDurationsUs = new long[0][];
|
||||||
|
listener = null;
|
||||||
mainHandler.post(new Runnable() {
|
mainHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
@ -301,20 +311,6 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
maybeUpdateSourceInfo();
|
maybeUpdateSourceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onLoadError(final IOException error) {
|
|
||||||
Log.w(TAG, "Ad load error", error);
|
|
||||||
if (eventHandler != null && eventListener != null) {
|
|
||||||
eventHandler.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (!released) {
|
|
||||||
eventListener.onAdLoadError(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onContentSourceInfoRefreshed(Timeline timeline, Object manifest) {
|
private void onContentSourceInfoRefreshed(Timeline timeline, Object manifest) {
|
||||||
contentTimeline = timeline;
|
contentTimeline = timeline;
|
||||||
contentManifest = manifest;
|
contentManifest = manifest;
|
||||||
|
|
@ -349,6 +345,23 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
/** Listener for component events. All methods are called on the main thread. */
|
/** Listener for component events. All methods are called on the main thread. */
|
||||||
private final class ComponentListener implements AdsLoader.EventListener {
|
private final class ComponentListener implements AdsLoader.EventListener {
|
||||||
|
|
||||||
|
private final Handler playerHandler;
|
||||||
|
private volatile boolean released;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new listener which forwards ad playback states on the creating thread and all other
|
||||||
|
* events on the external event listener thread.
|
||||||
|
*/
|
||||||
|
public ComponentListener() {
|
||||||
|
playerHandler = new Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Releases the component listener. */
|
||||||
|
public void release() {
|
||||||
|
released = true;
|
||||||
|
playerHandler.removeCallbacksAndMessages(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdPlaybackState(final AdPlaybackState adPlaybackState) {
|
public void onAdPlaybackState(final AdPlaybackState adPlaybackState) {
|
||||||
if (released) {
|
if (released) {
|
||||||
|
|
@ -367,6 +380,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdClicked() {
|
public void onAdClicked() {
|
||||||
|
if (released) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (eventHandler != null && eventListener != null) {
|
if (eventHandler != null && eventListener != null) {
|
||||||
eventHandler.post(new Runnable() {
|
eventHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -381,6 +397,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAdTapped() {
|
public void onAdTapped() {
|
||||||
|
if (released) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (eventHandler != null && eventListener != null) {
|
if (eventHandler != null && eventListener != null) {
|
||||||
eventHandler.post(new Runnable() {
|
eventHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -398,15 +417,18 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
|
||||||
if (released) {
|
if (released) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
playerHandler.post(new Runnable() {
|
Log.w(TAG, "Ad load error", error);
|
||||||
@Override
|
if (eventHandler != null && eventListener != null) {
|
||||||
public void run() {
|
eventHandler.post(
|
||||||
if (released) {
|
new Runnable() {
|
||||||
return;
|
@Override
|
||||||
}
|
public void run() {
|
||||||
AdsMediaSource.this.onLoadError(error);
|
if (!released) {
|
||||||
}
|
eventListener.onAdLoadError(error);
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue