mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Allow configuration of the Loader retry delay
Issue:#3370 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=201996109
This commit is contained in:
parent
eb8c686243
commit
a1f89bec0d
@ -13,6 +13,9 @@
|
||||
([#3972](https://github.com/google/ExoPlayer/issues/3972)).
|
||||
* Pass `BandwidthMeter` to `TrackSelection.Factory` which can be used to obtain
|
||||
bandwidth estimates in the future. Always null at the moment.
|
||||
* Error handling:
|
||||
* Allow configuration of the Loader retry delay
|
||||
([#3370](https://github.com/google/ExoPlayer/issues/3370)).
|
||||
* HLS:
|
||||
* Allow injection of custom playlist trackers.
|
||||
* Pass HTTP response headers to `HlsExtractorFactory.createExtractor`.
|
||||
|
@ -38,6 +38,7 @@ import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.upstream.Loader.Loadable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
@ -532,7 +533,7 @@ import java.util.Arrays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
ExtractingLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
|
||||
boolean isErrorFatal = isLoadableExceptionFatal(error);
|
||||
eventDispatcher.loadError(
|
||||
|
@ -25,6 +25,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.upstream.Loader.Loadable;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -228,7 +229,7 @@ import java.util.Arrays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
|
||||
errorCount++;
|
||||
boolean cancel = treatLoadErrorsAsEndOfStream && errorCount >= minLoadableRetryCount;
|
||||
|
@ -28,6 +28,7 @@ import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.source.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
@ -409,7 +410,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
|
||||
long bytesLoaded = loadable.bytesLoaded();
|
||||
boolean isMediaChunk = isMediaChunk(loadable);
|
||||
|
@ -23,6 +23,7 @@ import android.os.SystemClock;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.TraceUtil;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -110,12 +111,12 @@ public final class Loader implements LoaderErrorThrower {
|
||||
* @param elapsedRealtimeMs {@link SystemClock#elapsedRealtime} when the error occurred.
|
||||
* @param loadDurationMs The duration of the load up to the point at which the error occurred.
|
||||
* @param error The load error.
|
||||
* @return The desired retry action. One of {@link Loader#RETRY}, {@link
|
||||
* Loader#RETRY_RESET_ERROR_COUNT}, {@link Loader#DONT_RETRY} and {@link
|
||||
* Loader#DONT_RETRY_FATAL}.
|
||||
* @return The desired error handling action. One of {@link Loader#RETRY}, {@link
|
||||
* Loader#RETRY_RESET_ERROR_COUNT}, {@link Loader#DONT_RETRY}, {@link
|
||||
* Loader#DONT_RETRY_FATAL} or a retry action created by {@link #createRetryAction}.
|
||||
*/
|
||||
@RetryAction
|
||||
int onLoadError(T loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error);
|
||||
LoadErrorAction onLoadError(
|
||||
T loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,15 +131,51 @@ public final class Loader implements LoaderErrorThrower {
|
||||
|
||||
}
|
||||
|
||||
/** Actions that can be taken in response to a load error. */
|
||||
/** Types of action that can be taken in response to a load error. */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({RETRY, RETRY_RESET_ERROR_COUNT, DONT_RETRY, DONT_RETRY_FATAL})
|
||||
public @interface RetryAction {}
|
||||
@IntDef({
|
||||
ACTION_TYPE_RETRY,
|
||||
ACTION_TYPE_RETRY_AND_RESET_ERROR_COUNT,
|
||||
ACTION_TYPE_DONT_RETRY,
|
||||
ACTION_TYPE_DONT_RETRY_FATAL
|
||||
})
|
||||
private @interface RetryActionType {}
|
||||
|
||||
public static final int RETRY = 0;
|
||||
public static final int RETRY_RESET_ERROR_COUNT = 1;
|
||||
public static final int DONT_RETRY = 2;
|
||||
public static final int DONT_RETRY_FATAL = 3;
|
||||
private static final int ACTION_TYPE_RETRY = 0;
|
||||
private static final int ACTION_TYPE_RETRY_AND_RESET_ERROR_COUNT = 1;
|
||||
private static final int ACTION_TYPE_DONT_RETRY = 2;
|
||||
private static final int ACTION_TYPE_DONT_RETRY_FATAL = 3;
|
||||
|
||||
/** Retries the load using the default delay. */
|
||||
public static final LoadErrorAction RETRY =
|
||||
createRetryAction(/* resetErrorCount= */ false, C.TIME_UNSET);
|
||||
/** Retries the load using the default delay and resets the error count. */
|
||||
public static final LoadErrorAction RETRY_RESET_ERROR_COUNT =
|
||||
createRetryAction(/* resetErrorCount= */ true, C.TIME_UNSET);
|
||||
/** Discards the failed loading task and ignores any errors that have occurred. */
|
||||
public static final LoadErrorAction DONT_RETRY =
|
||||
new LoadErrorAction(ACTION_TYPE_DONT_RETRY, C.TIME_UNSET);
|
||||
/**
|
||||
* Discards the failed load. The next call to {@link #maybeThrowError()} will throw the last load
|
||||
* error.
|
||||
*/
|
||||
public static final LoadErrorAction DONT_RETRY_FATAL =
|
||||
new LoadErrorAction(ACTION_TYPE_DONT_RETRY_FATAL, C.TIME_UNSET);
|
||||
|
||||
/**
|
||||
* Action that can be taken in response to {@link Callback#onLoadError(Loadable, long, long,
|
||||
* IOException)}.
|
||||
*/
|
||||
public static final class LoadErrorAction {
|
||||
|
||||
private final @RetryActionType int type;
|
||||
private final long retryDelayMillis;
|
||||
|
||||
private LoadErrorAction(@RetryActionType int type, long retryDelayMillis) {
|
||||
this.type = type;
|
||||
this.retryDelayMillis = retryDelayMillis;
|
||||
}
|
||||
}
|
||||
|
||||
private final ExecutorService downloadExecutorService;
|
||||
|
||||
@ -152,6 +189,19 @@ public final class Loader implements LoaderErrorThrower {
|
||||
this.downloadExecutorService = Util.newSingleThreadExecutor(threadName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link LoadErrorAction} for retrying with the given parameters.
|
||||
*
|
||||
* @param resetErrorCount Whether the previous error count should be set to zero.
|
||||
* @param retryDelayMillis The number of milliseconds to wait before retrying.
|
||||
* @return A {@link LoadErrorAction} for retrying with the given parameters.
|
||||
*/
|
||||
public static LoadErrorAction createRetryAction(boolean resetErrorCount, long retryDelayMillis) {
|
||||
return new LoadErrorAction(
|
||||
resetErrorCount ? ACTION_TYPE_RETRY_AND_RESET_ERROR_COUNT : ACTION_TYPE_RETRY,
|
||||
retryDelayMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts loading a {@link Loadable}.
|
||||
*
|
||||
@ -395,12 +445,16 @@ public final class Loader implements LoaderErrorThrower {
|
||||
break;
|
||||
case MSG_IO_EXCEPTION:
|
||||
currentError = (IOException) msg.obj;
|
||||
int retryAction = callback.onLoadError(loadable, nowMs, durationMs, currentError);
|
||||
if (retryAction == DONT_RETRY_FATAL) {
|
||||
LoadErrorAction action = callback.onLoadError(loadable, nowMs, durationMs, currentError);
|
||||
if (action.type == ACTION_TYPE_DONT_RETRY_FATAL) {
|
||||
fatalError = currentError;
|
||||
} else if (retryAction != DONT_RETRY) {
|
||||
errorCount = retryAction == RETRY_RESET_ERROR_COUNT ? 1 : errorCount + 1;
|
||||
start(getRetryDelayMillis());
|
||||
} else if (action.type != ACTION_TYPE_DONT_RETRY) {
|
||||
errorCount =
|
||||
action.type == ACTION_TYPE_RETRY_AND_RESET_ERROR_COUNT ? 1 : errorCount + 1;
|
||||
start(
|
||||
action.retryDelayMillis != C.TIME_UNSET
|
||||
? action.retryDelayMillis
|
||||
: getRetryDelayMillis());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -43,6 +43,7 @@ import com.google.android.exoplayer2.source.dash.manifest.UtcTimingElement;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
@ -716,8 +717,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ @Loader.RetryAction
|
||||
int onManifestLoadError(
|
||||
/* package */ LoadErrorAction onManifestLoadError(
|
||||
ParsingLoadable<DashManifest> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
@ -745,8 +745,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
onUtcTimestampResolved(loadable.getResult() - elapsedRealtimeMs);
|
||||
}
|
||||
|
||||
/* package */ @Loader.RetryAction
|
||||
int onUtcTimestampLoadError(
|
||||
/* package */ LoadErrorAction onUtcTimestampLoadError(
|
||||
ParsingLoadable<Long> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
@ -1172,7 +1171,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
ParsingLoadable<DashManifest> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
@ -1197,7 +1196,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
ParsingLoadable<Long> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
|
@ -40,6 +40,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -602,7 +603,7 @@ import java.util.Arrays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
|
||||
long bytesLoaded = loadable.bytesLoaded();
|
||||
boolean isMediaChunk = isMediaChunk(loadable);
|
||||
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.UriUtil;
|
||||
@ -229,7 +230,7 @@ public final class DefaultHlsPlaylistTracker
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
ParsingLoadable<HlsPlaylist> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
@ -485,7 +486,7 @@ public final class DefaultHlsPlaylistTracker
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
ParsingLoadable<HlsPlaylist> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
|
@ -41,6 +41,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
@ -540,7 +541,7 @@ public final class SsMediaSource extends BaseMediaSource
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Loader.RetryAction int onLoadError(
|
||||
public LoadErrorAction onLoadError(
|
||||
ParsingLoadable<SsManifest> loadable,
|
||||
long elapsedRealtimeMs,
|
||||
long loadDurationMs,
|
||||
|
Loading…
x
Reference in New Issue
Block a user