Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for displaying controls in Android Exoplayer #1414

Merged
merged 9 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,9 @@ Determines whether to show player controls.

Note on iOS, controls are always shown when in fullscreen mode.

Controls are not available Android because the system does not provide a stock set of controls. You will need to build your own or use a package like [react-native-video-controls](https://github.com/itsnubix/react-native-video-controls) or [react-native-video-player](https://github.com/cornedor/react-native-video-player).
For Android MediaPlayer, you will need to build your own controls or use a package like [react-native-video-controls](https://github.com/itsnubix/react-native-video-controls) or [react-native-video-player](https://github.com/cornedor/react-native-video-player).

Platforms: iOS, react-native-dom
Platforms: Android ExoPlayer, iOS, react-native-dom

#### filter
Add video filter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.ui.PlayerControlView;

import java.net.CookieHandler;
import java.net.CookieManager;
Expand Down Expand Up @@ -96,6 +97,9 @@ class ReactExoplayerView extends FrameLayout implements
}

private final VideoEventEmitter eventEmitter;
private PlayerControlView playerControlView;
private View playPauseControlContainer;
private Player.EventListener eventListener;

private Handler mainHandler;
private ExoPlayerView exoPlayerView;
Expand Down Expand Up @@ -257,6 +261,76 @@ public void onBandwidthSample(int elapsedMs, long bytes, long bitrate) {
}

// Internal methods

/**
* Toggling the visibility of the player control view
*/
private void togglePlayerControlVisibility() {
reLayout(playerControlView);
if (playerControlView.isVisible()) {
playerControlView.hide();
} else {
playerControlView.show();
}
}

/**
* Initializing Player control
*/
private void initializePlayerControl() {
if (playerControlView == null) {
playerControlView = new PlayerControlView(getContext());
}

// Setting the player for the playerControlView
playerControlView.setPlayer(player);
playerControlView.show();
playPauseControlContainer = playerControlView.findViewById(R.id.exo_play_pause_container);

// Invoking onClick event for exoplayerView
exoPlayerView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
togglePlayerControlVisibility();
}
});

// Invoking onPlayerStateChanged event for Player
eventListener = new Player.EventListener() {
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
reLayout(playPauseControlContainer);
//Remove this eventListener once its executed. since UI will work fine once after the reLayout is done
player.removeListener(eventListener);
IbrahimSulai marked this conversation as resolved.
Show resolved Hide resolved
}
};
player.addListener(eventListener);
}

/**
* Adding Player control to the frame layout
*/
private void addPlayerControl() {
LayoutParams layoutParams = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
playerControlView.setLayoutParams(layoutParams);
addView(playerControlView, 1, layoutParams);
}

/**
* Update the layout
* @param view view needs to update layout
*
* This is a workaround for the open bug in react-native: https://github.com/facebook/react-native/issues/17968
*/
private void reLayout(View view) {
if (view == null) return;
view.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
view.layout(view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight());
}

private void initializePlayer() {
if (player == null) {
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
Expand Down Expand Up @@ -302,6 +376,9 @@ private void initializePlayer() {
eventEmitter.loadStart();
loadVideoStarted = true;
}

// Initializing the playerControlView
initializePlayerControl();
}

private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
Expand Down Expand Up @@ -517,6 +594,10 @@ public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
onBuffering(false);
startProgressHandler();
videoLoaded();
//Setting the visibility for the playerControlView
if(playerControlView != null) {
playerControlView.show();
}
break;
case ExoPlayer.STATE_ENDED:
text += "ended";
Expand Down Expand Up @@ -1056,4 +1137,17 @@ public void setBufferConfig(int newMinBufferMs, int newMaxBufferMs, int newBuffe
releasePlayer();
initializePlayer();
}

/**
* Handling controls prop
*
* @param controls Controls prop, if true enable controls, if false disable them
*/
public void setControls(boolean controls) {
if (controls && exoPlayerView != null) {
addPlayerControl();
} else if (getChildAt(1) instanceof PlayerControlView && exoPlayerView != null) {
removeViewAt(1);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_SELECTED_VIDEO_TRACK_TYPE = "type";
private static final String PROP_SELECTED_VIDEO_TRACK_VALUE = "value";
private static final String PROP_HIDE_SHUTTER_VIEW = "hideShutterView";
private static final String PROP_CONTROLS = "controls";

@Override
public String getName() {
Expand Down Expand Up @@ -255,6 +256,11 @@ public void setHideShutterView(final ReactExoplayerView videoView, final boolean
videoView.setHideShutterView(hideShutterView);
}

@ReactProp(name = PROP_CONTROLS, defaultBoolean = false)
public void setControls(final ReactExoplayerView videoView, final boolean controls) {
videoView.setControls(controls);
}

@ReactProp(name = PROP_BUFFER_CONFIG)
public void setBufferConfig(final ReactExoplayerView videoView, @Nullable ReadableMap bufferConfig) {
int minBufferMs = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS;
Expand Down
76 changes: 76 additions & 0 deletions android-exoplayer/src/main/res/layout/exo_player_control_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layoutDirection="ltr"
android:background="#CC000000"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="4dp"
android:orientation="horizontal">

<ImageButton android:id="@id/exo_prev"
style="@style/ExoMediaButton.Previous"/>

<ImageButton android:id="@id/exo_rew"
style="@style/ExoMediaButton.Rewind"/>
<FrameLayout
android:id="@+id/exo_play_pause_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageButton android:id="@id/exo_play"
style="@style/ExoMediaButton.Play"/>

<ImageButton android:id="@id/exo_pause"
style="@style/ExoMediaButton.Pause"/>
</FrameLayout>

<ImageButton android:id="@id/exo_ffwd"
style="@style/ExoMediaButton.FastForward"/>

<ImageButton android:id="@id/exo_next"
style="@style/ExoMediaButton.Next"/>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<TextView android:id="@id/exo_position"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/>

<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="26dp"/>

<TextView android:id="@id/exo_duration"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:includeFontPadding="false"
android:textColor="#FFBEBEBE"/>
</LinearLayout>

</LinearLayout>