Commit ca310100 by Oliver Woodman

Add HLS support to simple variant of demo app. Plus cleanup.

parent 3bee259d
...@@ -57,6 +57,9 @@ package com.google.android.exoplayer.demo; ...@@ -57,6 +57,9 @@ package com.google.android.exoplayer.demo;
new Sample("Super speed (SmoothStreaming)", "uid:ss:superspeed", new Sample("Super speed (SmoothStreaming)", "uid:ss:superspeed",
"http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism", "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism",
DemoUtil.TYPE_SS, false, false), DemoUtil.TYPE_SS, false, false),
new Sample("Apple master playlist (HLS)", "uid:hls:applemaster",
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
+ "bipbop_4x3_variant.m3u8", DemoUtil.TYPE_HLS_MASTER, false, false),
new Sample("Dizzy (Misc)", "uid:misc:dizzy", new Sample("Dizzy (Misc)", "uid:misc:dizzy",
"http://html5demos.com/assets/dizzy.mp4", DemoUtil.TYPE_OTHER, false, false), "http://html5demos.com/assets/dizzy.mp4", DemoUtil.TYPE_OTHER, false, false),
}; };
......
...@@ -175,11 +175,8 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba ...@@ -175,11 +175,8 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba
return new DashVodRendererBuilder(userAgent, contentUri.toString(), contentId, return new DashVodRendererBuilder(userAgent, contentUri.toString(), contentId,
new WidevineTestMediaDrmCallback(contentId), debugTextView); new WidevineTestMediaDrmCallback(contentId), debugTextView);
case DemoUtil.TYPE_HLS_MASTER: case DemoUtil.TYPE_HLS_MASTER:
return new HlsRendererBuilder(userAgent, contentUri.toString(), contentId,
HlsRendererBuilder.TYPE_MASTER);
case DemoUtil.TYPE_HLS_MEDIA: case DemoUtil.TYPE_HLS_MEDIA:
return new HlsRendererBuilder(userAgent, contentUri.toString(), contentId, return new HlsRendererBuilder(userAgent, contentUri.toString(), contentId, contentType);
HlsRendererBuilder.TYPE_MEDIA);
default: default:
return new DefaultRendererBuilder(this, contentUri, debugTextView); return new DefaultRendererBuilder(this, contentUri, debugTextView);
} }
......
...@@ -20,6 +20,7 @@ import com.google.android.exoplayer.LoadControl; ...@@ -20,6 +20,7 @@ import com.google.android.exoplayer.LoadControl;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer; import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.demo.DemoUtil;
import com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilder; import com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilder;
import com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilderCallback; import com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilderCallback;
import com.google.android.exoplayer.hls.HlsChunkSource; import com.google.android.exoplayer.hls.HlsChunkSource;
...@@ -29,7 +30,7 @@ import com.google.android.exoplayer.hls.HlsMasterPlaylistParser; ...@@ -29,7 +30,7 @@ import com.google.android.exoplayer.hls.HlsMasterPlaylistParser;
import com.google.android.exoplayer.hls.HlsSampleSource; import com.google.android.exoplayer.hls.HlsSampleSource;
import com.google.android.exoplayer.upstream.BufferPool; import com.google.android.exoplayer.upstream.BufferPool;
import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer.upstream.HttpDataSource; import com.google.android.exoplayer.upstream.UriDataSource;
import com.google.android.exoplayer.util.ManifestFetcher; import com.google.android.exoplayer.util.ManifestFetcher;
import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback; import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
...@@ -44,39 +45,36 @@ import java.util.Collections; ...@@ -44,39 +45,36 @@ import java.util.Collections;
*/ */
public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<HlsMasterPlaylist> { public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<HlsMasterPlaylist> {
public static final int TYPE_MASTER = 0;
public static final int TYPE_MEDIA = 1;
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024; private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int VIDEO_BUFFER_SEGMENTS = 200; private static final int VIDEO_BUFFER_SEGMENTS = 200;
private final String userAgent; private final String userAgent;
private final String url; private final String url;
private final String contentId; private final String contentId;
private final int playlistType; private final int contentType;
private DemoPlayer player; private DemoPlayer player;
private RendererBuilderCallback callback; private RendererBuilderCallback callback;
public HlsRendererBuilder(String userAgent, String url, String contentId, int playlistType) { public HlsRendererBuilder(String userAgent, String url, String contentId, int contentType) {
this.userAgent = userAgent; this.userAgent = userAgent;
this.url = url; this.url = url;
this.contentId = contentId; this.contentId = contentId;
this.playlistType = playlistType; this.contentType = contentType;
} }
@Override @Override
public void buildRenderers(DemoPlayer player, RendererBuilderCallback callback) { public void buildRenderers(DemoPlayer player, RendererBuilderCallback callback) {
this.player = player; this.player = player;
this.callback = callback; this.callback = callback;
switch (playlistType) { switch (contentType) {
case TYPE_MASTER: case DemoUtil.TYPE_HLS_MASTER:
HlsMasterPlaylistParser parser = new HlsMasterPlaylistParser(); HlsMasterPlaylistParser parser = new HlsMasterPlaylistParser();
ManifestFetcher<HlsMasterPlaylist> mediaPlaylistFetcher = ManifestFetcher<HlsMasterPlaylist> mediaPlaylistFetcher =
new ManifestFetcher<HlsMasterPlaylist>(parser, contentId, url); new ManifestFetcher<HlsMasterPlaylist>(parser, contentId, url);
mediaPlaylistFetcher.singleLoad(player.getMainHandler().getLooper(), this); mediaPlaylistFetcher.singleLoad(player.getMainHandler().getLooper(), this);
break; break;
case TYPE_MEDIA: case DemoUtil.TYPE_HLS_MEDIA:
onManifest(contentId, newSimpleMasterPlaylist(url)); onManifest(contentId, newSimpleMasterPlaylist(url));
break; break;
} }
...@@ -91,7 +89,7 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls ...@@ -91,7 +89,7 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
public void onManifest(String contentId, HlsMasterPlaylist manifest) { public void onManifest(String contentId, HlsMasterPlaylist manifest) {
LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE)); LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE));
DataSource dataSource = new HttpDataSource(userAgent, null, null); DataSource dataSource = new UriDataSource(userAgent, null);
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, manifest); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, manifest);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, 2); VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, 2);
......
/*
* 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.demo.simple;
import com.google.android.exoplayer.DefaultLoadControl;
import com.google.android.exoplayer.LoadControl;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.demo.DemoUtil;
import com.google.android.exoplayer.demo.full.player.DemoPlayer;
import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilder;
import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilderCallback;
import com.google.android.exoplayer.hls.HlsChunkSource;
import com.google.android.exoplayer.hls.HlsMasterPlaylist;
import com.google.android.exoplayer.hls.HlsMasterPlaylist.Variant;
import com.google.android.exoplayer.hls.HlsMasterPlaylistParser;
import com.google.android.exoplayer.hls.HlsSampleSource;
import com.google.android.exoplayer.upstream.BufferPool;
import com.google.android.exoplayer.upstream.DataSource;
import com.google.android.exoplayer.upstream.UriDataSource;
import com.google.android.exoplayer.util.ManifestFetcher;
import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
import android.media.MediaCodec;
import android.net.Uri;
import java.io.IOException;
import java.util.Collections;
/**
* A {@link RendererBuilder} for HLS.
*/
/* package */ class HlsRendererBuilder implements RendererBuilder,
ManifestCallback<HlsMasterPlaylist> {
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int VIDEO_BUFFER_SEGMENTS = 200;
private final SimplePlayerActivity playerActivity;
private final String userAgent;
private final String url;
private final String contentId;
private final int playlistType;
private RendererBuilderCallback callback;
public HlsRendererBuilder(SimplePlayerActivity playerActivity, String userAgent, String url,
String contentId, int playlistType) {
this.playerActivity = playerActivity;
this.userAgent = userAgent;
this.url = url;
this.contentId = contentId;
this.playlistType = playlistType;
}
@Override
public void buildRenderers(RendererBuilderCallback callback) {
this.callback = callback;
switch (playlistType) {
case DemoUtil.TYPE_HLS_MASTER:
HlsMasterPlaylistParser parser = new HlsMasterPlaylistParser();
ManifestFetcher<HlsMasterPlaylist> mediaPlaylistFetcher =
new ManifestFetcher<HlsMasterPlaylist>(parser, contentId, url);
mediaPlaylistFetcher.singleLoad(playerActivity.getMainLooper(), this);
break;
case DemoUtil.TYPE_HLS_MEDIA:
onManifest(contentId, newSimpleMasterPlaylist(url));
break;
}
}
@Override
public void onManifestError(String contentId, IOException e) {
callback.onRenderersError(e);
}
@Override
public void onManifest(String contentId, HlsMasterPlaylist manifest) {
LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE));
DataSource dataSource = new UriDataSource(userAgent, null);
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, manifest);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, 2);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, playerActivity.getMainHandler(),
playerActivity, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
callback.onRenderers(videoRenderer, audioRenderer);
}
private HlsMasterPlaylist newSimpleMasterPlaylist(String mediaPlaylistUrl) {
return new HlsMasterPlaylist(Uri.parse(""),
Collections.singletonList(new Variant(mediaPlaylistUrl, 0)));
}
}
...@@ -61,10 +61,6 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call ...@@ -61,10 +61,6 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call
private static final String TAG = "PlayerActivity"; private static final String TAG = "PlayerActivity";
public static final int TYPE_DASH_VOD = 0;
public static final int TYPE_SS_VOD = 1;
public static final int TYPE_OTHER = 2;
private MediaController mediaController; private MediaController mediaController;
private Handler mainHandler; private Handler mainHandler;
private View shutterView; private View shutterView;
...@@ -90,7 +86,7 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call ...@@ -90,7 +86,7 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call
Intent intent = getIntent(); Intent intent = getIntent();
contentUri = intent.getData(); contentUri = intent.getData();
contentType = intent.getIntExtra(DemoUtil.CONTENT_TYPE_EXTRA, TYPE_OTHER); contentType = intent.getIntExtra(DemoUtil.CONTENT_TYPE_EXTRA, DemoUtil.TYPE_OTHER);
contentId = intent.getStringExtra(DemoUtil.CONTENT_ID_EXTRA); contentId = intent.getStringExtra(DemoUtil.CONTENT_ID_EXTRA);
mainHandler = new Handler(getMainLooper()); mainHandler = new Handler(getMainLooper());
...@@ -163,11 +159,15 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call ...@@ -163,11 +159,15 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call
private RendererBuilder getRendererBuilder() { private RendererBuilder getRendererBuilder() {
String userAgent = DemoUtil.getUserAgent(this); String userAgent = DemoUtil.getUserAgent(this);
switch (contentType) { switch (contentType) {
case TYPE_SS_VOD: case DemoUtil.TYPE_SS:
return new SmoothStreamingRendererBuilder(this, userAgent, contentUri.toString(), return new SmoothStreamingRendererBuilder(this, userAgent, contentUri.toString(),
contentId); contentId);
case TYPE_DASH_VOD: case DemoUtil.TYPE_DASH_VOD:
return new DashVodRendererBuilder(this, userAgent, contentUri.toString(), contentId); return new DashVodRendererBuilder(this, userAgent, contentUri.toString(), contentId);
case DemoUtil.TYPE_HLS_MASTER:
case DemoUtil.TYPE_HLS_MEDIA:
return new HlsRendererBuilder(this, userAgent, contentUri.toString(), contentId,
contentType);
default: default:
return new DefaultRendererBuilder(this, contentUri); return new DefaultRendererBuilder(this, contentUri);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment