Merge pull request #1058 from react-native-community/feature/use-texture-view
ExoPlayer TextureView support
This commit is contained in:
commit
b7d6af024b
11
README.md
11
README.md
@ -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
|
||||||
|
1
Video.js
1
Video.js
@ -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,
|
||||||
|
@ -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() {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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://")
|
||||||
|
Loading…
Reference in New Issue
Block a user