|
64 | 64 | import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
65 | 65 | import com.google.android.exoplayer2.util.MimeTypes;
|
66 | 66 | import com.google.android.exoplayer2.util.Util;
|
| 67 | +import com.google.android.exoplayer2.ui.PlayerControlView; |
67 | 68 |
|
68 | 69 | import java.net.CookieHandler;
|
69 | 70 | import java.net.CookieManager;
|
@@ -96,6 +97,9 @@ class ReactExoplayerView extends FrameLayout implements
|
96 | 97 | }
|
97 | 98 |
|
98 | 99 | private final VideoEventEmitter eventEmitter;
|
| 100 | + private PlayerControlView playerControlView; |
| 101 | + private View playPauseControlContainer; |
| 102 | + private Player.EventListener eventListener; |
99 | 103 |
|
100 | 104 | private Handler mainHandler;
|
101 | 105 | private ExoPlayerView exoPlayerView;
|
@@ -257,6 +261,76 @@ public void onBandwidthSample(int elapsedMs, long bytes, long bitrate) {
|
257 | 261 | }
|
258 | 262 |
|
259 | 263 | // Internal methods
|
| 264 | + |
| 265 | + /** |
| 266 | + * Toggling the visibility of the player control view |
| 267 | + */ |
| 268 | + private void togglePlayerControlVisibility() { |
| 269 | + reLayout(playerControlView); |
| 270 | + if (playerControlView.isVisible()) { |
| 271 | + playerControlView.hide(); |
| 272 | + } else { |
| 273 | + playerControlView.show(); |
| 274 | + } |
| 275 | + } |
| 276 | + |
| 277 | + /** |
| 278 | + * Initializing Player control |
| 279 | + */ |
| 280 | + private void initializePlayerControl() { |
| 281 | + if (playerControlView == null) { |
| 282 | + playerControlView = new PlayerControlView(getContext()); |
| 283 | + } |
| 284 | + |
| 285 | + // Setting the player for the playerControlView |
| 286 | + playerControlView.setPlayer(player); |
| 287 | + playerControlView.show(); |
| 288 | + playPauseControlContainer = playerControlView.findViewById(R.id.exo_play_pause_container); |
| 289 | + |
| 290 | + // Invoking onClick event for exoplayerView |
| 291 | + exoPlayerView.setOnClickListener(new OnClickListener() { |
| 292 | + @Override |
| 293 | + public void onClick(View v) { |
| 294 | + togglePlayerControlVisibility(); |
| 295 | + } |
| 296 | + }); |
| 297 | + |
| 298 | + // Invoking onPlayerStateChanged event for Player |
| 299 | + eventListener = new Player.EventListener() { |
| 300 | + @Override |
| 301 | + public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { |
| 302 | + reLayout(playPauseControlContainer); |
| 303 | + //Remove this eventListener once its executed. since UI will work fine once after the reLayout is done |
| 304 | + player.removeListener(eventListener); |
| 305 | + } |
| 306 | + }; |
| 307 | + player.addListener(eventListener); |
| 308 | + } |
| 309 | + |
| 310 | + /** |
| 311 | + * Adding Player control to the frame layout |
| 312 | + */ |
| 313 | + private void addPlayerControl() { |
| 314 | + LayoutParams layoutParams = new LayoutParams( |
| 315 | + LayoutParams.MATCH_PARENT, |
| 316 | + LayoutParams.MATCH_PARENT); |
| 317 | + playerControlView.setLayoutParams(layoutParams); |
| 318 | + addView(playerControlView, 1, layoutParams); |
| 319 | + } |
| 320 | + |
| 321 | + /** |
| 322 | + * Update the layout |
| 323 | + * @param view view needs to update layout |
| 324 | + * |
| 325 | + * This is a workaround for the open bug in react-native: https://github.com/facebook/react-native/issues/17968 |
| 326 | + */ |
| 327 | + private void reLayout(View view) { |
| 328 | + if (view == null) return; |
| 329 | + view.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY), |
| 330 | + MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY)); |
| 331 | + view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight()); |
| 332 | + } |
| 333 | + |
260 | 334 | private void initializePlayer() {
|
261 | 335 | if (player == null) {
|
262 | 336 | TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
|
@@ -302,6 +376,9 @@ private void initializePlayer() {
|
302 | 376 | eventEmitter.loadStart();
|
303 | 377 | loadVideoStarted = true;
|
304 | 378 | }
|
| 379 | + |
| 380 | + // Initializing the playerControlView |
| 381 | + initializePlayerControl(); |
305 | 382 | }
|
306 | 383 |
|
307 | 384 | private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
|
@@ -517,6 +594,10 @@ public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
517 | 594 | onBuffering(false);
|
518 | 595 | startProgressHandler();
|
519 | 596 | videoLoaded();
|
| 597 | + //Setting the visibility for the playerControlView |
| 598 | + if(playerControlView != null) { |
| 599 | + playerControlView.show(); |
| 600 | + } |
520 | 601 | break;
|
521 | 602 | case ExoPlayer.STATE_ENDED:
|
522 | 603 | text += "ended";
|
@@ -1056,4 +1137,17 @@ public void setBufferConfig(int newMinBufferMs, int newMaxBufferMs, int newBuffe
|
1056 | 1137 | releasePlayer();
|
1057 | 1138 | initializePlayer();
|
1058 | 1139 | }
|
| 1140 | + |
| 1141 | + /** |
| 1142 | + * Handling controls prop |
| 1143 | + * |
| 1144 | + * @param controls Controls prop, if true enable controls, if false disable them |
| 1145 | + */ |
| 1146 | + public void setControls(boolean controls) { |
| 1147 | + if (controls && exoPlayerView != null) { |
| 1148 | + addPlayerControl(); |
| 1149 | + } else if (getChildAt(1) instanceof PlayerControlView && exoPlayerView != null) { |
| 1150 | + removeViewAt(1); |
| 1151 | + } |
| 1152 | + } |
1059 | 1153 | }
|
0 commit comments