metadata) {
428 | if (id3MetadataListener != null && getSelectedTrack(TYPE_METADATA) != TRACK_DISABLED) {
429 | id3MetadataListener.onId3Metadata(metadata);
430 | }
431 | }
432 |
433 | @Override
434 | public void onAvailableRangeChanged(TimeRange availableRange) {
435 | if (infoListener != null) {
436 | infoListener.onAvailableRangeChanged(availableRange);
437 | }
438 | }
439 |
440 | @Override
441 | public void onPlayWhenReadyCommitted() {
442 | // Do nothing.
443 | }
444 |
445 | @Override
446 | public void onDrawnToSurface(Surface surface) {
447 | // Do nothing.
448 | }
449 |
450 | @Override
451 | public void onLoadStarted(int sourceId, long length, int type, int trigger, Format format,
452 | long mediaStartTimeMs, long mediaEndTimeMs) {
453 | if (infoListener != null) {
454 | infoListener.onLoadStarted(sourceId, length, type, trigger, format, mediaStartTimeMs,
455 | mediaEndTimeMs);
456 | }
457 | }
458 |
459 | @Override
460 | public void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format,
461 | long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs) {
462 | if (infoListener != null) {
463 | infoListener.onLoadCompleted(sourceId, bytesLoaded, type, trigger, format, mediaStartTimeMs,
464 | mediaEndTimeMs, elapsedRealtimeMs, loadDurationMs);
465 | }
466 | }
467 |
468 | @Override
469 | public void onLoadCanceled(int sourceId, long bytesLoaded) {
470 | // Do nothing.
471 | }
472 |
473 | @Override
474 | public void onUpstreamDiscarded(int sourceId, long mediaStartTimeMs, long mediaEndTimeMs) {
475 | // Do nothing.
476 | }
477 |
478 | private void maybeReportPlayerState() {
479 | boolean playWhenReady = player.getPlayWhenReady();
480 | int playbackState = getPlaybackState();
481 | if (lastReportedPlayWhenReady != playWhenReady || lastReportedPlaybackState != playbackState) {
482 | for (Listener listener : listeners) {
483 | listener.onStateChanged(playWhenReady, playbackState);
484 | }
485 | lastReportedPlayWhenReady = playWhenReady;
486 | lastReportedPlaybackState = playbackState;
487 | }
488 | }
489 |
490 | private void pushSurface(boolean blockForSurfacePush) {
491 | if (videoRenderer == null) {
492 | return;
493 | }
494 |
495 | if (blockForSurfacePush) {
496 | player.blockingSendMessage(
497 | videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
498 | } else {
499 | player.sendMessage(
500 | videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
501 | }
502 | }
503 |
504 | /**
505 | * Builds renderers for the player.
506 | */
507 | public interface RendererBuilder {
508 | /**
509 | * Builds renderers for playback.
510 | *
511 | * @param player The player for which renderers are being built. {@link gujarat.videoplayaer.player.DemoPlayer#onRenderers}
512 | * should be invoked once the renderers have been built. If building fails,
513 | * {@link gujarat.videoplayaer.player.DemoPlayer#onRenderersError} should be invoked.
514 | */
515 | void buildRenderers(DemoPlayer player);
516 | /**
517 | * Cancels the current build operation, if there is one. Else does nothing.
518 | *
519 | * A canceled build operation must not invoke {@link gujarat.videoplayaer.player.DemoPlayer#onRenderers} or
520 | * {@link gujarat.videoplayaer.player.DemoPlayer#onRenderersError} on the player, which may have been released.
521 | */
522 | void cancel();
523 | }
524 |
525 | /**
526 | * A listener for core events.
527 | */
528 | public interface Listener {
529 | void onStateChanged(boolean playWhenReady, int playbackState);
530 | void onError(Exception e);
531 | void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
532 | float pixelWidthHeightRatio);
533 | }
534 |
535 | /**
536 | * A listener for internal errors.
537 | *
538 | * These errors are not visible to the user, and hence this listener is provided for
539 | * informational purposes only. Note however that an internal error may cause a fatal
540 | * error if the player fails to recover. If this happens, {@link gujarat.videoplayaer.player.DemoPlayer.Listener#onError(Exception)}
541 | * will be invoked.
542 | */
543 | public interface InternalErrorListener {
544 | void onRendererInitializationError(Exception e);
545 | void onAudioTrackInitializationError(AudioTrack.InitializationException e);
546 | void onAudioTrackWriteError(AudioTrack.WriteException e);
547 | void onDecoderInitializationError(DecoderInitializationException e);
548 | void onCryptoError(CryptoException e);
549 | void onLoadError(int sourceId, IOException e);
550 | void onDrmSessionManagerError(Exception e);
551 | }
552 |
553 | /**
554 | * A listener for debugging information.
555 | */
556 | public interface InfoListener {
557 | void onVideoFormatEnabled(Format format, int trigger, long mediaTimeMs);
558 | void onAudioFormatEnabled(Format format, int trigger, long mediaTimeMs);
559 | void onDroppedFrames(int count, long elapsed);
560 | void onBandwidthSample(int elapsedMs, long bytes, long bitrateEstimate);
561 | void onLoadStarted(int sourceId, long length, int type, int trigger, Format format,
562 | long mediaStartTimeMs, long mediaEndTimeMs);
563 | void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format,
564 | long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs);
565 | void onDecoderInitialized(String decoderName, long elapsedRealtimeMs,
566 | long initializationDurationMs);
567 | void onAvailableRangeChanged(TimeRange availableRange);
568 | }
569 |
570 | /**
571 | * A listener for receiving notifications of timed text.
572 | */
573 | public interface CaptionListener {
574 | void onCues(List cues);
575 | }
576 |
577 | /**
578 | * A listener for receiving ID3 metadata parsed from the media stream.
579 | */
580 | public interface Id3MetadataListener {
581 | void onId3Metadata(Map metadata);
582 | }
583 |
584 | }
585 |
--------------------------------------------------------------------------------
/app/src/main/java/gujarat/videoplayaer/player/ExtractorRendererBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package gujarat.videoplayaer.player;
17 |
18 | import android.content.Context;
19 | import android.media.MediaCodec;
20 | import android.net.Uri;
21 |
22 | import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
23 | import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
24 | import com.google.android.exoplayer.TrackRenderer;
25 | import com.google.android.exoplayer.audio.AudioCapabilities;
26 | import com.google.android.exoplayer.extractor.ExtractorSampleSource;
27 | import com.google.android.exoplayer.text.TextTrackRenderer;
28 | import com.google.android.exoplayer.upstream.Allocator;
29 | import com.google.android.exoplayer.upstream.DataSource;
30 | import com.google.android.exoplayer.upstream.DefaultAllocator;
31 | import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
32 | import com.google.android.exoplayer.upstream.DefaultUriDataSource;
33 |
34 | /**
35 | * A {@link RendererBuilder} for streams that can be read using an {@link com.google.android.exoplayer.extractor.Extractor}.
36 | */
37 | public class ExtractorRendererBuilder implements DemoPlayer.RendererBuilder {
38 |
39 | private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
40 | private static final int BUFFER_SEGMENT_COUNT = 256;
41 |
42 | private final Context context;
43 | private final String userAgent;
44 | private final Uri uri;
45 |
46 | public ExtractorRendererBuilder(Context context, String userAgent, Uri uri) {
47 | this.context = context;
48 | this.userAgent = userAgent;
49 | this.uri = uri;
50 | }
51 |
52 | @Override
53 | public void buildRenderers(DemoPlayer player) {
54 | Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
55 |
56 | // Build the video and audio renderers.
57 | DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(),
58 | null);
59 | DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
60 | ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
61 | BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
62 | MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
63 | sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, player.getMainHandler(),
64 | player, 50);
65 | MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
66 | null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context));
67 | TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
68 | player.getMainHandler().getLooper());
69 |
70 | // Invoke the callback.
71 | TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
72 | renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
73 | renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
74 | renderers[DemoPlayer.TYPE_TEXT] = textRenderer;
75 | player.onRenderers(renderers, bandwidthMeter);
76 | }
77 |
78 | @Override
79 | public void cancel() {
80 | // Do nothing.
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/gujarat/videoplayaer/player/HlsRendererBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package gujarat.videoplayaer.player;
17 |
18 | import android.content.Context;
19 | import android.media.MediaCodec;
20 | import android.os.Handler;
21 |
22 | import com.google.android.exoplayer.DefaultLoadControl;
23 | import com.google.android.exoplayer.LoadControl;
24 | import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
25 | import com.google.android.exoplayer.MediaCodecUtil.DecoderQueryException;
26 | import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
27 | import com.google.android.exoplayer.TrackRenderer;
28 | import com.google.android.exoplayer.audio.AudioCapabilities;
29 | import com.google.android.exoplayer.chunk.VideoFormatSelectorUtil;
30 | import com.google.android.exoplayer.hls.HlsChunkSource;
31 | import com.google.android.exoplayer.hls.HlsMasterPlaylist;
32 | import com.google.android.exoplayer.hls.HlsPlaylist;
33 | import com.google.android.exoplayer.hls.HlsPlaylistParser;
34 | import com.google.android.exoplayer.hls.HlsSampleSource;
35 | import com.google.android.exoplayer.metadata.Id3Parser;
36 | import com.google.android.exoplayer.metadata.MetadataTrackRenderer;
37 | import com.google.android.exoplayer.text.eia608.Eia608TrackRenderer;
38 | import com.google.android.exoplayer.upstream.DataSource;
39 | import com.google.android.exoplayer.upstream.DefaultAllocator;
40 | import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
41 | import com.google.android.exoplayer.upstream.DefaultUriDataSource;
42 | import com.google.android.exoplayer.util.ManifestFetcher;
43 | import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
44 |
45 | import java.io.IOException;
46 | import java.util.Map;
47 |
48 | /**
49 | * A {@link RendererBuilder} for HLS.
50 | */
51 | public class HlsRendererBuilder implements DemoPlayer.RendererBuilder {
52 |
53 | private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
54 | private static final int BUFFER_SEGMENTS = 256;
55 |
56 | private final Context context;
57 | private final String userAgent;
58 | private final String url;
59 |
60 | private AsyncRendererBuilder currentAsyncBuilder;
61 |
62 | public HlsRendererBuilder(Context context, String userAgent, String url) {
63 | this.context = context;
64 | this.userAgent = userAgent;
65 | this.url = url;
66 | }
67 |
68 | @Override
69 | public void buildRenderers(DemoPlayer player) {
70 | currentAsyncBuilder = new AsyncRendererBuilder(context, userAgent, url, player);
71 | currentAsyncBuilder.init();
72 | }
73 |
74 | @Override
75 | public void cancel() {
76 | if (currentAsyncBuilder != null) {
77 | currentAsyncBuilder.cancel();
78 | currentAsyncBuilder = null;
79 | }
80 | }
81 |
82 | private static final class AsyncRendererBuilder implements ManifestCallback {
83 |
84 | private final Context context;
85 | private final String userAgent;
86 | private final String url;
87 | private final DemoPlayer player;
88 | private final ManifestFetcher playlistFetcher;
89 |
90 | private boolean canceled;
91 |
92 | public AsyncRendererBuilder(Context context, String userAgent, String url, DemoPlayer player) {
93 | this.context = context;
94 | this.userAgent = userAgent;
95 | this.url = url;
96 | this.player = player;
97 | HlsPlaylistParser parser = new HlsPlaylistParser();
98 | playlistFetcher = new ManifestFetcher<>(url, new DefaultUriDataSource(context, userAgent),
99 | parser);
100 | }
101 |
102 | public void init() {
103 | playlistFetcher.singleLoad(player.getMainHandler().getLooper(), this);
104 | }
105 |
106 | public void cancel() {
107 | canceled = true;
108 | }
109 |
110 | @Override
111 | public void onSingleManifestError(IOException e) {
112 | if (canceled) {
113 | return;
114 | }
115 |
116 | player.onRenderersError(e);
117 | }
118 |
119 | @Override
120 | public void onSingleManifest(HlsPlaylist manifest) {
121 | if (canceled) {
122 | return;
123 | }
124 |
125 | Handler mainHandler = player.getMainHandler();
126 | LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE));
127 | DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
128 |
129 | int[] variantIndices = null;
130 | if (manifest instanceof HlsMasterPlaylist) {
131 | HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest;
132 | try {
133 | variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay(
134 | context, masterPlaylist.variants, null, false);
135 | } catch (DecoderQueryException e) {
136 | player.onRenderersError(e);
137 | return;
138 | }
139 | if (variantIndices.length == 0) {
140 | player.onRenderersError(new IllegalStateException("No variants selected."));
141 | return;
142 | }
143 | }
144 |
145 | DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
146 | HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter,
147 | variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
148 | HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
149 | BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_VIDEO);
150 | MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
151 | sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50);
152 | MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
153 | null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context));
154 | MetadataTrackRenderer