diff --git a/README.md b/README.md index 1b6a913e..fc6681f0 100644 --- a/README.md +++ b/README.md @@ -276,10 +276,12 @@ var styles = StyleSheet.create({ * [allowsExternalPlayback](#allowsexternalplayback) * [audioOnly](#audioonly) * [automaticallyWaitsToMinimizeStalling](#automaticallyWaitsToMinimizeStalling) +* [backBufferDurationMs](#backBufferDurationMs) * [bufferConfig](#bufferconfig) * [controls](#controls) * [currentPlaybackTime](#currentPlaybackTime) * [disableFocus](#disableFocus) +* [disableDisconnectError](#disableDisconnectError) * [filter](#filter) * [filterEnabled](#filterEnabled) * [fullscreen](#fullscreen) @@ -367,6 +369,11 @@ A Boolean value that indicates whether the player should automatically delay pla Platforms: iOS +#### backBufferDurationMs +The number of milliseconds of buffer to keep before the current position. This allows rewinding without rebuffering within that duration. + +Platforms: Android ExoPlayer + #### bufferConfig Adjust the buffer settings. This prop takes an object with one or more of the properties listed below. @@ -416,6 +423,13 @@ Determines whether video audio should override background music/audio in Android Platforms: Android Exoplayer +#### disableDisconnectError +Determines if the player needs to throw an error when connection is lost or not +* **false (default)** - Player will throw an error when connection is lost +* **true** - Player will keep trying to buffer when network connect is lost + +Platforms: Android Exoplayer + ### DRM To setup DRM please follow [this guide](./DRM.md) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.java index d68274b7..3475273c 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DefaultReactExoplayerConfig.java @@ -9,16 +9,28 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; public class DefaultReactExoplayerConfig implements ReactExoplayerConfig { private final DefaultBandwidthMeter bandwidthMeter; + private boolean disableDisconnectError = false; public DefaultReactExoplayerConfig(Context context) { this.bandwidthMeter = new DefaultBandwidthMeter.Builder(context).build(); } - @Override public LoadErrorHandlingPolicy buildLoadErrorHandlingPolicy(int minLoadRetryCount) { + if (this.disableDisconnectError) { + // Use custom error handling policy to prevent throwing an error when losing network connection + return new ReactExoplayerLoadErrorHandlingPolicy(minLoadRetryCount); + } return new DefaultLoadErrorHandlingPolicy(minLoadRetryCount); } + public void setDisableDisconnectError(boolean disableDisconnectError) { + this.disableDisconnectError = disableDisconnectError; + } + + public boolean getDisableDisconnectError() { + return this.disableDisconnectError; + } + @Override public DefaultBandwidthMeter getBandwidthMeter() { return bandwidthMeter; diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerConfig.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerConfig.java index 522578b7..2cc56f9a 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerConfig.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerConfig.java @@ -9,5 +9,8 @@ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; public interface ReactExoplayerConfig { LoadErrorHandlingPolicy buildLoadErrorHandlingPolicy(int minLoadRetryCount); + void setDisableDisconnectError(boolean disableDisconnectError); + boolean getDisableDisconnectError(); + DefaultBandwidthMeter getBandwidthMeter(); } diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerLoadErrorHandlingPolicy.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerLoadErrorHandlingPolicy.java new file mode 100644 index 00000000..c701310f --- /dev/null +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerLoadErrorHandlingPolicy.java @@ -0,0 +1,33 @@ +package com.brentvatne.exoplayer; + +import java.io.IOException; +import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; +import com.google.android.exoplayer2.upstream.HttpDataSource.HttpDataSourceException; +import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo; +import com.google.android.exoplayer2.C; + +public final class ReactExoplayerLoadErrorHandlingPolicy extends DefaultLoadErrorHandlingPolicy { + private int minLoadRetryCount = Integer.MAX_VALUE; + + public ReactExoplayerLoadErrorHandlingPolicy(int minLoadRetryCount) { + super(minLoadRetryCount); + this.minLoadRetryCount = minLoadRetryCount; + } + + @Override + public long getRetryDelayMsFor(LoadErrorInfo loadErrorInfo) { + if (loadErrorInfo.exception instanceof HttpDataSourceException) { + // Capture the error we get when there is no network connectivity and keep retrying it + return 1000; // Retry every second + } else if(loadErrorInfo.errorCount < this.minLoadRetryCount) { + return Math.min((loadErrorInfo.errorCount - 1) * 1000, 5000); // Default timeout handling + } else { + return C.TIME_UNSET; // Done retrying and will return the error immediately + } + } + + @Override + public int getMinimumLoadableRetryCount(int dataType) { + return Integer.MAX_VALUE; + } +} \ No newline at end of file diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 7881c914..488f2d3b 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -139,6 +139,7 @@ class ReactExoplayerView extends FrameLayout implements private Handler mainHandler; // Props from React + private int backBufferDurationMs = DefaultLoadControl.DEFAULT_BACK_BUFFER_DURATION_MS; private Uri srcUri; private String extension; private boolean repeat; @@ -151,6 +152,7 @@ class ReactExoplayerView extends FrameLayout implements private ReadableArray textTracks; private boolean disableFocus; private boolean disableBuffering; + private boolean disableDisconnectError; private boolean preventsDisplaySleepDuringVideoPlayback = true; private float mProgressUpdateInterval = 250.0f; private boolean playInBackground = false; @@ -434,7 +436,7 @@ class ReactExoplayerView extends FrameLayout implements bufferForPlaybackAfterRebufferMs, -1, true, - DefaultLoadControl.DEFAULT_BACK_BUFFER_DURATION_MS, + backBufferDurationMs, DefaultLoadControl.DEFAULT_RETAIN_BACK_BUFFER_FROM_KEYFRAME ); DefaultRenderersFactory renderersFactory = @@ -527,6 +529,7 @@ class ReactExoplayerView extends FrameLayout implements private MediaSource buildMediaSource(Uri uri, String overrideExtension, DrmSessionManager drmSessionManager) { int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension : uri.getLastPathSegment()); + config.setDisableDisconnectError(this.disableDisconnectError); switch (type) { case C.TYPE_SS: return new SsMediaSource.Factory( @@ -1312,10 +1315,18 @@ class ReactExoplayerView extends FrameLayout implements this.disableFocus = disableFocus; } + public void setBackBufferDurationMs(int backBufferDurationMs) { + this.backBufferDurationMs = backBufferDurationMs; + } + public void setDisableBuffering(boolean disableBuffering) { this.disableBuffering = disableBuffering; } + public void setDisableDisconnectError(boolean disableDisconnectError) { + this.disableDisconnectError = disableDisconnectError; + } + public void setFullscreen(boolean fullscreen) { if (fullscreen == isFullscreen) { return; // Avoid generating events when nothing is changing diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java index 2fc12e42..c460f176 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java @@ -49,6 +49,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager