diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java index 03953cd00d..47b46413eb 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java @@ -26,6 +26,7 @@ import com.google.android.exoplayer.MediaCodecSelector; import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException; import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; import com.google.android.exoplayer.SampleSource; +import com.google.android.exoplayer.SingleSampleSource; import com.google.android.exoplayer.TimeRange; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.audio.AudioCapabilities; @@ -33,6 +34,7 @@ import com.google.android.exoplayer.audio.AudioTrack; import com.google.android.exoplayer.chunk.ChunkSampleSource; import com.google.android.exoplayer.dash.DashChunkSource; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; +import com.google.android.exoplayer.extractor.ExtractorSampleSource; import com.google.android.exoplayer.hls.HlsSampleSource; import com.google.android.exoplayer.metadata.MetadataTrackRenderer; import com.google.android.exoplayer.metadata.MetadataTrackRenderer.MetadataRenderer; @@ -64,6 +66,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.EventListener, ChunkSampleSource.EventListener, HlsSampleSource.EventListener, + ExtractorSampleSource.EventListener, SingleSampleSource.EventListener, DefaultBandwidthMeter.EventListener, MediaCodecVideoTrackRenderer.EventListener, MediaCodecAudioTrackRenderer.EventListener, StreamingDrmSessionManager.EventListener, DashChunkSource.EventListener, TextRenderer, MetadataRenderer>, diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorSourceBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorSourceBuilder.java index ccc7a45407..03e2dcf7e9 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorSourceBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorSourceBuilder.java @@ -51,7 +51,7 @@ public class ExtractorSourceBuilder implements SourceBuilder { DataSource dataSource = new DefaultUriDataSource(context, player.getBandwidthMeter(), userAgent); return new ExtractorSampleSource(uri, dataSource, allocator, - BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE); + BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, player.getMainHandler(), player, 0); } } diff --git a/library/src/main/java/com/google/android/exoplayer/SingleSampleSource.java b/library/src/main/java/com/google/android/exoplayer/SingleSampleSource.java index 83eb9934e5..e09035bf2c 100644 --- a/library/src/main/java/com/google/android/exoplayer/SingleSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/SingleSampleSource.java @@ -22,6 +22,7 @@ import com.google.android.exoplayer.upstream.Loader.Loadable; import com.google.android.exoplayer.util.Assertions; import android.net.Uri; +import android.os.Handler; import android.os.SystemClock; import java.io.IOException; @@ -33,6 +34,21 @@ import java.util.Arrays; public final class SingleSampleSource implements SampleSource, TrackStream, Loader.Callback, Loadable { + /** + * Interface definition for a callback to be notified of {@link SingleSampleSource} events. + */ + public interface EventListener { + + /** + * Invoked when an error occurs loading media data. + * + * @param sourceId The id of the reporting {@link SampleSource}. + * @param e The cause of the failure. + */ + void onLoadError(int sourceId, IOException e); + + } + /** * The default minimum number of times to retry loading data prior to failing. */ @@ -53,6 +69,9 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load private final long durationUs; private final int minLoadableRetryCount; private final TrackGroupArray tracks; + private final Handler eventHandler; + private final EventListener eventListener; + private final int eventSourceId; private int state; private byte[] sampleData; @@ -71,11 +90,20 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load public SingleSampleSource(Uri uri, DataSource dataSource, Format format, long durationUs, int minLoadableRetryCount) { + this(uri, dataSource, format, durationUs, minLoadableRetryCount, null, null, 0); + } + + public SingleSampleSource(Uri uri, DataSource dataSource, Format format, long durationUs, + int minLoadableRetryCount, Handler eventHandler, EventListener eventListener, + int eventSourceId) { this.uri = uri; this.dataSource = dataSource; this.format = format; this.durationUs = durationUs; this.minLoadableRetryCount = minLoadableRetryCount; + this.eventHandler = eventHandler; + this.eventListener = eventListener; + this.eventSourceId = eventSourceId; tracks = new TrackGroupArray(new TrackGroup(format)); sampleData = new byte[INITIAL_SAMPLE_SIZE]; } @@ -224,6 +252,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load currentLoadableException = e; currentLoadableExceptionCount++; currentLoadableExceptionTimestamp = SystemClock.elapsedRealtime(); + notifyLoadError(e); maybeStartLoading(); } @@ -260,4 +289,15 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load } } + private void notifyLoadError(final IOException e) { + if (eventHandler != null && eventListener != null) { + eventHandler.post(new Runnable() { + @Override + public void run() { + eventListener.onLoadError(eventSourceId, e); + } + }); + } + } + }