Support playlists in exolist.json.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=126622342
This commit is contained in:
olly 2016-07-05 03:34:02 -07:00 committed by Oliver Woodman
parent 9f017d71ef
commit f0f25aef83
3 changed files with 135 additions and 29 deletions

View file

@ -330,5 +330,32 @@
"uri": "http://vod.leasewebcdn.com/bbb.flv?ri=1024&rs=150&start=0"
}
]
},
{
"name": "Playlists",
"samples": [
{
"name": "Cats and dogs",
"playlist": [
{
"uri": "http://html5demos.com/assets/dizzy.mp4"
},
{
"uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv"
}
]
},
{
"name": "Audio then Video",
"playlist": [
{
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4"
},
{
"uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv"
}
]
}
]
}
]

View file

@ -87,15 +87,18 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
ExoPlayer.EventListener, SimpleExoPlayer.VideoListener, SimpleExoPlayer.CaptionListener,
SimpleExoPlayer.Id3MetadataListener, DefaultTrackSelector.EventListener {
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";
public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW";
public static final String EXTENSION_EXTRA = "extension";
public static final String ACTION_VIEW_LIST =
"com.google.android.exoplayer.demo.action.VIEW_LIST";
public static final String URI_LIST_EXTRA = "uri_list";
public static final String EXTENSION_LIST_EXTRA = "extension_list";
private static final String TAG = "PlayerActivity";
@ -285,14 +288,20 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
if (playerNeedsSource) {
String action = intent.getAction();
Uri[] uris;
String[] extensions;
if (ACTION_VIEW.equals(action)) {
uris = new Uri[] {intent.getData()};
extensions = new String[] {intent.getStringExtra(EXTENSION_EXTRA)};
} else if (ACTION_VIEW_LIST.equals(action)) {
String[] uriStrings = intent.getStringArrayExtra(URIS_LIST_EXTRA);
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
uris = new Uri[uriStrings.length];
for (int i = 0; i < uriStrings.length; i++) {
uris[i] = Uri.parse(uriStrings[i]);
}
extensions = intent.getStringArrayExtra(EXTENSION_LIST_EXTRA);
if (extensions == null) {
extensions = new String[uriStrings.length];
}
} else {
Log.w(TAG, "Unexpected intent action: " + action);
return;
@ -305,7 +314,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
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);
uris[i], extensions[i], mainHandler, eventLogger);
}
SampleSourceProvider sourceProvider = providers.length == 1 ? providers[0]
: new ConcatenatingSampleSourceProvider(providers);

View file

