Merge pull request #1058 from react-native-community/feature/use-texture-view

ExoPlayer TextureView support
This commit is contained in:
Hampton Maxwell 2018-06-08 00:09:10 -07:00 committed by GitHub
commit b7d6af024b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 20 deletions

View File

@ -232,6 +232,7 @@ var styles = StyleSheet.create({
* [resizeMode](#resizemode) * [resizeMode](#resizemode)
* [selectedTextTrack](#selectedtexttrack) * [selectedTextTrack](#selectedtexttrack)
* [stereoPan](#stereopan) * [stereoPan](#stereopan)
* [useTextureView](#usetextureview)
* [volume](#volume) * [volume](#volume)
#### ignoreSilentSwitch #### ignoreSilentSwitch
@ -346,6 +347,16 @@ Adjust the balance of the left and right audio channels. Any value between 1
Platforms: Android MediaPlayer Platforms: Android MediaPlayer
#### useTextureView
Output to a TextureView instead of the default SurfaceView. In general you will want to use SurfaceView because it provides better performance. However, SurfaceViews can't be animated, transformed or scaled. You also can't overlay multiple SurfaceViews.
useTextureView can only be set at same time you're setting the source.
* **false (default)** - Use a SurfaceView
* **true** - Use a TextureView
Platforms: Android ExoPlayer
#### volume #### volume
Adjust the volume. Adjust the volume.
* **1.0 (default)** - Play at full volume * **1.0 (default)** - Play at full volume

View File

@ -293,6 +293,7 @@ Video.propTypes = {
controls: PropTypes.bool, controls: PropTypes.bool,
currentTime: PropTypes.number, currentTime: PropTypes.number,
progressUpdateInterval: PropTypes.number, progressUpdateInterval: PropTypes.number,
useTextureView: PropTypes.bool,
onLoadStart: PropTypes.func, onLoadStart: PropTypes.func,
onLoad: PropTypes.func, onLoad: PropTypes.func,
onBuffer: PropTypes.func, onBuffer: PropTypes.func,

View File

@ -25,17 +25,20 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.SubtitleView; import com.google.android.exoplayer2.ui.SubtitleView;
import java.util.List; import java.util.List;
import java.lang.Object;
@TargetApi(16) @TargetApi(16)
public final class ExoPlayerView extends FrameLayout { public final class ExoPlayerView extends FrameLayout {
private final View surfaceView; private View surfaceView;
private final View shutterView; private final View shutterView;
private final SubtitleView subtitleLayout; private final SubtitleView subtitleLayout;
private final AspectRatioFrameLayout layout; private final AspectRatioFrameLayout layout;
private final ComponentListener componentListener; private final ComponentListener componentListener;
private SimpleExoPlayer player; private SimpleExoPlayer player;
private Context context;
private ViewGroup.LayoutParams layoutParams;
private boolean useTextureView = false;
public ExoPlayerView(Context context) { public ExoPlayerView(Context context) {
this(context, null); this(context, null);
@ -48,9 +51,9 @@ public final class ExoPlayerView extends FrameLayout {
public ExoPlayerView(Context context, AttributeSet attrs, int defStyleAttr) { public ExoPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
boolean useTextureView = false; this.context = context;
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( layoutParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT); ViewGroup.LayoutParams.MATCH_PARENT);
@ -64,25 +67,45 @@ public final class ExoPlayerView extends FrameLayout {
layout.setLayoutParams(aspectRatioParams); layout.setLayoutParams(aspectRatioParams);
shutterView = new View(getContext()); shutterView = new View(getContext());
shutterView.setLayoutParams(params); shutterView.setLayoutParams(layoutParams);
shutterView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.black)); shutterView.setBackgroundColor(ContextCompat.getColor(context, android.R.color.black));
subtitleLayout = new SubtitleView(context); subtitleLayout = new SubtitleView(context);
subtitleLayout.setLayoutParams(params); subtitleLayout.setLayoutParams(layoutParams);
subtitleLayout.setUserDefaultStyle(); subtitleLayout.setUserDefaultStyle();
subtitleLayout.setUserDefaultTextSize(); subtitleLayout.setUserDefaultTextSize();
View view = useTextureView ? new TextureView(context) : new SurfaceView(context); updateSurfaceView();
view.setLayoutParams(params);
surfaceView = view;
layout.addView(surfaceView, 0, params); layout.addView(shutterView, 1, layoutParams);
layout.addView(shutterView, 1, params); layout.addView(subtitleLayout, 2, layoutParams);
layout.addView(subtitleLayout, 2, params);
addViewInLayout(layout, 0, aspectRatioParams); addViewInLayout(layout, 0, aspectRatioParams);
} }
private void setVideoView() {
if (surfaceView instanceof TextureView) {
player.setVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SurfaceView) {
player.setVideoSurfaceView((SurfaceView) surfaceView);
}
}
private void updateSurfaceView() {
View view = useTextureView ? new TextureView(context) : new SurfaceView(context);
view.setLayoutParams(layoutParams);
surfaceView = view;
if (layout.getChildAt(0) != null) {
layout.removeViewAt(0);
}
layout.addView(surfaceView, 0, layoutParams);
if (this.player != null) {
setVideoView();
}
}
/** /**
* Set the {@link SimpleExoPlayer} to use. The {@link SimpleExoPlayer#setTextOutput} and * Set the {@link SimpleExoPlayer} to use. The {@link SimpleExoPlayer#setTextOutput} and
* {@link SimpleExoPlayer#setVideoListener} method of the player will be called and previous * {@link SimpleExoPlayer#setVideoListener} method of the player will be called and previous
@ -103,11 +126,7 @@ public final class ExoPlayerView extends FrameLayout {
this.player = player; this.player = player;
shutterView.setVisibility(VISIBLE); shutterView.setVisibility(VISIBLE);
if (player != null) { if (player != null) {
if (surfaceView instanceof TextureView) { setVideoView();
player.setVideoTextureView((TextureView) surfaceView);
} else if (surfaceView instanceof SurfaceView) {
player.setVideoSurfaceView((SurfaceView) surfaceView);
}
player.setVideoListener(componentListener); player.setVideoListener(componentListener);
player.addListener(componentListener); player.addListener(componentListener);
player.setTextOutput(componentListener); player.setTextOutput(componentListener);
@ -137,6 +156,11 @@ public final class ExoPlayerView extends FrameLayout {
return surfaceView; return surfaceView;
} }
public void setUseTextureView(boolean useTextureView) {
this.useTextureView = useTextureView;
updateSurfaceView();
}
private final Runnable measureAndLayout = new Runnable() { private final Runnable measureAndLayout = new Runnable() {
@Override @Override
public void run() { public void run() {

View File

@ -5,14 +5,12 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.accessibility.CaptioningManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.brentvatne.react.R; import com.brentvatne.react.R;
@ -61,7 +59,6 @@ import java.net.CookieManager;
import java.net.CookiePolicy; import java.net.CookiePolicy;
import java.lang.Math; import java.lang.Math;
import java.lang.Object; import java.lang.Object;
import java.util.Locale;
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
class ReactExoplayerView extends FrameLayout implements class ReactExoplayerView extends FrameLayout implements
@ -109,6 +106,7 @@ class ReactExoplayerView extends FrameLayout implements
private boolean disableFocus; private boolean disableFocus;
private float mProgressUpdateInterval = 250.0f; private float mProgressUpdateInterval = 250.0f;
private boolean playInBackground = false; private boolean playInBackground = false;
private boolean useTextureView = false;
// \ End props // \ End props
// React // React
@ -780,4 +778,8 @@ class ReactExoplayerView extends FrameLayout implements
eventEmitter.fullscreenDidDismiss(); eventEmitter.fullscreenDidDismiss();
} }
} }
public void setUseTextureView(boolean useTextureView) {
exoPlayerView.setUseTextureView(useTextureView);
}
} }

View File

@ -37,6 +37,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_PLAY_IN_BACKGROUND = "playInBackground"; private static final String PROP_PLAY_IN_BACKGROUND = "playInBackground";
private static final String PROP_DISABLE_FOCUS = "disableFocus"; private static final String PROP_DISABLE_FOCUS = "disableFocus";
private static final String PROP_FULLSCREEN = "fullscreen"; private static final String PROP_FULLSCREEN = "fullscreen";
private static final String PROP_USE_TEXTURE_VIEW = "useTextureView";
@Override @Override
public String getName() { public String getName() {
@ -175,6 +176,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
videoView.setFullscreen(fullscreen); videoView.setFullscreen(fullscreen);
} }
@ReactProp(name = PROP_USE_TEXTURE_VIEW, defaultBoolean = false)
public void setUseTextureView(final ReactExoplayerView videoView, final boolean useTextureView) {
videoView.setUseTextureView(useTextureView);
}
private boolean startsWithValidScheme(String uriString) { private boolean startsWithValidScheme(String uriString) {
return uriString.startsWith("http://") return uriString.startsWith("http://")
|| uriString.startsWith("https://") || uriString.startsWith("https://")