merge
This commit is contained in:
commit
c2d9fb4301
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,5 +1,17 @@
|
||||
## Changelog
|
||||
|
||||
### Version 4.2.0
|
||||
* Don't initialize filters on iOS unless a filter is set. This was causing a startup performance regression [#1360](https://github.com/react-native-community/react-native-video/pull/1360)
|
||||
* Support setting the maxBitRate [#1310](https://github.com/react-native-community/react-native-video/pull/1310)
|
||||
* Fix useTextureView not defaulting to true [#1383](https://github.com/react-native-community/react-native-video/pull/1383)
|
||||
* Fix crash on MediaPlayer w/ Android 4.4 & avoid memory leak [#1328](https://github.com/react-native-community/react-native-video/pull/1328)
|
||||
|
||||
### Version 4.1.0
|
||||
* Generate onSeek on Android ExoPlayer & MediaPlayer after seek completes [#1351](https://github.com/react-native-community/react-native-video/pull/1351)
|
||||
* Remove unneeded onVideoSaved event [#1350](https://github.com/react-native-community/react-native-video/pull/1350)
|
||||
* Disable AirPlay if sidecar text tracks are enabled [#1304](https://github.com/react-native-community/react-native-video/pull/1304)
|
||||
* Add possibility to remove black screen while video is loading in Exoplayer [#1355](https://github.com/react-native-community/react-native-video/pull/1355)
|
||||
|
||||
### Version 4.0.1
|
||||
* Add missing files to package.json [#1342](https://github.com/react-native-community/react-native-video/pull/1342)
|
||||
|
||||
|
25
README.md
25
README.md
@ -265,8 +265,10 @@ var styles = StyleSheet.create({
|
||||
* [fullscreenAutorotate](#fullscreenautorotate)
|
||||
* [fullscreenOrientation](#fullscreenorientation)
|
||||
* [headers](#headers)
|
||||
* [hideShutterView](#hideshutterview)
|
||||
* [id](#id)
|
||||
* [ignoreSilentSwitch](#ignoresilentswitch)
|
||||
* [maxBitRate](#maxbitrate)
|
||||
* [muted](#muted)
|
||||
* [paused](#paused)
|
||||
* [playInBackground](#playinbackground)
|
||||
@ -427,6 +429,14 @@ headers={{
|
||||
|
||||
Platforms: Android ExoPlayer
|
||||
|
||||
#### hideShutterView
|
||||
Controls whether the ExoPlayer shutter view (black screen while loading) is enabled.
|
||||
|
||||
* **false (default)** - Show shutter view
|
||||
* **true** - Hide shutter view
|
||||
|
||||
Platforms: Android ExoPlayer
|
||||
|
||||
#### id
|
||||
Set the DOM id element so you can use document.getElementById on web platforms. Accepts string values.
|
||||
|
||||
@ -445,6 +455,18 @@ Controls the iOS silent switch behavior
|
||||
|
||||
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
|
||||
Controls whether the audio is muted
|
||||
* **false (default)** - Don't mute audio
|
||||
@ -594,6 +616,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.
|
||||
|
||||
|
||||
##### Asset loaded via require
|
||||
|
||||
Example:
|
||||
@ -666,6 +689,8 @@ uri | URL for the text track. Currently, only tracks hosted on a webserver are s
|
||||
|
||||
On iOS, sidecar text tracks are only supported for individual files, not HLS playlists. For HLS, you should include the text tracks as part of the playlist.
|
||||
|
||||
Note: Due to iOS limitations, sidecar text tracks are not compatible with Airplay. If textTracks are specified, AirPlay support will be automatically disabled.
|
||||
|
||||
Example:
|
||||
```
|
||||
import { TextTrackType }, Video from 'react-native-video';
|
||||
|
2
Video.js
2
Video.js
@ -331,6 +331,7 @@ Video.propTypes = {
|
||||
// Opaque type returned by require('./video.mp4')
|
||||
PropTypes.number
|
||||
]),
|
||||
maxBitRate: PropTypes.number,
|
||||
resizeMode: PropTypes.string,
|
||||
poster: PropTypes.string,
|
||||
posterResizeMode: Image.propTypes.resizeMode,
|
||||
@ -384,6 +385,7 @@ Video.propTypes = {
|
||||
fullscreenOrientation: PropTypes.oneOf(['all','landscape','portrait']),
|
||||
progressUpdateInterval: PropTypes.number,
|
||||
useTextureView: PropTypes.bool,
|
||||
hideShutterView: PropTypes.bool,
|
||||
onLoadStart: PropTypes.func,
|
||||
onLoad: PropTypes.func,
|
||||
onBuffer: PropTypes.func,
|
||||
|
@ -38,7 +38,8 @@ public final class ExoPlayerView extends FrameLayout {
|
||||
private Context context;
|
||||
private ViewGroup.LayoutParams layoutParams;
|
||||
|
||||
private boolean useTextureView = false;
|
||||
private boolean useTextureView = true;
|
||||
private boolean hideShutterView = false;
|
||||
|
||||
public ExoPlayerView(Context context) {
|
||||
this(context, null);
|
||||
@ -106,6 +107,10 @@ public final class ExoPlayerView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateShutterViewVisibility() {
|
||||
shutterView.setVisibility(this.hideShutterView ? View.INVISIBLE : View.VISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link SimpleExoPlayer} to use. The {@link SimpleExoPlayer#setTextOutput} and
|
||||
* {@link SimpleExoPlayer#setVideoListener} method of the player will be called and previous
|
||||
@ -157,9 +162,16 @@ public final class ExoPlayerView extends FrameLayout {
|
||||
}
|
||||
|
||||
public void setUseTextureView(boolean useTextureView) {
|
||||
if (useTextureView != this.useTextureView) {
|
||||
this.useTextureView = useTextureView;
|
||||
updateSurfaceView();
|
||||
}
|
||||
}
|
||||
|
||||
public void setHideShutterView(boolean hideShutterView) {
|
||||
this.hideShutterView = hideShutterView;
|
||||
updateShutterViewVisibility();
|
||||
}
|
||||
|
||||
private final Runnable measureAndLayout = new Runnable() {
|
||||
@Override
|
||||
|
@ -110,6 +110,7 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
private boolean isBuffering;
|
||||
private float rate = 1f;
|
||||
private float audioVolume = 1f;
|
||||
private int maxBitRate = 0;
|
||||
private long seekTime = C.TIME_UNSET;
|
||||
|
||||
private int minBufferMs = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS;
|
||||
@ -130,7 +131,6 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
private boolean disableFocus;
|
||||
private float mProgressUpdateInterval = 250.0f;
|
||||
private boolean playInBackground = false;
|
||||
private boolean useTextureView = false;
|
||||
private Map<String, String> requestHeaders;
|
||||
// \ End props
|
||||
|
||||
@ -245,6 +245,9 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
if (player == null) {
|
||||
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
|
||||
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);
|
||||
DefaultLoadControl defaultLoadControl = new DefaultLoadControl(allocator, minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, -1, true);
|
||||
player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl);
|
||||
@ -908,6 +911,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) {
|
||||
this.playInBackground = playInBackground;
|
||||
@ -954,6 +965,10 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
exoPlayerView.setUseTextureView(useTextureView);
|
||||
}
|
||||
|
||||
public void setHideShutterView(boolean hideShutterView) {
|
||||
exoPlayerView.setHideShutterView(hideShutterView);
|
||||
}
|
||||
|
||||
public void setBufferConfig(int newMinBufferMs, int newMaxBufferMs, int newBufferForPlaybackMs, int newBufferForPlaybackAfterRebufferMs) {
|
||||
minBufferMs = newMinBufferMs;
|
||||
maxBufferMs = newMaxBufferMs;
|
||||
|
@ -47,10 +47,12 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
|
||||
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
|
||||
private static final String PROP_SEEK = "seek";
|
||||
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_DISABLE_FOCUS = "disableFocus";
|
||||
private static final String PROP_FULLSCREEN = "fullscreen";
|
||||
private static final String PROP_USE_TEXTURE_VIEW = "useTextureView";
|
||||
private static final String PROP_HIDE_SHUTTER_VIEW = "hideShutterView";
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@ -200,6 +202,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
|
||||
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)
|
||||
public void setPlayInBackground(final ReactExoplayerView videoView, final boolean playInBackground) {
|
||||
videoView.setPlayInBackground(playInBackground);
|
||||
@ -220,6 +227,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
|
||||
videoView.setUseTextureView(useTextureView);
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_HIDE_SHUTTER_VIEW, defaultBoolean = false)
|
||||
public void setHideShutterView(final ReactExoplayerView videoView, final boolean hideShutterView) {
|
||||
videoView.setHideShutterView(hideShutterView);
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_BUFFER_CONFIG)
|
||||
public void setBufferConfig(final ReactExoplayerView videoView, @Nullable ReadableMap bufferConfig) {
|
||||
int minBufferMs = DefaultLoadControl.DEFAULT_MIN_BUFFER_MS;
|
||||
|
@ -235,12 +235,19 @@ public class ReactVideoView extends ScalableVideoView implements
|
||||
mediaController.hide();
|
||||
}
|
||||
if ( mMediaPlayer != null ) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
mMediaPlayer.setOnTimedMetaDataAvailableListener(null);
|
||||
}
|
||||
mMediaPlayerValid = false;
|
||||
release();
|
||||
}
|
||||
if (mIsFullscreen) {
|
||||
setFullscreen(false);
|
||||
}
|
||||
if (mThemedReactContext != null) {
|
||||
mThemedReactContext.removeLifecycleEventListener(this);
|
||||
mThemedReactContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSrc(final String uriString, final String type, final boolean isNetwork, final boolean isAsset, final ReadableMap requestHeaders) {
|
||||
@ -567,8 +574,7 @@ public class ReactVideoView extends ScalableVideoView implements
|
||||
});
|
||||
}
|
||||
|
||||
// Select track (so we can use it to listen to timed meta data updates)
|
||||
mp.selectTrack(0);
|
||||
selectTimedMetadataTrack(mp);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -603,9 +609,7 @@ public class ReactVideoView extends ScalableVideoView implements
|
||||
|
||||
@Override
|
||||
public void onBufferingUpdate(MediaPlayer mp, int percent) {
|
||||
// Select track (so we can use it to listen to timed meta data updates)
|
||||
mp.selectTrack(0);
|
||||
|
||||
selectTimedMetadataTrack(mp);
|
||||
mVideoBufferedDuration = (int) Math.round((double) (mVideoDuration * percent) / 100.0);
|
||||
}
|
||||
|
||||
@ -761,4 +765,20 @@ public class ReactVideoView extends ScalableVideoView implements
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Select track (so we can use it to listen to timed meta data updates)
|
||||
private void selectTimedMetadataTrack(MediaPlayer mp) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
return;
|
||||
}
|
||||
try { // It's possible this could throw an exception if the framework doesn't support getting track info
|
||||
MediaPlayer.TrackInfo[] trackInfo = mp.getTrackInfo();
|
||||
for (int i = 0; i < trackInfo.length; ++i) {
|
||||
if (trackInfo[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
|
||||
mp.selectTrack(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ RCT_EXPORT_MODULE();
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary);
|
||||
RCT_EXPORT_VIEW_PROPERTY(maxBitRate, float);
|
||||
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString);
|
||||
RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL);
|
||||
RCT_EXPORT_VIEW_PROPERTY(allowsExternalPlayback, BOOL);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-video",
|
||||
"version": "4.0.2",
|
||||
"version": "4.2.1",
|
||||
"description": "A <Video /> element for react-native",
|
||||
"main": "Video.js",
|
||||
"license": "MIT",
|
||||
|
Loading…
Reference in New Issue
Block a user