diff --git a/demo/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml index ff3821f8fb..88b5eb5a93 100644 --- a/demo/src/main/AndroidManifest.xml +++ b/demo/src/main/AndroidManifest.xml @@ -42,12 +42,7 @@ - - - diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java b/demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java index a2915f53ff..dae5773100 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java @@ -44,16 +44,11 @@ public class DemoUtil { public static final UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL); - public static final String CONTENT_TYPE_EXTRA = "content_type"; - public static final String CONTENT_ID_EXTRA = "content_id"; - public static final int TYPE_DASH = 0; public static final int TYPE_SS = 1; public static final int TYPE_OTHER = 2; public static final int TYPE_HLS = 3; - public static final boolean EXPOSE_EXPERIMENTAL_FEATURES = false; - private static final CookieManager defaultCookieManager; static { diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/EventLogger.java b/demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java similarity index 93% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/EventLogger.java rename to demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java index 52b00246e5..c9ece110b1 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/EventLogger.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/EventLogger.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full; +package com.google.android.exoplayer.demo; import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException; import com.google.android.exoplayer.audio.AudioTrack; -import com.google.android.exoplayer.demo.full.player.DemoPlayer; +import com.google.android.exoplayer.demo.player.DemoPlayer; import com.google.android.exoplayer.util.VerboseLogUtil; import android.media.MediaCodec.CryptoException; @@ -63,8 +63,8 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener @Override public void onStateChanged(boolean playWhenReady, int state) { - Log.d(TAG, "state [" + getSessionTimeString() + ", " + playWhenReady + ", " + - getStateString(state) + "]"); + Log.d(TAG, "state [" + getSessionTimeString() + ", " + playWhenReady + ", " + + getStateString(state) + "]"); } @Override @@ -81,8 +81,8 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener @Override public void onBandwidthSample(int elapsedMs, long bytes, long bitrateEstimate) { - Log.d(TAG, "bandwidth [" + getSessionTimeString() + ", " + bytes + - ", " + getTimeString(elapsedMs) + ", " + bitrateEstimate + "]"); + Log.d(TAG, "bandwidth [" + getSessionTimeString() + ", " + bytes + ", " + + getTimeString(elapsedMs) + ", " + bitrateEstimate + "]"); } @Override @@ -104,21 +104,21 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener public void onLoadCompleted(int sourceId, long bytesLoaded) { if (VerboseLogUtil.isTagEnabled(TAG)) { long downloadTime = SystemClock.elapsedRealtime() - loadStartTimeMs[sourceId]; - Log.v(TAG, "loadEnd [" + getSessionTimeString() + ", " + sourceId + ", " + - downloadTime + "]"); + Log.v(TAG, "loadEnd [" + getSessionTimeString() + ", " + sourceId + ", " + downloadTime + + "]"); } } @Override public void onVideoFormatEnabled(String formatId, int trigger, int mediaTimeMs) { - Log.d(TAG, "videoFormat [" + getSessionTimeString() + ", " + formatId + ", " + - Integer.toString(trigger) + "]"); + Log.d(TAG, "videoFormat [" + getSessionTimeString() + ", " + formatId + ", " + + Integer.toString(trigger) + "]"); } @Override public void onAudioFormatEnabled(String formatId, int trigger, int mediaTimeMs) { - Log.d(TAG, "audioFormat [" + getSessionTimeString() + ", " + formatId + ", " + - Integer.toString(trigger) + "]"); + Log.d(TAG, "audioFormat [" + getSessionTimeString() + ", " + formatId + ", " + + Integer.toString(trigger) + "]"); } // DemoPlayer.InternalErrorListener diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java similarity index 94% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java rename to demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java index 9ff45850d2..6c5bb7536a 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java @@ -13,21 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full; +package com.google.android.exoplayer.demo; import com.google.android.exoplayer.ExoPlayer; import com.google.android.exoplayer.VideoSurfaceView; import com.google.android.exoplayer.audio.AudioCapabilities; import com.google.android.exoplayer.audio.AudioCapabilitiesReceiver; -import com.google.android.exoplayer.demo.DemoUtil; -import com.google.android.exoplayer.demo.R; -import com.google.android.exoplayer.demo.full.player.DashRendererBuilder; -import com.google.android.exoplayer.demo.full.player.DefaultRendererBuilder; -import com.google.android.exoplayer.demo.full.player.DemoPlayer; -import com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilder; -import com.google.android.exoplayer.demo.full.player.HlsRendererBuilder; -import com.google.android.exoplayer.demo.full.player.SmoothStreamingRendererBuilder; -import com.google.android.exoplayer.demo.full.player.UnsupportedDrmException; +import com.google.android.exoplayer.demo.player.DashRendererBuilder; +import com.google.android.exoplayer.demo.player.DefaultRendererBuilder; +import com.google.android.exoplayer.demo.player.DemoPlayer; +import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder; +import com.google.android.exoplayer.demo.player.HlsRendererBuilder; +import com.google.android.exoplayer.demo.player.SmoothStreamingRendererBuilder; +import com.google.android.exoplayer.demo.player.UnsupportedDrmException; import com.google.android.exoplayer.metadata.TxxxMetadata; import com.google.android.exoplayer.text.CaptionStyleCompat; import com.google.android.exoplayer.text.SubtitleView; @@ -65,11 +63,14 @@ import java.util.Map; /** * An activity that plays media using {@link DemoPlayer}. */ -public class FullPlayerActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, +public class PlayerActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, DemoPlayer.Listener, DemoPlayer.TextListener, DemoPlayer.Id3MetadataListener, AudioCapabilitiesReceiver.Listener { - private static final String TAG = "FullPlayerActivity"; + public static final String CONTENT_TYPE_EXTRA = "content_type"; + public static final String CONTENT_ID_EXTRA = "content_id"; + + private static final String TAG = "PlayerActivity"; private static final float CAPTION_LINE_HEIGHT_RATIO = 0.0533f; private static final int MENU_GROUP_TRACKS = 1; @@ -110,10 +111,10 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba Intent intent = getIntent(); contentUri = intent.getData(); - contentType = intent.getIntExtra(DemoUtil.CONTENT_TYPE_EXTRA, DemoUtil.TYPE_OTHER); - contentId = intent.getStringExtra(DemoUtil.CONTENT_ID_EXTRA); + contentType = intent.getIntExtra(CONTENT_TYPE_EXTRA, DemoUtil.TYPE_OTHER); + contentId = intent.getStringExtra(CONTENT_ID_EXTRA); - setContentView(R.layout.player_activity_full); + setContentView(R.layout.player_activity); View root = findViewById(R.id.root); root.setOnTouchListener(new OnTouchListener() { @Override 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 94478c48e7..3a9fdc5529 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 @@ -15,15 +15,17 @@ */ package com.google.android.exoplayer.demo; +import com.google.android.exoplayer.MediaCodecUtil; +import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer.demo.Samples.Sample; -import com.google.android.exoplayer.demo.full.FullPlayerActivity; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity; +import com.google.android.exoplayer.util.MimeTypes; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -38,6 +40,8 @@ import android.widget.TextView; */ public class SampleChooserActivity extends Activity { + private static final String TAG = "SampleChooserActivity"; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -46,21 +50,25 @@ public class SampleChooserActivity extends Activity { ListView sampleList = (ListView) findViewById(R.id.sample_list); final SampleAdapter sampleAdapter = new SampleAdapter(this); - sampleAdapter.add(new Header("Simple player")); - sampleAdapter.addAll((Object[]) Samples.SIMPLE); sampleAdapter.add(new Header("YouTube DASH")); sampleAdapter.addAll((Object[]) Samples.YOUTUBE_DASH_MP4); sampleAdapter.add(new Header("Widevine GTS DASH")); sampleAdapter.addAll((Object[]) Samples.WIDEVINE_GTS); sampleAdapter.add(new Header("SmoothStreaming")); sampleAdapter.addAll((Object[]) Samples.SMOOTHSTREAMING); - sampleAdapter.add(new Header("Misc")); - sampleAdapter.addAll((Object[]) Samples.MISC); sampleAdapter.add(new Header("HLS")); sampleAdapter.addAll((Object[]) Samples.HLS); - if (DemoUtil.EXPOSE_EXPERIMENTAL_FEATURES) { - sampleAdapter.add(new Header("YouTube WebM DASH (Experimental)")); - sampleAdapter.addAll((Object[]) Samples.YOUTUBE_DASH_WEBM); + sampleAdapter.add(new Header("Misc")); + sampleAdapter.addAll((Object[]) Samples.MISC); + + // Add WebM samples if the device has a VP9 decoder. + try { + if (MediaCodecUtil.getDecoderInfo(MimeTypes.VIDEO_VP9, false) != null) { + sampleAdapter.add(new Header("YouTube WebM DASH (Experimental)")); + sampleAdapter.addAll((Object[]) Samples.YOUTUBE_DASH_WEBM); + } + } catch (DecoderQueryException e) { + Log.e(TAG, "Failed to query vp9 decoder", e); } sampleList.setAdapter(sampleAdapter); @@ -76,12 +84,10 @@ public class SampleChooserActivity extends Activity { } private void onSampleSelected(Sample sample) { - Class playerActivityClass = sample.fullPlayer ? FullPlayerActivity.class - : SimplePlayerActivity.class; - Intent mpdIntent = new Intent(this, playerActivityClass) + Intent mpdIntent = new Intent(this, PlayerActivity.class) .setData(Uri.parse(sample.uri)) - .putExtra(DemoUtil.CONTENT_ID_EXTRA, sample.contentId) - .putExtra(DemoUtil.CONTENT_TYPE_EXTRA, sample.type); + .putExtra(PlayerActivity.CONTENT_ID_EXTRA, sample.contentId) + .putExtra(PlayerActivity.CONTENT_TYPE_EXTRA, sample.type); startActivity(mpdIntent); } diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/Samples.java b/demo/src/main/java/com/google/android/exoplayer/demo/Samples.java index b3eb4af93c..7817123830 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/Samples.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/Samples.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer.demo; +import java.util.Locale; + /** * Holds statically defined sample definitions. */ @@ -26,72 +28,53 @@ package com.google.android.exoplayer.demo; public final String contentId; public final String uri; public final int type; - public final boolean fullPlayer; - public Sample(String name, String contentId, String uri, int type, boolean fullPlayer) { + public Sample(String name, String uri, int type) { + this(name, name.toLowerCase(Locale.US).replaceAll("\\s", ""), uri, type); + } + + public Sample(String name, String contentId, String uri, int type) { this.name = name; this.contentId = contentId; this.uri = uri; this.type = type; - this.fullPlayer = fullPlayer; } } - public static final Sample[] SIMPLE = new Sample[] { - new Sample("Google Glass (DASH)", "bf5bb2419360daf1", - "http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?" - + "as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&" - + "ipbits=0&expire=19000000000&signature=255F6B3C07C753C88708C07EA31B7A1A10703C8D." - + "2D6A28B21F921D0B245CDCF36F7EB54A2B5ABFC2&key=ik0", DemoUtil.TYPE_DASH, false), - new Sample("Google Play (DASH)", "3aa39fa2cc27967f", - "http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?" - + "as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0&" - + "expire=19000000000&signature=7181C59D0252B285D593E1B61D985D5B7C98DE2A." - + "5B445837F55A40E0F28AACAA047982E372D177E2&key=ik0", DemoUtil.TYPE_DASH, false), - new Sample("Super speed (SmoothStreaming)", "uid:ss:superspeed", - "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism", - DemoUtil.TYPE_SS, 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, false), - new Sample("Dizzy (Misc)", "uid:misc:dizzy", - "http://html5demos.com/assets/dizzy.mp4", DemoUtil.TYPE_OTHER, false), - }; - public static final Sample[] YOUTUBE_DASH_MP4 = new Sample[] { - new Sample("Google Glass", "bf5bb2419360daf1", + new Sample("Google Glass", "http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?" + "as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&" + "ipbits=0&expire=19000000000&signature=255F6B3C07C753C88708C07EA31B7A1A10703C8D." - + "2D6A28B21F921D0B245CDCF36F7EB54A2B5ABFC2&key=ik0", DemoUtil.TYPE_DASH, true), - new Sample("Google Play", "3aa39fa2cc27967f", + + "2D6A28B21F921D0B245CDCF36F7EB54A2B5ABFC2&key=ik0", DemoUtil.TYPE_DASH), + new Sample("Google Play", "http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?" + "as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0&" + "expire=19000000000&signature=7181C59D0252B285D593E1B61D985D5B7C98DE2A." - + "5B445837F55A40E0F28AACAA047982E372D177E2&key=ik0", DemoUtil.TYPE_DASH, true), + + "5B445837F55A40E0F28AACAA047982E372D177E2&key=ik0", DemoUtil.TYPE_DASH), }; public static final Sample[] YOUTUBE_DASH_WEBM = new Sample[] { - new Sample("Google Glass", "bf5bb2419360daf1", + new Sample("Google Glass", "http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?" + "as=fmp4_audio_clear,webm2_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0&" + "expire=19000000000&signature=A3EC7EE53ABE601B357F7CAB8B54AD0702CA85A7." - + "446E9C38E47E3EDAF39E0163C390FF83A7944918&key=ik0", DemoUtil.TYPE_DASH, true), - new Sample("Google Play", "3aa39fa2cc27967f", + + "446E9C38E47E3EDAF39E0163C390FF83A7944918&key=ik0", DemoUtil.TYPE_DASH), + new Sample("Google Play", "http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?" + "as=fmp4_audio_clear,webm2_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0&" + "expire=19000000000&signature=B752B262C6D7262EC4E4EB67901E5D8F7058A81D." - + "C0358CE1E335417D9A8D88FF192F0D5D8F6DA1B6&key=ik0", DemoUtil.TYPE_DASH, true), + + "C0358CE1E335417D9A8D88FF192F0D5D8F6DA1B6&key=ik0", DemoUtil.TYPE_DASH), }; public static final Sample[] SMOOTHSTREAMING = new Sample[] { - new Sample("Super speed", "uid:ss:superspeed", + new Sample("Super speed", "http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism", - DemoUtil.TYPE_SS, true), - new Sample("Super speed (PlayReady)", "uid:ss:pr:superspeed", + DemoUtil.TYPE_SS), + new Sample("Super speed (PlayReady)", "http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism", - DemoUtil.TYPE_SS, true), + DemoUtil.TYPE_SS), }; public static final Sample[] WIDEVINE_GTS = new Sample[] { @@ -99,54 +82,54 @@ package com.google.android.exoplayer.demo; "http://www.youtube.com/api/manifest/dash/id/d286538032258a1c/source/youtube?" + "as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0" + "&expire=19000000000&signature=41EA40A027A125A16292E0A5E3277A3B5FA9B938." - + "0BB075C396FFDDC97E526E8F77DC26FF9667D0D6&key=ik0", DemoUtil.TYPE_DASH, true), + + "0BB075C396FFDDC97E526E8F77DC26FF9667D0D6&key=ik0", DemoUtil.TYPE_DASH), new Sample("WV: HDCP not required", "48fcc369939ac96c", "http://www.youtube.com/api/manifest/dash/id/48fcc369939ac96c/source/youtube?" + "as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0" + "&expire=19000000000&signature=315911BDCEED0FB0C763455BDCC97449DAAFA9E8." - + "5B41E2EB411F797097A359D6671D2CDE26272373&key=ik0", DemoUtil.TYPE_DASH, true), + + "5B41E2EB411F797097A359D6671D2CDE26272373&key=ik0", DemoUtil.TYPE_DASH), new Sample("WV: HDCP required", "e06c39f1151da3df", "http://www.youtube.com/api/manifest/dash/id/e06c39f1151da3df/source/youtube?" + "as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0" + "&expire=19000000000&signature=A47A1E13E7243BD567601A75F79B34644D0DC592." - + "B09589A34FA23527EFC1552907754BB8033870BD&key=ik0", DemoUtil.TYPE_DASH, true), + + "B09589A34FA23527EFC1552907754BB8033870BD&key=ik0", DemoUtil.TYPE_DASH), new Sample("WV: Secure video path required", "0894c7c8719b28a0", "http://www.youtube.com/api/manifest/dash/id/0894c7c8719b28a0/source/youtube?" + "as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0" + "&expire=19000000000&signature=2847EE498970F6B45176766CD2802FEB4D4CB7B2." - + "A1CA51EC40A1C1039BA800C41500DD448C03EEDA&key=ik0", DemoUtil.TYPE_DASH, true), + + "A1CA51EC40A1C1039BA800C41500DD448C03EEDA&key=ik0", DemoUtil.TYPE_DASH), new Sample("WV: HDCP + secure video path required", "efd045b1eb61888a", "http://www.youtube.com/api/manifest/dash/id/efd045b1eb61888a/source/youtube?" + "as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0" + "&expire=19000000000&signature=61611F115EEEC7BADE5536827343FFFE2D83D14F." - + "2FDF4BFA502FB5865C5C86401314BDDEA4799BD0&key=ik0", DemoUtil.TYPE_DASH, true), + + "2FDF4BFA502FB5865C5C86401314BDDEA4799BD0&key=ik0", DemoUtil.TYPE_DASH), new Sample("WV: 30s license duration", "f9a34cab7b05881a", "http://www.youtube.com/api/manifest/dash/id/f9a34cab7b05881a/source/youtube?" + "as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,as&ip=0.0.0.0&ipbits=0" + "&expire=19000000000&signature=88DC53943385CED8CF9F37ADD9E9843E3BF621E6." - + "22727BB612D24AA4FACE4EF62726F9461A9BF57A&key=ik0", DemoUtil.TYPE_DASH, true), + + "22727BB612D24AA4FACE4EF62726F9461A9BF57A&key=ik0", DemoUtil.TYPE_DASH), }; public static final Sample[] HLS = new Sample[] { - new Sample("Apple master playlist", "uid:hls:applemaster", + new Sample("Apple master playlist", "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/" - + "bipbop_4x3_variant.m3u8", DemoUtil.TYPE_HLS, true), - new Sample("Apple master playlist advanced", "uid:hls:applemasteradvanced", + + "bipbop_4x3_variant.m3u8", DemoUtil.TYPE_HLS), + new Sample("Apple master playlist advanced", "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/" - + "bipbop_16x9_variant.m3u8", DemoUtil.TYPE_HLS, true), - new Sample("Apple single media playlist", "uid:hls:applesinglemedia", + + "bipbop_16x9_variant.m3u8", DemoUtil.TYPE_HLS), + new Sample("Apple single media playlist", "https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/" - + "prog_index.m3u8", DemoUtil.TYPE_HLS, true), + + "prog_index.m3u8", DemoUtil.TYPE_HLS), }; public static final Sample[] MISC = new Sample[] { - new Sample("Dizzy", "uid:misc:dizzy", "http://html5demos.com/assets/dizzy.mp4", - DemoUtil.TYPE_OTHER, true), - new Sample("Dizzy (https->http redirect)", "uid:misc:dizzy2", "https://goo.gl/MtUDEj", - DemoUtil.TYPE_OTHER, true), - new Sample("Apple AAC 10s", "uid:misc:appleaacseg", "https://devimages.apple.com.edgekey.net/" + new Sample("Dizzy", "http://html5demos.com/assets/dizzy.mp4", + DemoUtil.TYPE_OTHER), + new Sample("Dizzy (https->http redirect)", "https://goo.gl/MtUDEj", + DemoUtil.TYPE_OTHER), + new Sample("Apple AAC 10s", "https://devimages.apple.com.edgekey.net/" + "streaming/examples/bipbop_4x3/gear0/fileSequence0.aac", - DemoUtil.TYPE_OTHER, true), + DemoUtil.TYPE_OTHER), }; private Samples() {} diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/SmoothStreamingTestMediaDrmCallback.java b/demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java similarity index 95% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/SmoothStreamingTestMediaDrmCallback.java rename to demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java index b193860423..ace3f1ee08 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/SmoothStreamingTestMediaDrmCallback.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full; +package com.google.android.exoplayer.demo; -import com.google.android.exoplayer.demo.DemoUtil; import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/WidevineTestMediaDrmCallback.java b/demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java similarity index 95% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/WidevineTestMediaDrmCallback.java rename to demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java index f2425589db..378c74c202 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/WidevineTestMediaDrmCallback.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full; +package com.google.android.exoplayer.demo; -import com.google.android.exoplayer.demo.DemoUtil; import com.google.android.exoplayer.drm.MediaDrmCallback; import android.annotation.TargetApi; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DashRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java similarity index 98% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/DashRendererBuilder.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java index dca0b2a57d..3f14a58bdb 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DashRendererBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; import com.google.android.exoplayer.Ac3PassthroughAudioTrackRenderer; import com.google.android.exoplayer.DefaultLoadControl; @@ -38,8 +38,8 @@ import com.google.android.exoplayer.dash.mpd.MediaPresentationDescriptionParser; import com.google.android.exoplayer.dash.mpd.Period; import com.google.android.exoplayer.dash.mpd.Representation; 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.RendererBuilderCallback; +import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder; +import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback; import com.google.android.exoplayer.drm.DrmSessionManager; import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DebugTrackRenderer.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DebugTrackRenderer.java similarity index 96% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/DebugTrackRenderer.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/DebugTrackRenderer.java index d848dd3908..c0b9d50417 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DebugTrackRenderer.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DebugTrackRenderer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.MediaCodecTrackRenderer; @@ -82,8 +82,8 @@ import android.widget.TextView; } private String getRenderString() { - return "ms(" + (currentPositionUs / 1000) + "), " + getQualityString() + - ", " + renderer.codecCounters.getDebugString(); + return "ms(" + (currentPositionUs / 1000) + "), " + getQualityString() + + ", " + renderer.codecCounters.getDebugString(); } private String getQualityString() { diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DefaultRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DefaultRendererBuilder.java similarity index 92% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/DefaultRendererBuilder.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/DefaultRendererBuilder.java index 5bf369a5fc..36c2e58879 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DefaultRendererBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DefaultRendererBuilder.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; import com.google.android.exoplayer.MediaCodecAudioTrackRenderer; import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; import com.google.android.exoplayer.TrackRenderer; -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.player.DemoPlayer.RendererBuilder; +import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback; import com.google.android.exoplayer.source.DefaultSampleSource; import com.google.android.exoplayer.source.FrameworkSampleExtractor; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java similarity index 99% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java index a7ba111990..e20b87c21a 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; import com.google.android.exoplayer.Ac3PassthroughAudioTrackRenderer; import com.google.android.exoplayer.DummyTrackRenderer; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/HlsRendererBuilder.java similarity index 94% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/HlsRendererBuilder.java index cab7ffcc33..326a0689d5 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/HlsRendererBuilder.java @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; import com.google.android.exoplayer.MediaCodecAudioTrackRenderer; import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; import com.google.android.exoplayer.TrackRenderer; -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.player.DemoPlayer.RendererBuilder; +import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback; import com.google.android.exoplayer.hls.HlsChunkSource; import com.google.android.exoplayer.hls.HlsPlaylist; import com.google.android.exoplayer.hls.HlsPlaylistParser; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/SmoothStreamingRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/SmoothStreamingRendererBuilder.java similarity index 98% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/SmoothStreamingRendererBuilder.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/SmoothStreamingRendererBuilder.java index b31ea0a50d..22a342bfc7 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/SmoothStreamingRendererBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/SmoothStreamingRendererBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; import com.google.android.exoplayer.DefaultLoadControl; import com.google.android.exoplayer.LoadControl; @@ -27,8 +27,8 @@ import com.google.android.exoplayer.chunk.ChunkSource; import com.google.android.exoplayer.chunk.FormatEvaluator; import com.google.android.exoplayer.chunk.FormatEvaluator.AdaptiveEvaluator; import com.google.android.exoplayer.chunk.MultiTrackChunkSource; -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.player.DemoPlayer.RendererBuilder; +import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback; import com.google.android.exoplayer.drm.DrmSessionManager; import com.google.android.exoplayer.drm.MediaDrmCallback; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/UnsupportedDrmException.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/UnsupportedDrmException.java similarity index 95% rename from demo/src/main/java/com/google/android/exoplayer/demo/full/player/UnsupportedDrmException.java rename to demo/src/main/java/com/google/android/exoplayer/demo/player/UnsupportedDrmException.java index 3776b8bef5..e71e1b04d3 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/UnsupportedDrmException.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/UnsupportedDrmException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.demo.full.player; +package com.google.android.exoplayer.demo.player; /** * Exception thrown when the required level of DRM is not supported. diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/simple/DashRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/simple/DashRendererBuilder.java deleted file mode 100644 index e850421479..0000000000 --- a/demo/src/main/java/com/google/android/exoplayer/demo/simple/DashRendererBuilder.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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.MediaCodecUtil; -import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException; -import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; -import com.google.android.exoplayer.SampleSource; -import com.google.android.exoplayer.chunk.ChunkSampleSource; -import com.google.android.exoplayer.chunk.ChunkSource; -import com.google.android.exoplayer.chunk.Format; -import com.google.android.exoplayer.chunk.FormatEvaluator; -import com.google.android.exoplayer.chunk.FormatEvaluator.AdaptiveEvaluator; -import com.google.android.exoplayer.dash.DashChunkSource; -import com.google.android.exoplayer.dash.mpd.AdaptationSet; -import com.google.android.exoplayer.dash.mpd.MediaPresentationDescription; -import com.google.android.exoplayer.dash.mpd.MediaPresentationDescriptionParser; -import com.google.android.exoplayer.dash.mpd.Period; -import com.google.android.exoplayer.dash.mpd.Representation; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilder; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilderCallback; -import com.google.android.exoplayer.upstream.BufferPool; -import com.google.android.exoplayer.upstream.DataSource; -import com.google.android.exoplayer.upstream.DefaultBandwidthMeter; -import com.google.android.exoplayer.upstream.UriDataSource; -import com.google.android.exoplayer.util.ManifestFetcher; -import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback; -import com.google.android.exoplayer.util.MimeTypes; -import com.google.android.exoplayer.util.Util; - -import android.media.MediaCodec; -import android.os.Handler; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * A {@link RendererBuilder} for DASH. - */ -/* package */ class DashRendererBuilder implements RendererBuilder, - ManifestCallback { - - private static final int BUFFER_SEGMENT_SIZE = 64 * 1024; - private static final int VIDEO_BUFFER_SEGMENTS = 200; - private static final int AUDIO_BUFFER_SEGMENTS = 60; - private static final int LIVE_EDGE_LATENCY_MS = 30000; - - private final SimplePlayerActivity playerActivity; - private final String userAgent; - private final String url; - private final String contentId; - - private RendererBuilderCallback callback; - private ManifestFetcher manifestFetcher; - - public DashRendererBuilder(SimplePlayerActivity playerActivity, String userAgent, String url, - String contentId) { - this.playerActivity = playerActivity; - this.userAgent = userAgent; - this.url = url; - this.contentId = contentId; - } - - @Override - public void buildRenderers(RendererBuilderCallback callback) { - this.callback = callback; - MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser(); - manifestFetcher = new ManifestFetcher(parser, contentId, url, - userAgent); - manifestFetcher.singleLoad(playerActivity.getMainLooper(), this); - } - - @Override - public void onManifestError(String contentId, IOException e) { - callback.onRenderersError(e); - } - - @Override - public void onManifest(String contentId, MediaPresentationDescription manifest) { - Period period = manifest.periods.get(0); - Handler mainHandler = playerActivity.getMainHandler(); - LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE)); - DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); - - // Determine which video representations we should use for playback. - int maxDecodableFrameSize; - try { - maxDecodableFrameSize = MediaCodecUtil.maxH264DecodableFrameSize(); - } catch (DecoderQueryException e) { - callback.onRenderersError(e); - return; - } - - int videoAdaptationSetIndex = period.getAdaptationSetIndex(AdaptationSet.TYPE_VIDEO); - List videoRepresentations = - period.adaptationSets.get(videoAdaptationSetIndex).representations; - ArrayList videoRepresentationIndexList = new ArrayList(); - for (int i = 0; i < videoRepresentations.size(); i++) { - Format format = videoRepresentations.get(i).format; - if (format.width * format.height > maxDecodableFrameSize) { - // Filtering stream that device cannot play - } else if (!format.mimeType.equals(MimeTypes.VIDEO_MP4) - && !format.mimeType.equals(MimeTypes.VIDEO_WEBM)) { - // Filtering unsupported mime type - } else { - videoRepresentationIndexList.add(i); - } - } - - // Build the video renderer. - final MediaCodecVideoTrackRenderer videoRenderer; - if (videoRepresentationIndexList.isEmpty()) { - videoRenderer = null; - } else { - int[] videoRepresentationIndices = Util.toArray(videoRepresentationIndexList); - DataSource videoDataSource = new UriDataSource(userAgent, bandwidthMeter); - ChunkSource videoChunkSource = new DashChunkSource(manifestFetcher, videoAdaptationSetIndex, - videoRepresentationIndices, videoDataSource, new AdaptiveEvaluator(bandwidthMeter), - LIVE_EDGE_LATENCY_MS); - ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, - VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); - videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, - MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, mainHandler, playerActivity, 50); - } - - // Build the audio renderer. - int audioAdaptationSetIndex = period.getAdaptationSetIndex(AdaptationSet.TYPE_AUDIO); - DataSource audioDataSource = new UriDataSource(userAgent, bandwidthMeter); - ChunkSource audioChunkSource = new DashChunkSource(manifestFetcher, audioAdaptationSetIndex, - new int[] {0}, audioDataSource, new FormatEvaluator.FixedEvaluator(), LIVE_EDGE_LATENCY_MS); - SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, - AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); - MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer( - audioSampleSource); - callback.onRenderers(videoRenderer, audioRenderer); - } - -} diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/simple/DefaultRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/simple/DefaultRendererBuilder.java deleted file mode 100644 index 849e0ad986..0000000000 --- a/demo/src/main/java/com/google/android/exoplayer/demo/simple/DefaultRendererBuilder.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.MediaCodecAudioTrackRenderer; -import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilder; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilderCallback; -import com.google.android.exoplayer.source.DefaultSampleSource; -import com.google.android.exoplayer.source.FrameworkSampleExtractor; - -import android.media.MediaCodec; -import android.net.Uri; - -/** - * A {@link RendererBuilder} for streams that can be read using - * {@link android.media.MediaExtractor}. - */ -/* package */ class DefaultRendererBuilder implements RendererBuilder { - - private final SimplePlayerActivity playerActivity; - private final Uri uri; - - public DefaultRendererBuilder(SimplePlayerActivity playerActivity, Uri uri) { - this.playerActivity = playerActivity; - this.uri = uri; - } - - @Override - public void buildRenderers(RendererBuilderCallback callback) { - // Build the video and audio renderers. - DefaultSampleSource sampleSource = - new DefaultSampleSource(new FrameworkSampleExtractor(playerActivity, uri, null), 2); - MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, - MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, playerActivity.getMainHandler(), - playerActivity, 50); - MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); - - // Invoke the callback. - callback.onRenderers(videoRenderer, audioRenderer); - } - -} diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java deleted file mode 100644 index 1f08b63b38..0000000000 --- a/demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.MediaCodecAudioTrackRenderer; -import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; -import com.google.android.exoplayer.TrackRenderer; -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.HlsPlaylist; -import com.google.android.exoplayer.hls.HlsPlaylistParser; -import com.google.android.exoplayer.hls.HlsSampleSource; -import com.google.android.exoplayer.upstream.DataSource; -import com.google.android.exoplayer.upstream.DefaultBandwidthMeter; -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 java.io.IOException; - -/** - * A {@link RendererBuilder} for HLS. - */ -/* package */ class HlsRendererBuilder implements RendererBuilder, - ManifestCallback { - - private final SimplePlayerActivity playerActivity; - private final String userAgent; - private final String url; - private final String contentId; - - private RendererBuilderCallback callback; - - public HlsRendererBuilder(SimplePlayerActivity playerActivity, String userAgent, String url, - String contentId) { - this.playerActivity = playerActivity; - this.userAgent = userAgent; - this.url = url; - this.contentId = contentId; - } - - @Override - public void buildRenderers(RendererBuilderCallback callback) { - this.callback = callback; - HlsPlaylistParser parser = new HlsPlaylistParser(); - ManifestFetcher playlistFetcher = - new ManifestFetcher(parser, contentId, url, userAgent); - playlistFetcher.singleLoad(playerActivity.getMainLooper(), this); - } - - @Override - public void onManifestError(String contentId, IOException e) { - callback.onRenderersError(e); - } - - @Override - public void onManifest(String contentId, HlsPlaylist manifest) { - DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); - - DataSource dataSource = new UriDataSource(userAgent, bandwidthMeter); - HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, null, - HlsChunkSource.ADAPTIVE_MODE_SPLICE); - HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, 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); - } - -} diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java deleted file mode 100644 index 6577921bbc..0000000000 --- a/demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * 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.ExoPlaybackException; -import com.google.android.exoplayer.ExoPlayer; -import com.google.android.exoplayer.MediaCodecAudioTrackRenderer; -import com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException; -import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; -import com.google.android.exoplayer.VideoSurfaceView; -import com.google.android.exoplayer.demo.DemoUtil; -import com.google.android.exoplayer.demo.R; -import com.google.android.exoplayer.util.PlayerControl; - -import android.app.Activity; -import android.content.Intent; -import android.media.MediaCodec.CryptoException; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -import android.view.MotionEvent; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.View; -import android.view.View.OnTouchListener; -import android.widget.MediaController; -import android.widget.Toast; - -/** - * An activity that plays media using {@link ExoPlayer}. - */ -public class SimplePlayerActivity extends Activity implements SurfaceHolder.Callback, - ExoPlayer.Listener, MediaCodecVideoTrackRenderer.EventListener { - - /** - * Builds renderers for the player. - */ - public interface RendererBuilder { - - void buildRenderers(RendererBuilderCallback callback); - - } - - public static final int RENDERER_COUNT = 2; - public static final int TYPE_VIDEO = 0; - public static final int TYPE_AUDIO = 1; - - private static final String TAG = "PlayerActivity"; - - private MediaController mediaController; - private Handler mainHandler; - private View shutterView; - private VideoSurfaceView surfaceView; - - private ExoPlayer player; - private RendererBuilder builder; - private RendererBuilderCallback callback; - private MediaCodecVideoTrackRenderer videoRenderer; - - private boolean autoPlay = true; - private long playerPosition; - - private Uri contentUri; - private int contentType; - private String contentId; - - // Activity lifecycle - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - contentUri = intent.getData(); - contentType = intent.getIntExtra(DemoUtil.CONTENT_TYPE_EXTRA, DemoUtil.TYPE_OTHER); - contentId = intent.getStringExtra(DemoUtil.CONTENT_ID_EXTRA); - - mainHandler = new Handler(getMainLooper()); - builder = getRendererBuilder(); - - setContentView(R.layout.player_activity_simple); - View root = findViewById(R.id.root); - root.setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View arg0, MotionEvent arg1) { - if (arg1.getAction() == MotionEvent.ACTION_DOWN) { - toggleControlsVisibility(); - } - return true; - } - }); - - mediaController = new MediaController(this); - mediaController.setAnchorView(root); - shutterView = findViewById(R.id.shutter); - surfaceView = (VideoSurfaceView) findViewById(R.id.surface_view); - surfaceView.getHolder().addCallback(this); - - DemoUtil.setDefaultCookieManager(); - } - - @Override - public void onResume() { - super.onResume(); - // Setup the player - player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000); - player.addListener(this); - player.seekTo(playerPosition); - // Build the player controls - mediaController.setMediaPlayer(new PlayerControl(player)); - mediaController.setEnabled(true); - // Request the renderers - callback = new RendererBuilderCallback(); - builder.buildRenderers(callback); - } - - @Override - public void onPause() { - super.onPause(); - // Release the player - if (player != null) { - playerPosition = player.getCurrentPosition(); - player.release(); - player = null; - } - callback = null; - videoRenderer = null; - shutterView.setVisibility(View.VISIBLE); - } - - // Public methods - - public Handler getMainHandler() { - return mainHandler; - } - - // Internal methods - - private void toggleControlsVisibility() { - if (mediaController.isShowing()) { - mediaController.hide(); - } else { - mediaController.show(0); - } - } - - private RendererBuilder getRendererBuilder() { - String userAgent = DemoUtil.getUserAgent(this); - switch (contentType) { - case DemoUtil.TYPE_SS: - return new SmoothStreamingRendererBuilder(this, userAgent, contentUri.toString(), - contentId); - case DemoUtil.TYPE_DASH: - return new DashRendererBuilder(this, userAgent, contentUri.toString(), contentId); - case DemoUtil.TYPE_HLS: - return new HlsRendererBuilder(this, userAgent, contentUri.toString(), contentId); - default: - return new DefaultRendererBuilder(this, contentUri); - } - } - - private void onRenderers(RendererBuilderCallback callback, - MediaCodecVideoTrackRenderer videoRenderer, MediaCodecAudioTrackRenderer audioRenderer) { - if (this.callback != callback) { - return; - } - this.callback = null; - this.videoRenderer = videoRenderer; - player.prepare(videoRenderer, audioRenderer); - maybeStartPlayback(); - } - - private void maybeStartPlayback() { - Surface surface = surfaceView.getHolder().getSurface(); - if (videoRenderer == null || surface == null || !surface.isValid()) { - // We're not ready yet. - return; - } - player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); - if (autoPlay) { - player.setPlayWhenReady(true); - autoPlay = false; - } - } - - private void onRenderersError(RendererBuilderCallback callback, Exception e) { - if (this.callback != callback) { - return; - } - this.callback = null; - onError(e); - } - - private void onError(Exception e) { - Log.e(TAG, "Playback failed", e); - Toast.makeText(this, R.string.failed, Toast.LENGTH_SHORT).show(); - finish(); - } - - // ExoPlayer.Listener implementation - - @Override - public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { - // Do nothing. - } - - @Override - public void onPlayWhenReadyCommitted() { - // Do nothing. - } - - @Override - public void onPlayerError(ExoPlaybackException e) { - onError(e); - } - - // MediaCodecVideoTrackRenderer.Listener - - @Override - public void onVideoSizeChanged(int width, int height, float pixelWidthHeightRatio) { - surfaceView.setVideoWidthHeightRatio( - height == 0 ? 1 : (pixelWidthHeightRatio * width) / height); - } - - @Override - public void onDrawnToSurface(Surface surface) { - shutterView.setVisibility(View.GONE); - } - - @Override - public void onDroppedFrames(int count, long elapsed) { - Log.d(TAG, "Dropped frames: " + count); - } - - @Override - public void onDecoderInitializationError(DecoderInitializationException e) { - // This is for informational purposes only. Do nothing. - } - - @Override - public void onCryptoError(CryptoException e) { - // This is for informational purposes only. Do nothing. - } - - // SurfaceHolder.Callback implementation - - @Override - public void surfaceCreated(SurfaceHolder holder) { - maybeStartPlayback(); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - // Do nothing. - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - if (videoRenderer != null) { - player.blockingSendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, null); - } - } - - /* package */ final class RendererBuilderCallback { - - public void onRenderers(MediaCodecVideoTrackRenderer videoRenderer, - MediaCodecAudioTrackRenderer audioRenderer) { - SimplePlayerActivity.this.onRenderers(this, videoRenderer, audioRenderer); - } - - public void onRenderersError(Exception e) { - SimplePlayerActivity.this.onRenderersError(this, e); - } - - } - -} diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/simple/SmoothStreamingRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/simple/SmoothStreamingRendererBuilder.java deleted file mode 100644 index a5c5569a32..0000000000 --- a/demo/src/main/java/com/google/android/exoplayer/demo/simple/SmoothStreamingRendererBuilder.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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.MediaCodecUtil; -import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException; -import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; -import com.google.android.exoplayer.SampleSource; -import com.google.android.exoplayer.chunk.ChunkSampleSource; -import com.google.android.exoplayer.chunk.ChunkSource; -import com.google.android.exoplayer.chunk.FormatEvaluator; -import com.google.android.exoplayer.chunk.FormatEvaluator.AdaptiveEvaluator; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilder; -import com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilderCallback; -import com.google.android.exoplayer.smoothstreaming.SmoothStreamingChunkSource; -import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest; -import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.StreamElement; -import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.TrackElement; -import com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifestParser; -import com.google.android.exoplayer.upstream.BufferPool; -import com.google.android.exoplayer.upstream.DataSource; -import com.google.android.exoplayer.upstream.DefaultBandwidthMeter; -import com.google.android.exoplayer.upstream.UriDataSource; -import com.google.android.exoplayer.util.ManifestFetcher; -import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback; -import com.google.android.exoplayer.util.Util; - -import android.media.MediaCodec; -import android.os.Handler; - -import java.io.IOException; -import java.util.ArrayList; - -/** - * A {@link RendererBuilder} for SmoothStreaming. - */ -/* package */ class SmoothStreamingRendererBuilder implements RendererBuilder, - ManifestCallback { - - private static final int BUFFER_SEGMENT_SIZE = 64 * 1024; - private static final int VIDEO_BUFFER_SEGMENTS = 200; - private static final int AUDIO_BUFFER_SEGMENTS = 60; - private static final int LIVE_EDGE_LATENCY_MS = 30000; - - private final SimplePlayerActivity playerActivity; - private final String userAgent; - private final String url; - private final String contentId; - - private RendererBuilderCallback callback; - private ManifestFetcher manifestFetcher; - - public SmoothStreamingRendererBuilder(SimplePlayerActivity playerActivity, String userAgent, - String url, String contentId) { - this.playerActivity = playerActivity; - this.userAgent = userAgent; - this.url = url; - this.contentId = contentId; - } - - @Override - public void buildRenderers(RendererBuilderCallback callback) { - this.callback = callback; - SmoothStreamingManifestParser parser = new SmoothStreamingManifestParser(); - manifestFetcher = new ManifestFetcher(parser, contentId, - url + "/Manifest", userAgent); - manifestFetcher.singleLoad(playerActivity.getMainLooper(), this); - } - - @Override - public void onManifestError(String contentId, IOException e) { - callback.onRenderersError(e); - } - - @Override - public void onManifest(String contentId, SmoothStreamingManifest manifest) { - Handler mainHandler = playerActivity.getMainHandler(); - LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE)); - DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); - - // Obtain stream elements for playback. - int maxDecodableFrameSize; - try { - maxDecodableFrameSize = MediaCodecUtil.maxH264DecodableFrameSize(); - } catch (DecoderQueryException e) { - callback.onRenderersError(e); - return; - } - int audioStreamElementIndex = -1; - int videoStreamElementIndex = -1; - ArrayList videoTrackIndexList = new ArrayList(); - for (int i = 0; i < manifest.streamElements.length; i++) { - if (audioStreamElementIndex == -1 - && manifest.streamElements[i].type == StreamElement.TYPE_AUDIO) { - audioStreamElementIndex = i; - } else if (videoStreamElementIndex == -1 - && manifest.streamElements[i].type == StreamElement.TYPE_VIDEO) { - videoStreamElementIndex = i; - StreamElement streamElement = manifest.streamElements[i]; - for (int j = 0; j < streamElement.tracks.length; j++) { - TrackElement trackElement = streamElement.tracks[j]; - if (trackElement.maxWidth * trackElement.maxHeight <= maxDecodableFrameSize) { - videoTrackIndexList.add(j); - } else { - // The device isn't capable of playing this stream. - } - } - } - } - int[] videoTrackIndices = Util.toArray(videoTrackIndexList); - - // Build the video renderer. - DataSource videoDataSource = new UriDataSource(userAgent, bandwidthMeter); - ChunkSource videoChunkSource = new SmoothStreamingChunkSource(manifestFetcher, - videoStreamElementIndex, videoTrackIndices, videoDataSource, - new AdaptiveEvaluator(bandwidthMeter), LIVE_EDGE_LATENCY_MS); - ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, - VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); - MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(videoSampleSource, - MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, mainHandler, playerActivity, 50); - - // Build the audio renderer. - DataSource audioDataSource = new UriDataSource(userAgent, bandwidthMeter); - ChunkSource audioChunkSource = new SmoothStreamingChunkSource(manifestFetcher, - audioStreamElementIndex, new int[] {0}, audioDataSource, - new FormatEvaluator.FixedEvaluator(), LIVE_EDGE_LATENCY_MS); - SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, - AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true); - MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer( - audioSampleSource); - callback.onRenderers(videoRenderer, audioRenderer); - } - -} diff --git a/demo/src/main/res/layout/player_activity_full.xml b/demo/src/main/res/layout/player_activity.xml similarity index 100% rename from demo/src/main/res/layout/player_activity_full.xml rename to demo/src/main/res/layout/player_activity.xml diff --git a/demo/src/main/res/layout/player_activity_simple.xml b/demo/src/main/res/layout/player_activity_simple.xml deleted file mode 100644 index 767f20439f..0000000000 --- a/demo/src/main/res/layout/player_activity_simple.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -