Remove Exoplayer deprecations

- Bump Exoplayer to 2.10.4
- Remove deprecated usages of Exoplayer methdos
- Add `ReactExoplayerConfig` as extension points to configure the Exoplayer instance
This commit is contained in:
Benoit Dion 2019-09-16 16:29:31 -04:00 committed by Benoit Dion
parent 81cfd4e629
commit 3e38f88869
8 changed files with 154 additions and 83 deletions

View File

@ -7,7 +7,7 @@ def safeExtGet(prop, fallback) {
android { android {
compileSdkVersion safeExtGet('compileSdkVersion', 28) compileSdkVersion safeExtGet('compileSdkVersion', 28)
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3') buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
compileOptions { compileOptions {
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -23,18 +23,18 @@ android {
dependencies { dependencies {
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}" implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
implementation('com.google.android.exoplayer:exoplayer:2.9.3') { implementation('com.google.android.exoplayer:exoplayer:2.10.4') {
exclude group: 'com.android.support' exclude group: 'com.android.support'
} }
// All support libs must use the same version // All support libs must use the same version
implementation "androidx.annotation:annotation:1.0.0" implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.core:core:1.0.0" implementation "androidx.core:core:1.1.0"
implementation "androidx.media:media:1.0.0" implementation "androidx.media:media:1.1.0"
implementation('com.google.android.exoplayer:extension-okhttp:2.9.3') { implementation('com.google.android.exoplayer:extension-okhttp:2.10.4') {
exclude group: 'com.squareup.okhttp3', module: 'okhttp' exclude group: 'com.squareup.okhttp3', module: 'okhttp'
} }
implementation 'com.squareup.okhttp3:okhttp:3.12.1' implementation 'com.squareup.okhttp3:okhttp:3.14.3'
} }

View File

@ -1,8 +1,5 @@
package com.brentvatne.exoplayer; package com.brentvatne.exoplayer;
import android.content.Context;
import android.content.ContextWrapper;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.CookieJarContainer; import com.facebook.react.modules.network.CookieJarContainer;
import com.facebook.react.modules.network.ForwardingCookieHandler; import com.facebook.react.modules.network.ForwardingCookieHandler;
@ -14,12 +11,10 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import okhttp3.Cookie;
import okhttp3.JavaNetCookieJar; import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import java.util.Map; import java.util.Map;
public class DataSourceUtil { public class DataSourceUtil {
private DataSourceUtil() { private DataSourceUtil() {

View File

@ -0,0 +1,26 @@
package com.brentvatne.exoplayer;
import android.content.Context;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
public class DefaultReactExoplayerConfig implements ReactExoplayerConfig {
private final DefaultBandwidthMeter bandwidthMeter;
public DefaultReactExoplayerConfig(Context context) {
this.bandwidthMeter = new DefaultBandwidthMeter.Builder(context).build();
}
@Override
public LoadErrorHandlingPolicy buildLoadErrorHandlingPolicy(int minLoadRetryCount) {
return new DefaultLoadErrorHandlingPolicy(minLoadRetryCount);
}
@Override
public DefaultBandwidthMeter getBandwidthMeter() {
return bandwidthMeter;
}
}

View File

@ -15,6 +15,6 @@ class RawResourceDataSourceFactory implements DataSource.Factory {
@Override @Override
public DataSource createDataSource() { public DataSource createDataSource() {
return new RawResourceDataSource(context, null); return new RawResourceDataSource(context);
} }
} }

View File

@ -0,0 +1,13 @@
package com.brentvatne.exoplayer;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
/**
* Extension points to configure the Exoplayer instance
*/
public interface ReactExoplayerConfig {
LoadErrorHandlingPolicy buildLoadErrorHandlingPolicy(int minLoadRetryCount);
DefaultBandwidthMeter getBandwidthMeter();
}

View File

@ -27,26 +27,25 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ThemedReactContext;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer; import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataRenderer; import com.google.android.exoplayer2.metadata.MetadataOutput;
import com.google.android.exoplayer2.source.BehindLiveWindowException; import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource; import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource; import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource; import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.source.hls.HlsMediaSource;
@ -54,42 +53,36 @@ import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; 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.util.Util;
import com.google.android.exoplayer2.ui.PlayerControlView;
import java.net.CookieHandler; import java.net.CookieHandler;
import java.net.CookieManager; import java.net.CookieManager;
import java.net.CookiePolicy; import java.net.CookiePolicy;
import java.lang.Math;
import java.util.Map;
import java.lang.Object;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
class ReactExoplayerView extends FrameLayout implements class ReactExoplayerView extends FrameLayout implements
LifecycleEventListener, LifecycleEventListener,
ExoPlayer.EventListener, Player.EventListener,
BandwidthMeter.EventListener, BandwidthMeter.EventListener,
BecomingNoisyListener, BecomingNoisyListener,
AudioManager.OnAudioFocusChangeListener, AudioManager.OnAudioFocusChangeListener,
MetadataRenderer.Output { MetadataOutput {
private static final String TAG = "ReactExoplayerView"; private static final String TAG = "ReactExoplayerView";
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private static final CookieManager DEFAULT_COOKIE_MANAGER; private static final CookieManager DEFAULT_COOKIE_MANAGER;
private static final int SHOW_PROGRESS = 1; private static final int SHOW_PROGRESS = 1;
private static final int REPORT_BANDWIDTH = 1;
static { static {
DEFAULT_COOKIE_MANAGER = new CookieManager(); DEFAULT_COOKIE_MANAGER = new CookieManager();
@ -97,11 +90,12 @@ class ReactExoplayerView extends FrameLayout implements
} }
private final VideoEventEmitter eventEmitter; private final VideoEventEmitter eventEmitter;
private final ReactExoplayerConfig config;
private final DefaultBandwidthMeter bandwidthMeter;
private PlayerControlView playerControlView; private PlayerControlView playerControlView;
private View playPauseControlContainer; private View playPauseControlContainer;
private Player.EventListener eventListener; private Player.EventListener eventListener;
private Handler mainHandler;
private ExoPlayerView exoPlayerView; private ExoPlayerView exoPlayerView;
private DataSource.Factory mediaDataSourceFactory; private DataSource.Factory mediaDataSourceFactory;
@ -135,8 +129,7 @@ class ReactExoplayerView extends FrameLayout implements
private String audioTrackType; private String audioTrackType;
private Dynamic audioTrackValue; private Dynamic audioTrackValue;
private String videoTrackType; private String videoTrackType;
private Dynamic videoTrackValue; private Dynamic videoTrackValue;
private ReadableArray audioTracks;
private String textTrackType; private String textTrackType;
private Dynamic textTrackValue; private Dynamic textTrackValue;
private ReadableArray textTracks; private ReadableArray textTracks;
@ -159,7 +152,7 @@ class ReactExoplayerView extends FrameLayout implements
switch (msg.what) { switch (msg.what) {
case SHOW_PROGRESS: case SHOW_PROGRESS:
if (player != null if (player != null
&& player.getPlaybackState() == ExoPlayer.STATE_READY && player.getPlaybackState() == Player.STATE_READY
&& player.getPlayWhenReady() && player.getPlayWhenReady()
) { ) {
long pos = player.getCurrentPosition(); long pos = player.getCurrentPosition();
@ -173,14 +166,15 @@ class ReactExoplayerView extends FrameLayout implements
} }
}; };
public ReactExoplayerView(ThemedReactContext context) { public ReactExoplayerView(ThemedReactContext context, ReactExoplayerConfig config) {
super(context); super(context);
this.themedReactContext = context; this.themedReactContext = context;
this.eventEmitter = new VideoEventEmitter(context); this.eventEmitter = new VideoEventEmitter(context);
this.config = config;
this.bandwidthMeter = config.getBandwidthMeter();
createViews(); createViews();
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
themedReactContext.addLifecycleEventListener(this); themedReactContext.addLifecycleEventListener(this);
audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext); audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext);
@ -198,7 +192,6 @@ class ReactExoplayerView extends FrameLayout implements
private void createViews() { private void createViews() {
clearResumePosition(); clearResumePosition();
mediaDataSourceFactory = buildDataSourceFactory(true); mediaDataSourceFactory = buildDataSourceFactory(true);
mainHandler = new Handler();
if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) { if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {
CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER); CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);
} }
@ -266,7 +259,7 @@ class ReactExoplayerView extends FrameLayout implements
// Internal methods // Internal methods
/** /**
* Toggling the visibility of the player control view * Toggling the visibility of the player control view
*/ */
private void togglePlayerControlVisibility() { private void togglePlayerControlVisibility() {
if(player == null) return; if(player == null) return;
@ -342,24 +335,34 @@ class ReactExoplayerView extends FrameLayout implements
private void initializePlayer() { private void initializePlayer() {
ReactExoplayerView self = this; ReactExoplayerView self = this;
// This ensures all props have been setted, to avoid async racing conditions. // This ensures all props have been settled, to avoid async racing conditions.
new Handler().postDelayed(new Runnable() { new Handler().postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
if (player == null) { if (player == null) {
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory();
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelector.setParameters(trackSelector.buildUponParameters() trackSelector.setParameters(trackSelector.buildUponParameters()
.setMaxVideoBitrate(maxBitRate == 0 ? Integer.MAX_VALUE : maxBitRate)); .setMaxVideoBitrate(maxBitRate == 0 ? Integer.MAX_VALUE : maxBitRate));
DefaultAllocator allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE); DefaultAllocator allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE);
DefaultLoadControl defaultLoadControl = new DefaultLoadControl(allocator, minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, -1, true); DefaultLoadControl.Builder defaultLoadControlBuilder = new DefaultLoadControl.Builder();
player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl); defaultLoadControlBuilder.setAllocator(allocator);
defaultLoadControlBuilder.setBufferDurationsMs(minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs);
defaultLoadControlBuilder.setTargetBufferBytes(-1);
defaultLoadControlBuilder.setPrioritizeTimeOverSizeThresholds(true);
DefaultLoadControl defaultLoadControl = defaultLoadControlBuilder.createDefaultLoadControl();
DefaultRenderersFactory renderersFactory =
new DefaultRenderersFactory(getContext())
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
// TODO: Add drmSessionManager to 5th param from: https://github.com/react-native-community/react-native-video/pull/1445
player = ExoPlayerFactory.newSimpleInstance(getContext(), renderersFactory,
trackSelector, defaultLoadControl, null, bandwidthMeter);
player.addListener(self); player.addListener(self);
player.setMetadataOutput(self); player.addMetadataOutput(self);
exoPlayerView.setPlayer(player); exoPlayerView.setPlayer(player);
audioBecomingNoisyReceiver.setListener(self); audioBecomingNoisyReceiver.setListener(self);
BANDWIDTH_METER.addEventListener(new Handler(), self); bandwidthMeter.addEventListener(new Handler(), self);
setPlayWhenReady(!isPaused); setPlayWhenReady(!isPaused);
playerNeedsSource = true; playerNeedsSource = true;
@ -404,21 +407,31 @@ class ReactExoplayerView extends FrameLayout implements
: uri.getLastPathSegment()); : uri.getLastPathSegment());
switch (type) { switch (type) {
case C.TYPE_SS: case C.TYPE_SS:
return new SsMediaSource(uri, buildDataSourceFactory(false), return new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(mediaDataSourceFactory), new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
minLoadRetryCount, SsMediaSource.DEFAULT_LIVE_PRESENTATION_DELAY_MS, buildDataSourceFactory(false)
mainHandler, null); ).setLoadErrorHandlingPolicy(
config.buildLoadErrorHandlingPolicy(minLoadRetryCount)
).createMediaSource(uri);
case C.TYPE_DASH: case C.TYPE_DASH:
return new DashMediaSource(uri, buildDataSourceFactory(false), return new DashMediaSource.Factory(
new DefaultDashChunkSource.Factory(mediaDataSourceFactory), new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
minLoadRetryCount, DashMediaSource.DEFAULT_LIVE_PRESENTATION_DELAY_MS, buildDataSourceFactory(false)
mainHandler, null); ).setLoadErrorHandlingPolicy(
config.buildLoadErrorHandlingPolicy(minLoadRetryCount)
).createMediaSource(uri);
case C.TYPE_HLS: case C.TYPE_HLS:
return new HlsMediaSource(uri, mediaDataSourceFactory, return new HlsMediaSource.Factory(
minLoadRetryCount, mainHandler, null); mediaDataSourceFactory
).setLoadErrorHandlingPolicy(
config.buildLoadErrorHandlingPolicy(minLoadRetryCount)
).createMediaSource(uri);
case C.TYPE_OTHER: case C.TYPE_OTHER:
return new ExtractorMediaSource(uri, mediaDataSourceFactory, new DefaultExtractorsFactory(), return new ProgressiveMediaSource.Factory(
mainHandler, null); mediaDataSourceFactory
).setLoadErrorHandlingPolicy(
config.buildLoadErrorHandlingPolicy(minLoadRetryCount)
).createMediaSource(uri);
default: { default: {
throw new IllegalStateException("Unsupported type: " + type); throw new IllegalStateException("Unsupported type: " + type);
} }
@ -448,21 +461,22 @@ class ReactExoplayerView extends FrameLayout implements
private MediaSource buildTextSource(String title, Uri uri, String mimeType, String language) { private MediaSource buildTextSource(String title, Uri uri, String mimeType, String language) {
Format textFormat = Format.createTextSampleFormat(title, mimeType, Format.NO_VALUE, language); Format textFormat = Format.createTextSampleFormat(title, mimeType, Format.NO_VALUE, language);
return new SingleSampleMediaSource(uri, mediaDataSourceFactory, textFormat, C.TIME_UNSET); return new SingleSampleMediaSource.Factory(mediaDataSourceFactory)
.createMediaSource(uri, textFormat, C.TIME_UNSET);
} }
private void releasePlayer() { private void releasePlayer() {
if (player != null) { if (player != null) {
updateResumePosition(); updateResumePosition();
player.release(); player.release();
player.setMetadataOutput(null); player.removeMetadataOutput(this);
trackSelector = null; trackSelector = null;
player = null; player = null;
} }
progressHandler.removeMessages(SHOW_PROGRESS); progressHandler.removeMessages(SHOW_PROGRESS);
themedReactContext.removeLifecycleEventListener(this); themedReactContext.removeLifecycleEventListener(this);
audioBecomingNoisyReceiver.removeListener(); audioBecomingNoisyReceiver.removeListener();
BANDWIDTH_METER.removeEventListener(this); bandwidthMeter.removeEventListener(this);
} }
private boolean requestAudioFocus() { private boolean requestAudioFocus() {
@ -493,12 +507,12 @@ class ReactExoplayerView extends FrameLayout implements
private void startPlayback() { private void startPlayback() {
if (player != null) { if (player != null) {
switch (player.getPlaybackState()) { switch (player.getPlaybackState()) {
case ExoPlayer.STATE_IDLE: case Player.STATE_IDLE:
case ExoPlayer.STATE_ENDED: case Player.STATE_ENDED:
initializePlayer(); initializePlayer();
break; break;
case ExoPlayer.STATE_BUFFERING: case Player.STATE_BUFFERING:
case ExoPlayer.STATE_READY: case Player.STATE_READY:
if (!player.getPlayWhenReady()) { if (!player.getPlayWhenReady()) {
setPlayWhenReady(true); setPlayWhenReady(true);
} }
@ -551,12 +565,13 @@ class ReactExoplayerView extends FrameLayout implements
/** /**
* Returns a new DataSource factory. * Returns a new DataSource factory.
* *
* @param useBandwidthMeter Whether to set {@link #BANDWIDTH_METER} as a listener to the new * @param useBandwidthMeter Whether to set {@link #bandwidthMeter} as a listener to the new
* DataSource factory. * DataSource factory.
* @return A new DataSource factory. * @return A new DataSource factory.
*/ */
private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) { private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) {
return DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext, useBandwidthMeter ? BANDWIDTH_METER : null, requestHeaders); return DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext,
useBandwidthMeter ? bandwidthMeter : null, requestHeaders);
} }
// AudioManager.OnAudioFocusChangeListener implementation // AudioManager.OnAudioFocusChangeListener implementation
@ -596,7 +611,7 @@ class ReactExoplayerView extends FrameLayout implements
eventEmitter.audioBecomingNoisy(); eventEmitter.audioBecomingNoisy();
} }
// ExoPlayer.EventListener implementation // Player.EventListener implementation
@Override @Override
public void onLoadingChanged(boolean isLoading) { public void onLoadingChanged(boolean isLoading) {
@ -607,26 +622,26 @@ class ReactExoplayerView extends FrameLayout implements
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
String text = "onStateChanged: playWhenReady=" + playWhenReady + ", playbackState="; String text = "onStateChanged: playWhenReady=" + playWhenReady + ", playbackState=";
switch (playbackState) { switch (playbackState) {
case ExoPlayer.STATE_IDLE: case Player.STATE_IDLE:
text += "idle"; text += "idle";
eventEmitter.idle(); eventEmitter.idle();
break; break;
case ExoPlayer.STATE_BUFFERING: case Player.STATE_BUFFERING:
text += "buffering"; text += "buffering";
onBuffering(true); onBuffering(true);
break; break;
case ExoPlayer.STATE_READY: case Player.STATE_READY:
text += "ready"; text += "ready";
eventEmitter.ready(); eventEmitter.ready();
onBuffering(false); onBuffering(false);
startProgressHandler(); startProgressHandler();
videoLoaded(); videoLoaded();
//Setting the visibility for the playerControlView //Setting the visibility for the playerControlView
if(playerControlView != null) { if (playerControlView != null) {
playerControlView.show(); playerControlView.show();
} }
break; break;
case ExoPlayer.STATE_ENDED: case Player.STATE_ENDED:
text += "ended"; text += "ended";
eventEmitter.end(); eventEmitter.end();
onStopPlayback(); onStopPlayback();
@ -752,7 +767,7 @@ class ReactExoplayerView extends FrameLayout implements
} }
// When repeat is turned on, reaching the end of the video will not cause a state change // When repeat is turned on, reaching the end of the video will not cause a state change
// so we need to explicitly detect it. // so we need to explicitly detect it.
if (reason == ExoPlayer.DISCONTINUITY_REASON_PERIOD_TRANSITION if (reason == Player.DISCONTINUITY_REASON_PERIOD_TRANSITION
&& player.getRepeatMode() == Player.REPEAT_MODE_ONE) { && player.getRepeatMode() == Player.REPEAT_MODE_ONE) {
eventEmitter.end(); eventEmitter.end();
} }
@ -870,7 +885,9 @@ class ReactExoplayerView extends FrameLayout implements
this.srcUri = uri; this.srcUri = uri;
this.extension = extension; this.extension = extension;
this.requestHeaders = headers; this.requestHeaders = headers;
this.mediaDataSourceFactory = DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext, BANDWIDTH_METER, this.requestHeaders); this.mediaDataSourceFactory =
DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext, bandwidthMeter,
this.requestHeaders);
if (!isOriginalSourceNull && !isSourceEqual) { if (!isOriginalSourceNull && !isSourceEqual) {
reloadSource(); reloadSource();
@ -884,7 +901,7 @@ class ReactExoplayerView extends FrameLayout implements
public void setReportBandwidth(boolean reportBandwidth) { public void setReportBandwidth(boolean reportBandwidth) {
mReportBandwidth = reportBandwidth; mReportBandwidth = reportBandwidth;
} }
public void setRawSrc(final Uri uri, final String extension) { public void setRawSrc(final Uri uri, final String extension) {
if (uri != null) { if (uri != null) {
@ -1010,7 +1027,7 @@ class ReactExoplayerView extends FrameLayout implements
for (int j = 0; j < group.length; j++) { for (int j = 0; j < group.length; j++) {
tracks[j] = j; tracks[j] = j;
} }
} }
if (groupIndex == C.INDEX_UNSET) { if (groupIndex == C.INDEX_UNSET) {
trackSelector.setParameters(disableParameters); trackSelector.setParameters(disableParameters);
@ -1180,7 +1197,7 @@ class ReactExoplayerView extends FrameLayout implements
/** /**
* Handling controls prop * Handling controls prop
* *
* @param controls Controls prop, if true enable controls, if false disable them * @param controls Controls prop, if true enable controls, if false disable them
*/ */
public void setControls(boolean controls) { public void setControls(boolean controls) {

View File

@ -60,6 +60,12 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_HIDE_SHUTTER_VIEW = "hideShutterView"; private static final String PROP_HIDE_SHUTTER_VIEW = "hideShutterView";
private static final String PROP_CONTROLS = "controls"; private static final String PROP_CONTROLS = "controls";
private ReactExoplayerConfig config;
public ReactExoplayerViewManager(ReactExoplayerConfig config) {
this.config = config;
}
@Override @Override
public String getName() { public String getName() {
return REACT_CLASS; return REACT_CLASS;
@ -67,7 +73,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
@Override @Override
protected ReactExoplayerView createViewInstance(ThemedReactContext themedReactContext) { protected ReactExoplayerView createViewInstance(ThemedReactContext themedReactContext) {
return new ReactExoplayerView(themedReactContext); return new ReactExoplayerView(themedReactContext, config);
} }
@Override @Override

View File

@ -1,5 +1,7 @@
package com.brentvatne.react; package com.brentvatne.react;
import com.brentvatne.exoplayer.DefaultReactExoplayerConfig;
import com.brentvatne.exoplayer.ReactExoplayerConfig;
import com.brentvatne.exoplayer.ReactExoplayerViewManager; import com.brentvatne.exoplayer.ReactExoplayerViewManager;
import com.facebook.react.ReactPackage; import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.JavaScriptModule;
@ -12,19 +14,31 @@ import java.util.List;
public class ReactVideoPackage implements ReactPackage { public class ReactVideoPackage implements ReactPackage {
private ReactExoplayerConfig config;
public ReactVideoPackage() {
}
public ReactVideoPackage(ReactExoplayerConfig config) {
this.config = config;
}
@Override @Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList(); return Collections.emptyList();
} }
// Deprecated RN 0.47 // Deprecated RN 0.47
public List<Class<? extends JavaScriptModule>> createJSModules() { public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override @Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.<ViewManager>singletonList(new ReactExoplayerViewManager()); if (config == null) {
config = new DefaultReactExoplayerConfig(reactContext);
}
return Collections.singletonList(new ReactExoplayerViewManager(config));
} }
} }