@ -21,6 +21,7 @@ import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer.upstream.DataSourceInputStream;
import com.google.android.exoplayer.upstream.DataSpec;
import com.google.android.exoplayer.upstream.DefaultDataSource;
import com.google.android.exoplayer.util.Assertions;
import com.google.android.exoplayer.util.Util;
import android.app.Activity;
@ -90,15 +91,7 @@ public class SampleChooserActivity extends Activity {
}
private void onSampleSelected(Sample sample) {
Intent intent = new Intent(this, PlayerActivity.class)
.setAction(PlayerActivity.ACTION_VIEW)
.setData(Uri.parse(sample.uri))
.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)
.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, sample.preferExtensionDecoders);
startActivity(intent);
startActivity(sample.buildIntent(this));
}
private final class SampleListLoader extends AsyncTask<String, Void, List<SampleGroup>> {
@ -116,7 +109,7 @@ public class SampleChooserActivity extends Activity {
InputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
try {
readSampleGroups(new JsonReader(new InputStreamReader(inputStream, "UTF-8")), result);
} catch (IOException e) {
} catch (Exception e) {
Log.e(TAG, "Error loading sample list: " + uri, e);
sawError = true;
} finally {
@ -152,7 +145,7 @@ public class SampleChooserActivity extends Activity {
case "samples":
reader.beginArray();
while (reader.hasNext()) {
samples.add(readSample(reader));
samples.add(readEntry(reader, false));
}
reader.endArray();
break;
@ -164,7 +157,7 @@ public class SampleChooserActivity extends Activity {
group.samples.addAll(samples);
}
private Sample readSample(JsonReader reader) throws IOException {
private Sample readEntry(JsonReader reader, boolean insidePlaylist) throws IOException {
String sampleName = null;
String uri = null;
String extension = null;
@ -172,10 +165,12 @@ public class SampleChooserActivity extends Activity {
String drmContentId = null;
String drmProvider = null;
boolean preferExtensionDecoders = false;
ArrayList<UriSample> playlistSamples = null;
reader.beginObject();
while (reader.hasNext()) {
switch (reader.nextName()) {
String name = reader.nextName();
switch (name) {
case "name":
sampleName = reader.nextString();
break;
@ -194,15 +189,30 @@ public class SampleChooserActivity extends Activity {
case "prefer_extension_decoders":
preferExtensionDecoders = reader.nextBoolean();
break;
case "playlist":
Assertions.checkState(!insidePlaylist, "Nested playlists are invalid");
playlistSamples = new ArrayList<>();
reader.beginArray();
while (reader.hasNext()) {
playlistSamples.add((UriSample) readEntry(reader, true));
}
reader.endArray();
break;
default:
throw new ParserException("Unsupported attribute name: " + name);
}
}
reader.endObject();
if (sampleName == null || uri == null) {
throw new ParserException("Invalid sample (name or uri missing)");
if (playlistSamples != null) {
UriSample[] playlistSamplesArray = playlistSamples.toArray(
new UriSample[playlistSamples.size()]);
return new PlaylistSample(sampleName, drmUuid, drmContentId, drmProvider,
preferExtensionDecoders, playlistSamplesArray);
} else {
return new UriSample(sampleName, drmUuid, drmContentId, drmProvider,
preferExtensionDecoders, uri, extension);
}
return new Sample(sampleName, uri, extension, drmUuid, drmContentId, drmProvider,
preferExtensionDecoders);
}
private SampleGroup getGroup(String groupName, List<SampleGroup> groups) {
@ -317,27 +327,87 @@ public class SampleChooserActivity extends Activity {
}
private static class Sample {
private abstract static class Sample {
public final String name;
public final String uri;
public final String extension;
public final boolean preferExtensionDecoders;
// TODO: DRM properties should be specified on UriSample only. This requires changes to
// PlayerActivity and beyond to be able to handle playlists containing multiple DRM protected
// items that have different DRM properties.
public final UUID drmSchemeUuid;
public final String drmContentId;
public final String drmProvider;
public final boolean preferExtensionDecoders;
public Sample(String name, String uri, String extension, UUID drmSchemeUuid,
String drmContentId, String drmProvider, boolean preferExtensionDecoders) {
public Sample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider,
boolean preferExtensionDecoders) {
this.name = name;
this.uri = uri;
this.extension = extension;
this.drmSchemeUuid = drmSchemeUuid;
this.drmContentId = drmContentId;
this.drmProvider = drmProvider;
this.preferExtensionDecoders = preferExtensionDecoders;
}
public abstract Intent buildIntent(Context context);
}
private static final class UriSample extends Sample {
public final String uri;
public final String extension;
public UriSample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider,
boolean preferExtensionDecoders, String uri, String extension) {
super(name, drmSchemeUuid, drmContentId, drmProvider, preferExtensionDecoders);
this.uri = uri;
this.extension = extension;
}
@Override
public Intent buildIntent(Context context) {
return new Intent(context, PlayerActivity.class)
.setAction(PlayerActivity.ACTION_VIEW)
.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid)
.putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, drmContentId)
.putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, drmProvider)
.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders)
.setData(Uri.parse(uri))
.putExtra(PlayerActivity.EXTENSION_EXTRA, extension)
.setAction(PlayerActivity.ACTION_VIEW);
}
}
private static final class PlaylistSample extends Sample {
public final UriSample[] children;
public PlaylistSample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider,
boolean preferExtensionDecoders, UriSample... children) {
super(name, drmSchemeUuid, drmContentId, drmProvider, preferExtensionDecoders);
this.children = children;
}
@Override
public Intent buildIntent(Context context) {
String[] uris = new String[children.length];
String[] extensions = new String[children.length];
for (int i = 0; i < children.length; i++) {
uris[i] = children[i].uri;
extensions[i] = children[i].extension;
}
return new Intent(context, PlayerActivity.class)
.setAction(PlayerActivity.ACTION_VIEW)
.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid)
.putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, drmContentId)
.putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, drmProvider)
.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders)
.putExtra(PlayerActivity.URI_LIST_EXTRA, uris)
.putExtra(PlayerActivity.EXTENSION_LIST_EXTRA, extensions)
.setAction(PlayerActivity.ACTION_VIEW_LIST);
}
}
}