Default SingleSampleMediaSource.treatLoadErrorsAsEndOfStream to true
See original GitHub issue- ExoPlayer version number : 2.12.2 and 2.12.1
- Android version : Android 10 (not OS specific)
- Android device : Not device specific
Steps to reproduce:
- Pass the external subtitle url to media item. Can replace this method in source code with the following method.
I have appended _xyz in the vtt url.
private static List<MediaItem.Subtitle> createSubtitlesFromIntent(
Intent intent, String extrasKeySuffix) {
// if (!intent.hasExtra(SUBTITLE_URI_EXTRA + extrasKeySuffix)) {
// return Collections.emptyList();
// }
String url = "https://storage.googleapis.com/exoplayer-test-media-1_xyz/webvtt/numeric-lines.vtt";
MediaItem.Subtitle subtitleMediaItem = new MediaItem.Subtitle(Uri.parse(url), MimeTypes.TEXT_VTT,"en", C.SELECTION_FLAG_DEFAULT, C.ROLE_FLAG_SUBTITLE, "ENGLISH-ZEE");
return Collections.singletonList(subtitleMediaItem);
}
- Run any content and playback will fail.
Logcat
2021-01-05 19:14:08.615 31453-31570/com.google.android.exoplayer2.demo E/ExoPlayerImplInternal: Playback error
com.google.android.exoplayer2.ExoPlaybackException: Source error
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:554)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:165)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 404
at com.google.android.exoplayer2.ext.cronet.CronetDataSource.open(CronetDataSource.java:486)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:199)
at com.google.android.exoplayer2.upstream.cache.CacheDataSource.openNextSource(CacheDataSource.java:764)
at com.google.android.exoplayer2.upstream.cache.CacheDataSource.open(CacheDataSource.java:579)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
at com.google.android.exoplayer2.source.SingleSampleMediaPeriod$SourceLoadable.load(SingleSampleMediaPeriod.java:428)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:415)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
Some Background
Prior exoplayer 2.12.1, we were passing DefaultLoadErrorHandlingPolicy
and here we were listening to Exception but after 2.12.1 this API does not seem to be working. We tried it but we are not getting any callback.
Following class we have added to listen the callback before 2.12.1 and it was fine. It means if the subtitle does not work, we listen to it and it does not hamper the playback.
public class ExternalTextTrackLoadErrorPolicy extends DefaultLoadErrorHandlingPolicy {
private static final PKLog log = PKLog.get("ExternalTextTrackLoadError");
private ExternalTextTrackLoadErrorPolicy.OnTextTrackLoadErrorListener textTrackLoadErrorListener;
public interface OnTextTrackLoadErrorListener {
void onTextTrackLoadError(PKError currentError);
}
public void setOnTextTrackErrorListener(ExternalTextTrackLoadErrorPolicy.OnTextTrackLoadErrorListener onTextTrackErrorListener) {
this.textTrackLoadErrorListener = onTextTrackErrorListener;
}
//public void onTextTrackLoadError(PKError currentError) {
// textTrackLoadErrorListener.onTextTrackLoadError(currentError);
//} TODO // need to test with vtt errored file
@Override
public long getRetryDelayMsFor(LoadErrorInfo loadErrorInfo) {
if (loadErrorInfo == null) {
return Consts.TIME_UNSET;
}
IOException exception = loadErrorInfo.exception;
Uri pathSegment = getPathSegmentUri(exception);
if (pathSegment == null || !(exception instanceof HttpDataSource.HttpDataSourceException)) {
return super.getRetryDelayMsFor(loadErrorInfo);
}
String lastPathSegment = pathSegment.getLastPathSegment();
if (lastPathSegment != null && (lastPathSegment.endsWith(PKSubtitleFormat.vtt.pathExt) || lastPathSegment.endsWith(PKSubtitleFormat.srt.pathExt))) {
PKError currentError = new PKError(PKPlayerErrorType.SOURCE_ERROR, PKError.Severity.Recoverable, "TextTrack is invalid url=" + pathSegment, exception);
if (textTrackLoadErrorListener != null) {
log.e("Error-Event sent, type = " + PKPlayerErrorType.SOURCE_ERROR);
textTrackLoadErrorListener.onTextTrackLoadError(currentError);
}
return Consts.TIME_UNSET;
} else {
return super.getRetryDelayMsFor(loadErrorInfo);
}
}
private Uri getPathSegmentUri(IOException ioException) {
DataSpec dataSpec = null;
if (ioException instanceof HttpDataSource.InvalidResponseCodeException) {
dataSpec = ((HttpDataSource.InvalidResponseCodeException) ioException).dataSpec;
} else if (ioException instanceof HttpDataSource.HttpDataSourceException) {
dataSpec = ((HttpDataSource.HttpDataSourceException) ioException).dataSpec;
}
if (dataSpec != null) {
return dataSpec.uri;
}
return null;
}
}
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (5 by maintainers)
Top Results From Across the Web
SingleSampleMediaSource.Factory (ExoPlayer library)
The default value is true. Parameters: treatLoadErrorsAsEndOfStream - If true, load errors will not be propagated by sample streams, treating them as ended ......
Read more >SingleSampleMediaSource.Factory - Android Developers
The default value is true. Parameters. treatLoadErrorsAsEndOfStream: Boolean. If true, load errors will not be propagated by sample streams, ...
Read more >SingleSampleMediaSource.Factory - androidx.* javadoc
treatLoadErrorsAsEndOfStream: If true, load errors will not be propagated by sample streams, treating them as ended instead.
Read more >com.google.android.exoplayer2.upstream ...
@Deprecated public SingleSampleMediaSource( Uri uri, DataSource. ... @param treatLoadErrorsAsEndOfStream If true, load errors will not be propagated by ...
Read more >RELEASENOTES.md - google/ExoPlayer - Sourcegraph
Default SingleSampleMediaSource.treatLoadErrorsAsEndOfStream to true so that errors loading external subtitle files do not cause playback to fail (#8430).
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
We plan to handle
treatLoadErrorsAsEndOfStream
in some way (possibly by adding it toMediaItem.Subtitle
, possibly by defaulting to it to true, or possibly by other means).We haven’t made this change yet (hence this issue is still open), so yes it’s not included in 2.12.3 released today.
Thanks for the branch - using that I’m able to reproduce what you’re seeing, and using the debugger I pinned down the problem - you’re right that basically your policy is being accidentally dropped internally. Specifically here, it needs to be propagated down to the
SingleSampleMediaSource.Factory
: https://github.com/google/ExoPlayer/blob/107fed9b2afc1e1edce95eee4a1fbc952377efd2/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java#L253-L254I’ve sent a fix for this - it should be included in 2.12.3 which will be released before the end of the month.
Note that even with this fix, your content doesn’t play in your LoadErrorHandlingPolicy branch - but I think that’s due to the implementation of your policy - the execution does now reach the
getRetryDelayMsFor
method.