diff --git a/README.md b/README.md index ed6ffae98e..947f4f2a89 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,7 @@ var styles = StyleSheet.create({ ### Configurable props * [allowsExternalPlayback](#allowsexternalplayback) * [audioOnly](#audioonly) +* [bufferConfig](#bufferconfig) * [ignoreSilentSwitch](#ignoresilentswitch) * [muted](#muted) * [paused](#paused) @@ -264,6 +265,30 @@ For this to work, the poster prop must be set. Platforms: all +#### bufferConfig +Adjust the buffer settings. This prop takes an object with one or more of the properties listed below. + +This prop can only be set when you are setting a new source, changing it after the media is loaded will cause it to restart. + +Property | Type | Description +--- | --- | --- +minBufferMs | number | The default minimum duration of media that the player will attempt to ensure is buffered at all times, in milliseconds. +maxBufferMs | number | The default maximum duration of media that the player will attempt to buffer, in milliseconds. +bufferForPlaybackMs | number | The default duration of media that must be buffered for playback to start or resume following a user action such as a seek, in milliseconds. +playbackAfterRebufferMs | number | The default duration of media that must be buffered for playback to resume after a rebuffer, in milliseconds. A rebuffer is defined to be caused by buffer depletion rather than a user action. + +Example with default values: +``` +bufferConfig={{ + minBufferMs: 15000, + maxBufferMs: 50000, + bufferForPlaybackMs: 2500, + bufferForPlaybackAfterRebufferMs: 5000 +}} +``` + +Platforms: Android ExoPlayer + #### ignoreSilentSwitch Controls the iOS silent switch behavior * **"inherit" (default)** - Use the default AVPlayer behavior diff --git a/Video.js b/Video.js index f32725f384..5c6cd1d3cf 100644 --- a/Video.js +++ b/Video.js @@ -345,6 +345,12 @@ Video.propTypes = { paused: PropTypes.bool, muted: PropTypes.bool, volume: PropTypes.number, + bufferConfig: PropTypes.shape({ + minBufferMs: PropTypes.number, + maxBufferMs: PropTypes.number, + bufferForPlaybackMs: PropTypes.number, + bufferForPlaybackAfterRebufferMs: PropTypes.number, + }), stereoPan: PropTypes.number, rate: PropTypes.number, playInBackground: PropTypes.bool, 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 487da3433c..9ef099cff7 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -58,6 +58,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; @@ -109,6 +110,11 @@ class ReactExoplayerView extends FrameLayout implements private boolean isBuffering; private float rate = 1f; + private int minBufferMs = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS; + private int maxBufferMs = DefaultLoadControl.DEFAULT_MAX_BUFFER_MS; + private int bufferForPlaybackMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS; + private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS; + // Props from React private Uri srcUri; private String extension; @@ -234,7 +240,9 @@ private void initializePlayer() { if (player == null) { TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); - player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, new DefaultLoadControl()); + DefaultAllocator allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE); + DefaultLoadControl defaultLoadControl = new DefaultLoadControl(allocator, minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, -1, true); + player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl); player.addListener(this); player.setMetadataOutput(this); exoPlayerView.setPlayer(player); @@ -320,7 +328,6 @@ private MediaSource buildTextSource(String title, Uri uri, String mimeType, Stri private void releasePlayer() { if (player != null) { - isPaused = player.getPlayWhenReady(); updateResumePosition(); player.release(); player.setMetadataOutput(null); @@ -931,4 +938,13 @@ public void setFullscreen(boolean fullscreen) { public void setUseTextureView(boolean useTextureView) { exoPlayerView.setUseTextureView(useTextureView); } + + public void setBufferConfig(int newMinBufferMs, int newMaxBufferMs, int newBufferForPlaybackMs, int newBufferForPlaybackAfterRebufferMs) { + minBufferMs = newMinBufferMs; + maxBufferMs = newMaxBufferMs; + bufferForPlaybackMs = newBufferForPlaybackMs; + bufferForPlaybackAfterRebufferMs = newBufferForPlaybackAfterRebufferMs; + releasePlayer(); + initializePlayer(); + } } 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 fbc8a9adb4..9ead70ce3c 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java @@ -11,6 +11,7 @@ import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; +import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.upstream.RawResourceDataSource; import java.util.HashMap; @@ -38,6 +39,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager