Improve sniffer error reporting.

- Make UnrecognizedInputFormatException public so the app can more easily handle
  it when it is propagated to onPlayerError.
- Format the description using the simple class names for the extractors.
- Don't retry loading after it's thrown, but just throw immediately.
This commit is contained in:
Oliver Woodman 2015-07-23 13:14:06 +01:00
parent 4c1fb0c977
commit b44de0d250
2 changed files with 43 additions and 15 deletions

View File

@ -32,6 +32,7 @@ import com.google.android.exoplayer.upstream.DefaultAllocator;
import com.google.android.exoplayer.upstream.Loader;
import com.google.android.exoplayer.upstream.Loader.Loadable;
import com.google.android.exoplayer.util.Assertions;
import com.google.android.exoplayer.util.Util;
import android.net.Uri;
import android.os.SystemClock;
@ -40,7 +41,6 @@ import android.util.SparseArray;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@ -70,6 +70,18 @@ import java.util.List;
public class ExtractorSampleSource implements SampleSource, SampleSourceReader, ExtractorOutput,
Loader.Callback {
/**
* Thrown if the input format could not recognized.
*/
public static final class UnrecognizedInputFormatException extends ParserException {
public UnrecognizedInputFormatException(Extractor[] extractors) {
super("None of the available extractors ("
+ Util.getCommaDelimitedSimpleClassNames(extractors) + ") could read the stream.");
}
}
/**
* The default minimum number of times to retry loading prior to failing for on-demand streams.
*/
@ -401,6 +413,9 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
if (currentLoadableException == null) {
return;
}
if (isCurrentLoadableExceptionFatal()) {
throw currentLoadableException;
}
int minLoadableRetryCountForMedia;
if (minLoadableRetryCount != MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA) {
minLoadableRetryCountForMedia = minLoadableRetryCount;
@ -545,6 +560,9 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
}
if (currentLoadableException != null) {
if (isCurrentLoadableExceptionFatal()) {
return;
}
Assertions.checkState(loadable != null);
long elapsedMillis = SystemClock.elapsedRealtime() - currentLoadableExceptionTimestamp;
if (elapsedMillis >= getRetryDelayMillis(currentLoadableExceptionCount)) {
@ -642,6 +660,10 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
return pendingResetPositionUs != NO_RESET_PENDING;
}
private boolean isCurrentLoadableExceptionFatal() {
return currentLoadableException instanceof UnrecognizedInputFormatException;
}
private long getRetryDelayMillis(long errorCount) {
return Math.min((errorCount - 1) * 1000, 5000);
}
@ -791,15 +813,4 @@ public class ExtractorSampleSource implements SampleSource, SampleSourceReader,
}
/**
* Thrown if the input format could not recognized by {@link Extractor#sniff(ExtractorInput)}.
*/
private static final class UnrecognizedInputFormatException extends ParserException {
public UnrecognizedInputFormatException(Extractor[] extractors) {
super("None of the extractors " + Arrays.toString(extractors) + " could read the stream.");
}
}
}

View File

@ -577,11 +577,28 @@ public final class Util {
* @return A string containing the hex representation of the data provided.
*/
public static String getHexStringFromBytes(byte[] data, int beginIndex, int endIndex) {
StringBuffer dataStringBuffer = new StringBuffer(endIndex - beginIndex);
StringBuilder dataStringBuilder = new StringBuilder(endIndex - beginIndex);
for (int i = beginIndex; i < endIndex; i++) {
dataStringBuffer.append(String.format(Locale.US, "%02X", data[i]));
dataStringBuilder.append(String.format(Locale.US, "%02X", data[i]));
}
return dataStringBuffer.toString();
return dataStringBuilder.toString();
}
/**
* Returns a string with comma delimited simple names of each object's class.
*
* @param objects The objects whose simple class names should be comma delimited and returned.
* @return A string with comma delimited simple names of each object's class.
*/
public static <T> String getCommaDelimitedSimpleClassNames(T[] objects) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < objects.length; i++) {
stringBuilder.append(objects[i].getClass().getSimpleName());
if (i < objects.length - 1) {
stringBuilder.append(", ");
}
}
return stringBuilder.toString();
}
/**