diff --git a/demo/src/main/assets/sample_media.exolist.json b/demo/src/main/assets/sample_media.exolist.json index 4d2a7fdfda..eb0ea01b90 100644 --- a/demo/src/main/assets/sample_media.exolist.json +++ b/demo/src/main/assets/sample_media.exolist.json @@ -5,22 +5,22 @@ { "name": "Google Glass (MP4,H264)", "uri": "http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0", - "type": "dash" + "extension": "mpd" }, { "name": "Google Play (MP4,H264)", "uri": "http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=A2716F75795F5D2AF0E88962FFCD10DB79384F29.84308FF04844498CE6FBCE4731507882B8307798&key=ik0", - "type": "dash" + "extension": "mpd" }, { "name": "Google Glass (WebM,VP9)", "uri": "http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,webm2_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=249B04F79E984D7F86B4D8DB48AE6FAF41C17AB3.7B9F0EC0505E1566E59B8E488E9419F253DDF413&key=ik0", - "type": "dash" + "extension": "mpd" }, { "name": "Google Play (WebM,VP9)", "uri": "http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?as=fmp4_audio_clear,webm2_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=B1C2A74783AC1CC4865EB312D7DD2D48230CC9FD.BD153B9882175F1F94BFE5141A5482313EA38E8D&key=ik0", - "type": "dash" + "extension": "mpd" } ] }, @@ -30,49 +30,41 @@ { "name": "WV: HDCP not specified", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:d286538032258a1c:widevine_test" }, { "name": "WV: HDCP not required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:48fcc369939ac96c:widevine_test" }, { "name": "WV: HDCP required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:e06c39f1151da3df:widevine_test" }, { "name": "WV: Secure video path required (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:0894c7c8719b28a0:widevine_test" }, { "name": "WV: Secure video path required (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd", - "type": "dash", "drm": "widevine:0894c7c8719b28a0:widevine_test" }, { "name": "WV: Secure video path required (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears.mpd", - "type": "dash", "drm": "widevine:0894c7c8719b28a0:widevine_test" }, { "name": "WV: HDCP + secure video path required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:efd045b1eb61888a:widevine_test" }, { "name": "WV: 30s license duration (fails at ~30s)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:f9a34cab7b05881a:widevine_test" } ] @@ -83,37 +75,31 @@ { "name": "WV: HDCP: None (not required)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:HDCP_None:widevine_test" }, { "name": "WV: HDCP: 1.0 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:HDCP_V1:widevine_test" }, { "name": "WV: HDCP: 2.0 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:HDCP_V2:widevine_test" }, { "name": "WV: HDCP: 2.1 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:HDCP_V2_1:widevine_test" }, { "name": "WV: HDCP: 2.2 required", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:HDCP_V2_2:widevine_test" }, { "name": "WV: HDCP: No digital output", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine:HDCP_NO_DIGTAL_OUTPUT:widevine_test" } ] @@ -123,46 +109,38 @@ "samples": [ { "name": "WV: Clear SD & HD (MP4,H264)", - "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd" }, { "name": "WV: Clear SD (MP4,H264)", - "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_sd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_sd.mpd" }, { "name": "WV: Clear HD (MP4,H264)", - "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_hd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_hd.mpd" }, { "name": "WV: Clear UHD (MP4,H264)", - "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_uhd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_uhd.mpd" }, { "name": "WV: Secure SD & HD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure SD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure HD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_hd.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure UHD (MP4,H264)", "uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_uhd.mpd", - "type": "dash", "drm": "widevine::widevine_test" } ] @@ -172,46 +150,38 @@ "samples": [ { "name": "WV: Clear SD & HD (WebM,VP9)", - "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears.mpd" }, { "name": "WV: Clear SD (WebM,VP9)", - "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_sd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_sd.mpd" }, { "name": "WV: Clear HD (WebM,VP9)", - "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_hd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_hd.mpd" }, { "name": "WV: Clear UHD (WebM,VP9)", - "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_uhd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/vp9/tears/tears_uhd.mpd" }, { "name": "WV: Secure SD & HD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure SD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_sd.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure HD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_hd.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure UHD (WebM,VP9)", "uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_uhd.mpd", - "type": "dash", "drm": "widevine::widevine_test" } ] @@ -221,46 +191,38 @@ "samples": [ { "name": "WV: Clear SD & HD (MP4,H265)", - "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears.mpd" }, { "name": "WV: Clear SD (MP4,H265)", - "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears_sd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears_sd.mpd" }, { "name": "WV: Clear HD (MP4,H265)", - "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears_hd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears_hd.mpd" }, { "name": "WV: Clear UHD (MP4,H265)", - "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears_uhd.mpd", - "type": "dash" + "uri": "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears_uhd.mpd" }, { "name": "WV: Secure SD & HD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure SD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_sd.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure HD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_hd.mpd", - "type": "dash", "drm": "widevine::widevine_test" }, { "name": "WV: Secure UHD (MP4,H265)", "uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_uhd.mpd", - "type": "dash", "drm": "widevine::widevine_test" } ] @@ -270,13 +232,11 @@ "samples": [ { "name": "Super speed", - "uri": "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism", - "type": "smoothstreaming" + "uri": "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism" }, { "name": "Super speed (PlayReady)", "uri": "http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism", - "type": "smoothstreaming", "drm": "playready::" } ] @@ -286,28 +246,23 @@ "samples": [ { "name": "Apple master playlist", - "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8", - "type": "hls" + "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8" }, { "name": "Apple master playlist advanced", - "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8", - "type": "hls" + "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8" }, { "name": "Apple TS media playlist", - "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8", - "type": "hls" + "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8" }, { "name": "Apple AAC media playlist", - "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear0/prog_index.m3u8", - "type": "hls" + "uri": "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear0/prog_index.m3u8" }, { "name": "Apple ID3 metadata", - "uri": "http://devimages.apple.com/samplecode/adDemo/ad.m3u8", - "type": "hls" + "uri": "http://devimages.apple.com/samplecode/adDemo/ad.m3u8" } ] }, @@ -368,8 +323,7 @@ }, { "name": "Google Glass DASH - VP9 and Opus", - "uri": "http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9_opus.mpd", - "type": "dash" + "uri": "http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9_opus.mpd" }, { "name": "Big Buck Bunny (FLV Video)", diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java index 18708a96e0..6bfa6d13cb 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer.demo; import com.google.android.exoplayer.AspectRatioFrameLayout; import com.google.android.exoplayer.C; +import com.google.android.exoplayer.ConcatenatingSampleSourceProvider; import com.google.android.exoplayer.DefaultBufferingPolicy; import com.google.android.exoplayer.DefaultTrackSelectionPolicy; import com.google.android.exoplayer.DefaultTrackSelector; @@ -26,6 +27,7 @@ import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.ExoPlayerFactory; import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException; import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException; +import com.google.android.exoplayer.SampleSourceProvider; import com.google.android.exoplayer.SimpleExoPlayer; import com.google.android.exoplayer.TrackGroupArray; import com.google.android.exoplayer.drm.DrmSessionManager; @@ -85,19 +87,15 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, ExoPlayer.EventListener, SimpleExoPlayer.VideoListener, SimpleExoPlayer.CaptionListener, SimpleExoPlayer.Id3MetadataListener, DefaultTrackSelector.EventListener { - // For use within demo app code. - public static final String CONTENT_TYPE_EXTRA = "content_type"; + public static final String URIS_LIST_EXTRA = "uris"; + public static final String CONTENT_EXT_EXTRA = "extension"; public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid"; public static final String DRM_CONTENT_ID_EXTRA = "drm_content_id"; public static final String DRM_PROVIDER_EXTRA = "drm_provider"; public static final String PREFER_EXTENSION_DECODERS = "prefer_extension_decoders"; - - // For use when launching the demo app using adb. public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW"; - private static final String ACTION_VIEW_LIST = + public static final String ACTION_VIEW_LIST = "com.google.android.exoplayer.demo.action.VIEW_LIST"; - private static final String CONTENT_EXT_EXTRA = "type"; - private static final String URIS_LIST_EXTRA = "uris"; private static final String TAG = "PlayerActivity"; @@ -287,20 +285,14 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, if (playerNeedsSource) { String action = intent.getAction(); Uri[] uris; - UriSampleSourceProvider sourceProvider; if (ACTION_VIEW.equals(action)) { uris = new Uri[] {intent.getData()}; - sourceProvider = new UriSampleSourceProvider(player, dataSourceFactory, intent.getData(), - intent.getIntExtra(CONTENT_TYPE_EXTRA, UriSampleSourceProvider.UNKNOWN_TYPE), - intent.getStringExtra(CONTENT_EXT_EXTRA), mainHandler, eventLogger); } else if (ACTION_VIEW_LIST.equals(action)) { String[] uriStrings = intent.getStringArrayExtra(URIS_LIST_EXTRA); uris = new Uri[uriStrings.length]; for (int i = 0; i < uriStrings.length; i++) { uris[i] = Uri.parse(uriStrings[i]); } - sourceProvider = new UriSampleSourceProvider(player, dataSourceFactory, uris, mainHandler, - eventLogger); } else { Log.w(TAG, "Unexpected intent action: " + action); return; @@ -309,6 +301,14 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback, // The player will be reinitialized if permission is granted. return; } + + UriSampleSourceProvider[] providers = new UriSampleSourceProvider[uris.length]; + for (int i = 0; i < uris.length; i++) { + providers[i] = new UriSampleSourceProvider(player.getBandwidthMeter(), dataSourceFactory, + uris[i], intent.getStringExtra(CONTENT_EXT_EXTRA), mainHandler, eventLogger); + } + SampleSourceProvider sourceProvider = providers.length == 1 ? providers[0] + : new ConcatenatingSampleSourceProvider(providers); player.setSourceProvider(sourceProvider); playerNeedsSource = false; updateButtonVisibilities(); diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/SampleChooserActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/SampleChooserActivity.java index 904dd23954..bcfafd9d64 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/SampleChooserActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/SampleChooserActivity.java @@ -93,7 +93,7 @@ public class SampleChooserActivity extends Activity { Intent intent = new Intent(this, PlayerActivity.class) .setAction(PlayerActivity.ACTION_VIEW) .setData(Uri.parse(sample.uri)) - .putExtra(PlayerActivity.CONTENT_TYPE_EXTRA, sample.type) + .putExtra(PlayerActivity.CONTENT_EXT_EXTRA, sample.extension) .putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, sample.drmSchemeUuid) .putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, sample.drmContentId) .putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, sample.drmProvider) @@ -167,7 +167,7 @@ public class SampleChooserActivity extends Activity { private Sample readSample(JsonReader reader) throws IOException { String sampleName = null; String uri = null; - int type = Util.TYPE_OTHER; + String extension = null; UUID drmUuid = null; String drmContentId = null; String drmProvider = null; @@ -182,8 +182,8 @@ public class SampleChooserActivity extends Activity { case "uri": uri = reader.nextString(); break; - case "type": - type = getType(reader.nextString()); + case "extension": + extension = reader.nextString(); break; case "drm": String[] drmComponents = reader.nextString().split(":", -1); @@ -201,7 +201,7 @@ public class SampleChooserActivity extends Activity { if (sampleName == null || uri == null) { throw new ParserException("Invalid sample (name or uri missing)"); } - return new Sample(sampleName, uri, type, drmUuid, drmContentId, drmProvider, + return new Sample(sampleName, uri, extension, drmUuid, drmContentId, drmProvider, preferExtensionDecoders); } @@ -227,22 +227,6 @@ public class SampleChooserActivity extends Activity { } } - private int getType(String typeString) { - if (typeString == null) { - return Util.TYPE_OTHER; - } - switch (typeString.toLowerCase()) { - case "dash": - return Util.TYPE_DASH; - case "smoothstreaming": - return Util.TYPE_SS; - case "hls": - return Util.TYPE_HLS; - default: - return Util.TYPE_OTHER; - } - } - } private static final class SampleAdapter extends BaseExpandableListAdapter { @@ -337,17 +321,17 @@ public class SampleChooserActivity extends Activity { public final String name; public final String uri; - public final int type; + public final String extension; public final UUID drmSchemeUuid; public final String drmContentId; public final String drmProvider; public final boolean preferExtensionDecoders; - public Sample(String name, String uri, int type, UUID drmSchemeUuid, String drmContentId, - String drmProvider, boolean preferExtensionDecoders) { + public Sample(String name, String uri, String extension, UUID drmSchemeUuid, + String drmContentId, String drmProvider, boolean preferExtensionDecoders) { this.name = name; this.uri = uri; - this.type = type; + this.extension = extension; this.drmSchemeUuid = drmSchemeUuid; this.drmContentId = drmContentId; this.drmProvider = drmProvider; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/UriSampleSourceProvider.java b/demo/src/main/java/com/google/android/exoplayer/demo/UriSampleSourceProvider.java index 9b99404383..07af26bd68 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/UriSampleSourceProvider.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/UriSampleSourceProvider.java @@ -17,11 +17,11 @@ package com.google.android.exoplayer.demo; import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.SampleSourceProvider; -import com.google.android.exoplayer.SimpleExoPlayer; import com.google.android.exoplayer.dash.DashSampleSource; import com.google.android.exoplayer.extractor.ExtractorSampleSource; import com.google.android.exoplayer.hls.HlsSampleSource; import com.google.android.exoplayer.smoothstreaming.SmoothStreamingSampleSource; +import com.google.android.exoplayer.upstream.BandwidthMeter; import com.google.android.exoplayer.upstream.DataSourceFactory; import com.google.android.exoplayer.util.Util; @@ -30,17 +30,14 @@ import android.os.Handler; import android.text.TextUtils; /** - * Provides {@link SampleSource}s to play back media loaded from one or more URI/URIs. + * Provides a {@link SampleSource} to play back media loaded from a {@link Uri}. */ public final class UriSampleSourceProvider implements SampleSourceProvider { - public static final int UNKNOWN_TYPE = -1; - - private final SimpleExoPlayer player; + private final BandwidthMeter bandwidthMeter; private final DataSourceFactory dataSourceFactory; - private final Uri[] uris; + private final Uri uri; private final String overrideExtension; - private final int type; private final Handler handler; private final EventLogger eventLogger; @@ -48,71 +45,42 @@ public final class UriSampleSourceProvider implements SampleSourceProvider { * Constructs a source provider for {@link SampleSource} to play back media at the specified * URI, using the specified type. * - * @param player The demo player, which will listen to source events. + * @param bandwidthMeter A bandwidth meter. * @param dataSourceFactory A data source factory. * @param uri The URI to play back. - * @param type A {@code PlayerActivity.TYPE_*} constant specifying the type of the source, or - * {@link #UNKNOWN_TYPE}, in which case it is inferred from the URI's extension. * @param overrideExtension An overriding file extension used when inferring the source's type, * or {@code null}. * @param handler A handler to use for logging events. * @param eventLogger An event logger. */ - public UriSampleSourceProvider(SimpleExoPlayer player, DataSourceFactory dataSourceFactory, - Uri uri, int type, String overrideExtension, Handler handler, EventLogger eventLogger) { - this.player = player; + public UriSampleSourceProvider(BandwidthMeter bandwidthMeter, DataSourceFactory dataSourceFactory, + Uri uri, String overrideExtension, Handler handler, EventLogger eventLogger) { + this.bandwidthMeter = bandwidthMeter; this.dataSourceFactory = dataSourceFactory; + this.uri = uri; this.overrideExtension = overrideExtension; - this.type = type; this.handler = handler; this.eventLogger = eventLogger; - - uris = new Uri[] {uri}; - } - - /** - * Constructs a source provider for {@link SampleSource}s to play back media at one or more - * {@link Uri}s. The content type of each URI is inferred based on its last path segment. - * - * @param player The demo player, which will listen to source events. - * @param dataSourceFactory A data source factory. - * @param uris The URIs to play back. - * @param handler A handler to use for logging events. - * @param eventLogger An event logger. - */ - public UriSampleSourceProvider(SimpleExoPlayer player, DataSourceFactory dataSourceFactory, - Uri[] uris, Handler handler, EventLogger eventLogger) { - this.player = player; - this.dataSourceFactory = dataSourceFactory; - this.uris = uris; - this.handler = handler; - this.eventLogger = eventLogger; - - overrideExtension = null; - type = UNKNOWN_TYPE; } @Override public int getSourceCount() { - return uris.length; + return 1; } @Override public SampleSource createSource(int index) { - Uri uri = uris[index]; - int type = this.type == UNKNOWN_TYPE ? inferContentType(uri, overrideExtension) : this.type; + int type = inferContentType(uri, overrideExtension); switch (type) { case Util.TYPE_SS: - return new SmoothStreamingSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), - handler, eventLogger); + return new SmoothStreamingSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, + eventLogger); case Util.TYPE_DASH: - return new DashSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), handler, - eventLogger); + return new DashSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, eventLogger); case Util.TYPE_HLS: - return new HlsSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), handler, - eventLogger); + return new HlsSampleSource(uri, dataSourceFactory, bandwidthMeter, handler, eventLogger); case Util.TYPE_OTHER: - return new ExtractorSampleSource(uri, dataSourceFactory, player.getBandwidthMeter(), + return new ExtractorSampleSource(uri, dataSourceFactory, bandwidthMeter, ExtractorSampleSource.newDefaultExtractors(), handler, eventLogger); default: throw new IllegalStateException("Unsupported type: " + type); diff --git a/library/src/main/java/com/google/android/exoplayer/ConcatenatingSampleSourceProvider.java b/library/src/main/java/com/google/android/exoplayer/ConcatenatingSampleSourceProvider.java new file mode 100644 index 0000000000..8a39b80e5b --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/ConcatenatingSampleSourceProvider.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer; + +/** + * A {@link SampleSourceProvider} that concatenates multiple {@link SampleSourceProvider}s. + */ +public final class ConcatenatingSampleSourceProvider implements SampleSourceProvider { + + private final SampleSourceProvider[] sampleSourceProviders; + + /** + * @param sampleSourcePoviders The {@link SampleSourceProvider}s to concatenate. + */ + public ConcatenatingSampleSourceProvider(SampleSourceProvider... sampleSourcePoviders) { + this.sampleSourceProviders = sampleSourcePoviders; + } + + @Override + public int getSourceCount() { + int sourceCount = 0; + for (SampleSourceProvider sampleSourceProvider : sampleSourceProviders) { + int count = sampleSourceProvider.getSourceCount(); + if (count == SampleSourceProvider.UNKNOWN_SOURCE_COUNT) { + return UNKNOWN_SOURCE_COUNT; + } + sourceCount += count; + } + return sourceCount; + } + + @Override + public SampleSource createSource(int index) { + int sourceCount = 0; + for (SampleSourceProvider sampleSourceProvider : sampleSourceProviders) { + int count = sampleSourceProvider.getSourceCount(); + if (count == SampleSourceProvider.UNKNOWN_SOURCE_COUNT || index < sourceCount + count) { + return sampleSourceProvider.createSource(index - sourceCount); + } + sourceCount += count; + } + throw new IndexOutOfBoundsException(); + } + +}