Merge pull request #1310 from nfb-onf/maximumBitRate-adaptive-streaming

Support for maximum bit rate adaptive streaming
This commit is contained in:
Hampton Maxwell 2018-12-13 09:53:16 -08:00 committed by GitHub
commit 62f722147e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 46 additions and 1 deletions

View File

@ -267,6 +267,7 @@ var styles = StyleSheet.create({
* [hideShutterView](#hideshutterview) * [hideShutterView](#hideshutterview)
* [id](#id) * [id](#id)
* [ignoreSilentSwitch](#ignoresilentswitch) * [ignoreSilentSwitch](#ignoresilentswitch)
* [maxBitRate](#maxbitrate)
* [muted](#muted) * [muted](#muted)
* [paused](#paused) * [paused](#paused)
* [playInBackground](#playinbackground) * [playInBackground](#playinbackground)
@ -444,6 +445,18 @@ Controls the iOS silent switch behavior
Platforms: iOS Platforms: iOS
#### maxBitRate
Sets the desired limit, in bits per second, of network bandwidth consumption when multiple video streams are available for a playlist.
Default: 0. Don't limit the maxBitRate.
Example:
```
maxBitRate={2000000} // 2 megabits
```
Platforms: Android ExoPlayer, iOS
#### muted #### muted
Controls whether the audio is muted Controls whether the audio is muted
* **false (default)** - Don't mute audio * **false (default)** - Don't mute audio
@ -593,6 +606,7 @@ Sets the media source. You can pass an asset loaded via require or an object wit
The docs for this prop are incomplete and will be updated as each option is investigated and tested. The docs for this prop are incomplete and will be updated as each option is investigated and tested.
##### Asset loaded via require ##### Asset loaded via require
Example: Example:

View File

@ -330,6 +330,7 @@ Video.propTypes = {
// Opaque type returned by require('./video.mp4') // Opaque type returned by require('./video.mp4')
PropTypes.number PropTypes.number
]), ]),
maxBitRate: PropTypes.number,
resizeMode: PropTypes.string, resizeMode: PropTypes.string,
poster: PropTypes.string, poster: PropTypes.string,
posterResizeMode: Image.propTypes.resizeMode, posterResizeMode: Image.propTypes.resizeMode,

View File

@ -110,6 +110,7 @@ class ReactExoplayerView extends FrameLayout implements
private boolean isBuffering; private boolean isBuffering;
private float rate = 1f; private float rate = 1f;
private float audioVolume = 1f; private float audioVolume = 1f;
private int maxBitRate = 0;
private long seekTime = C.TIME_UNSET; private long seekTime = C.TIME_UNSET;
private int minBufferMs = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS; private int minBufferMs = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS;
@ -246,6 +247,9 @@ class ReactExoplayerView extends FrameLayout implements
if (player == null) { if (player == null) {
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelector.setParameters(trackSelector.buildUponParameters()
.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 defaultLoadControl = new DefaultLoadControl(allocator, minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, -1, true);
player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl); player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl);
@ -909,6 +913,14 @@ class ReactExoplayerView extends FrameLayout implements
} }
} }
public void setMaxBitRateModifier(int newMaxBitRate) {
maxBitRate = newMaxBitRate;
if (player != null) {
trackSelector.setParameters(trackSelector.buildUponParameters()
.setMaxVideoBitrate(maxBitRate == 0 ? Integer.MAX_VALUE : maxBitRate));
}
}
public void setPlayInBackground(boolean playInBackground) { public void setPlayInBackground(boolean playInBackground) {
this.playInBackground = playInBackground; this.playInBackground = playInBackground;

View File

@ -47,6 +47,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval"; private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
private static final String PROP_SEEK = "seek"; private static final String PROP_SEEK = "seek";
private static final String PROP_RATE = "rate"; private static final String PROP_RATE = "rate";
private static final String PROP_MAXIMUM_BIT_RATE = "maxBitRate";
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";
@ -201,6 +202,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
videoView.setRateModifier(rate); videoView.setRateModifier(rate);
} }
@ReactProp(name = PROP_MAXIMUM_BIT_RATE)
public void setMaxBitRate(final ReactExoplayerView videoView, final int maxBitRate) {
videoView.setMaxBitRateModifier(maxBitRate);
}
@ReactProp(name = PROP_PLAY_IN_BACKGROUND, defaultBoolean = false) @ReactProp(name = PROP_PLAY_IN_BACKGROUND, defaultBoolean = false)
public void setPlayInBackground(final ReactExoplayerView videoView, final boolean playInBackground) { public void setPlayInBackground(final ReactExoplayerView videoView, final boolean playInBackground) {
videoView.setPlayInBackground(playInBackground); videoView.setPlayInBackground(playInBackground);

View File

@ -51,6 +51,8 @@ static int const RCTVideoUnset = -1;
/* Keep track of any modifiers, need to be applied after each play */ /* Keep track of any modifiers, need to be applied after each play */
float _volume; float _volume;
float _rate; float _rate;
float _maxBitRate;
BOOL _muted; BOOL _muted;
BOOL _paused; BOOL _paused;
BOOL _repeat; BOOL _repeat;
@ -337,6 +339,7 @@ static int const RCTVideoUnset = -1;
_playerItem = playerItem; _playerItem = playerItem;
[self addPlayerItemObservers]; [self addPlayerItemObservers];
[self setFilter:_filterName]; [self setFilter:_filterName];
[self setMaxBitRate:_maxBitRate];
[_player pause]; [_player pause];
[_playerViewController.view removeFromSuperview]; [_playerViewController.view removeFromSuperview];
@ -853,6 +856,12 @@ static int const RCTVideoUnset = -1;
[self applyModifiers]; [self applyModifiers];
} }
- (void)setMaxBitRate:(float) maxBitRate {
_maxBitRate = maxBitRate;
[self applyModifiers];
}
- (void)applyModifiers - (void)applyModifiers
{ {
if (_muted) { if (_muted) {
@ -863,6 +872,8 @@ static int const RCTVideoUnset = -1;
[_player setMuted:NO]; [_player setMuted:NO];
} }
_playerItem.preferredPeakBitRate = _maxBitRate;
[self setSelectedAudioTrack:_selectedAudioTrack]; [self setSelectedAudioTrack:_selectedAudioTrack];
[self setSelectedTextTrack:_selectedTextTrack]; [self setSelectedTextTrack:_selectedTextTrack];
[self setResizeMode:_resizeMode]; [self setResizeMode:_resizeMode];

View File

@ -19,6 +19,7 @@ RCT_EXPORT_MODULE();
} }
RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary); RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(maxBitRate, float);
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString); RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString);
RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL); RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL);
RCT_EXPORT_VIEW_PROPERTY(allowsExternalPlayback, BOOL); RCT_EXPORT_VIEW_PROPERTY(allowsExternalPlayback, BOOL);