Reporting estimatedBandwidth

Reporting estimatedBandwidth
This commit is contained in:
sridhar 2018-08-25 21:53:11 +05:30
parent ff31bd1772
commit 6480a6462b
4 changed files with 70 additions and 6 deletions

View File

@ -99,6 +99,12 @@ export default class Video extends Component {
} }
}; };
_onBandwidthUpdate = (event) => {
if (this.props.onBandwidthUpdate) {
this.props.onBandwidthUpdate(event.nativeEvent);
}
};
_onSeek = (event) => { _onSeek = (event) => {
if (this.state.showPoster && !this.props.audioOnly) { if (this.state.showPoster && !this.props.audioOnly) {
this.setState({showPoster: false}); this.setState({showPoster: false});
@ -234,6 +240,7 @@ export default class Video extends Component {
onVideoSeek: this._onSeek, onVideoSeek: this._onSeek,
onVideoEnd: this._onEnd, onVideoEnd: this._onEnd,
onVideoBuffer: this._onBuffer, onVideoBuffer: this._onBuffer,
onBandwidthUpdate: this._onBandwidthUpdate,
onTimedMetadata: this._onTimedMetadata, onTimedMetadata: this._onTimedMetadata,
onVideoAudioBecomingNoisy: this._onAudioBecomingNoisy, onVideoAudioBecomingNoisy: this._onAudioBecomingNoisy,
onVideoFullscreenPlayerWillPresent: this._onFullscreenPlayerWillPresent, onVideoFullscreenPlayerWillPresent: this._onFullscreenPlayerWillPresent,
@ -294,6 +301,7 @@ Video.propTypes = {
onVideoBuffer: PropTypes.func, onVideoBuffer: PropTypes.func,
onVideoError: PropTypes.func, onVideoError: PropTypes.func,
onVideoProgress: PropTypes.func, onVideoProgress: PropTypes.func,
onBandwidthUpdate: PropTypes.func,
onVideoSeek: PropTypes.func, onVideoSeek: PropTypes.func,
onVideoEnd: PropTypes.func, onVideoEnd: PropTypes.func,
onTimedMetadata: PropTypes.func, onTimedMetadata: PropTypes.func,
@ -363,6 +371,8 @@ Video.propTypes = {
playInBackground: PropTypes.bool, playInBackground: PropTypes.bool,
playWhenInactive: PropTypes.bool, playWhenInactive: PropTypes.bool,
ignoreSilentSwitch: PropTypes.oneOf(['ignore', 'obey']), ignoreSilentSwitch: PropTypes.oneOf(['ignore', 'obey']),
reportBandwidth: PropTypes.bool,
bandwidthUpdateInterval: PropTypes.number,
disableFocus: PropTypes.bool, disableFocus: PropTypes.bool,
controls: PropTypes.bool, controls: PropTypes.bool,
audioOnly: PropTypes.bool, audioOnly: PropTypes.bool,

View File

@ -86,6 +86,7 @@ class ReactExoplayerView extends FrameLayout implements
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter(); 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();
@ -133,6 +134,8 @@ class ReactExoplayerView extends FrameLayout implements
private boolean playInBackground = false; private boolean playInBackground = false;
private boolean useTextureView = false; private boolean useTextureView = false;
private Map<String, String> requestHeaders; private Map<String, String> requestHeaders;
private float mBandwidthUpdateInterval = 250.0f;
private boolean mReportBandwidth = false;
// \ End props // \ End props
// React // React
@ -149,10 +152,9 @@ class ReactExoplayerView extends FrameLayout implements
&& player.getPlaybackState() == ExoPlayer.STATE_READY && player.getPlaybackState() == ExoPlayer.STATE_READY
&& player.getPlayWhenReady() && player.getPlayWhenReady()
) { ) {
long bitRateEstimate = BANDWIDTH_METER.getBitrateEstimate();
long pos = player.getCurrentPosition(); long pos = player.getCurrentPosition();
long bufferedDuration = player.getBufferedPercentage() * player.getDuration() / 100; long bufferedDuration = player.getBufferedPercentage() * player.getDuration() / 100;
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration(), bitRateEstimate); eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration());
msg = obtainMessage(SHOW_PROGRESS); msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, Math.round(mProgressUpdateInterval)); sendMessageDelayed(msg, Math.round(mProgressUpdateInterval));
} }
@ -161,6 +163,23 @@ class ReactExoplayerView extends FrameLayout implements
} }
}; };
private final Handler bandwidthReporter = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REPORT_BANDWIDTH:
if (player != null) {
long bitRateEstimate = BANDWIDTH_METER.getBitrateEstimate();
eventEmitter.bandwidthReport(bitRateEstimate);
msg = obtainMessage(REPORT_BANDWIDTH);
sendMessageDelayed(msg, Math.round(mBandwidthUpdateInterval));
}
break;
}
}
};
public ReactExoplayerView(ThemedReactContext context) { public ReactExoplayerView(ThemedReactContext context) {
super(context); super(context);
this.themedReactContext = context; this.themedReactContext = context;
@ -338,6 +357,7 @@ class ReactExoplayerView extends FrameLayout implements
player = null; player = null;
trackSelector = null; trackSelector = null;
} }
bandwidthReporter.removeMessages(REPORT_BANDWIDTH);
progressHandler.removeMessages(SHOW_PROGRESS); progressHandler.removeMessages(SHOW_PROGRESS);
themedReactContext.removeLifecycleEventListener(this); themedReactContext.removeLifecycleEventListener(this);
audioBecomingNoisyReceiver.removeListener(); audioBecomingNoisyReceiver.removeListener();
@ -579,7 +599,6 @@ class ReactExoplayerView extends FrameLayout implements
videoTracks.pushMap(videoTrack); videoTracks.pushMap(videoTrack);
} }
} }
return videoTracks; return videoTracks;
} }
@ -758,6 +777,20 @@ class ReactExoplayerView extends FrameLayout implements
mProgressUpdateInterval = progressUpdateInterval; mProgressUpdateInterval = progressUpdateInterval;
} }
public void setBandwidthUpdateInterval(final float bandwidthUpdateInterval) {
mBandwidthUpdateInterval = bandwidthUpdateInterval;
}
public void setReportBandwidthModifier(boolean reportBandwidth) {
mReportBandwidth = reportBandwidth;
if (mReportBandwidth) {
bandwidthReporter.removeMessages(REPORT_BANDWIDTH);
bandwidthReporter.sendEmptyMessage(REPORT_BANDWIDTH);
} else {
bandwidthReporter.removeMessages(REPORT_BANDWIDTH);
}
}
public void setRawSrc(final Uri uri, final String extension) { public void setRawSrc(final Uri uri, final String extension) {
if (uri != null) { if (uri != null) {
boolean isOriginalSourceNull = srcUri == null; boolean isOriginalSourceNull = srcUri == null;

View File

@ -45,6 +45,8 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_MS = "bufferForPlaybackMs"; private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_MS = "bufferForPlaybackMs";
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = "bufferForPlaybackAfterRebufferMs"; private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = "bufferForPlaybackAfterRebufferMs";
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval"; private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
private static final String PROP_BANDWIDTH_UPDATE_INTERVAL = "bandwidthUpdateInterval";
private static final String PROP_REPORT_BANDWIDTH = "reportBandwidth";
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_PLAY_IN_BACKGROUND = "playInBackground"; private static final String PROP_PLAY_IN_BACKGROUND = "playInBackground";
@ -207,6 +209,16 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
videoView.setProgressUpdateInterval(progressUpdateInterval); videoView.setProgressUpdateInterval(progressUpdateInterval);
} }
@ReactProp(name = PROP_BANDWIDTH_UPDATE_INTERVAL, defaultFloat = 250.0f)
public void setBandwidthUpdateInterval(final ReactExoplayerView videoView, final float bandwidthUpdateInterval) {
videoView.setBandwidthUpdateInterval(bandwidthUpdateInterval);
}
@ReactProp(name = PROP_REPORT_BANDWIDTH, defaultBoolean = false)
public void setReportBandwidth(final ReactExoplayerView videoView, final boolean reportBandwidth) {
videoView.setReportBandwidthModifier(reportBandwidth);
}
@ReactProp(name = PROP_SEEK) @ReactProp(name = PROP_SEEK)
public void setSeek(final ReactExoplayerView videoView, final float seek) { public void setSeek(final ReactExoplayerView videoView, final float seek) {
videoView.seekTo(Math.round(seek * 1000f)); videoView.seekTo(Math.round(seek * 1000f));

View File

@ -29,6 +29,7 @@ class VideoEventEmitter {
private static final String EVENT_LOAD = "onVideoLoad"; private static final String EVENT_LOAD = "onVideoLoad";
private static final String EVENT_ERROR = "onVideoError"; private static final String EVENT_ERROR = "onVideoError";
private static final String EVENT_PROGRESS = "onVideoProgress"; private static final String EVENT_PROGRESS = "onVideoProgress";
private static final String EVENT_BANDWIDTH = "onBandwidthUpdate";
private static final String EVENT_SEEK = "onVideoSeek"; private static final String EVENT_SEEK = "onVideoSeek";
private static final String EVENT_END = "onVideoEnd"; private static final String EVENT_END = "onVideoEnd";
private static final String EVENT_FULLSCREEN_WILL_PRESENT = "onVideoFullscreenPlayerWillPresent"; private static final String EVENT_FULLSCREEN_WILL_PRESENT = "onVideoFullscreenPlayerWillPresent";
@ -66,6 +67,7 @@ class VideoEventEmitter {
EVENT_AUDIO_BECOMING_NOISY, EVENT_AUDIO_BECOMING_NOISY,
EVENT_AUDIO_FOCUS_CHANGE, EVENT_AUDIO_FOCUS_CHANGE,
EVENT_PLAYBACK_RATE_CHANGE, EVENT_PLAYBACK_RATE_CHANGE,
EVENT_BANDWIDTH,
}; };
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@ -89,6 +91,7 @@ class VideoEventEmitter {
EVENT_AUDIO_BECOMING_NOISY, EVENT_AUDIO_BECOMING_NOISY,
EVENT_AUDIO_FOCUS_CHANGE, EVENT_AUDIO_FOCUS_CHANGE,
EVENT_PLAYBACK_RATE_CHANGE, EVENT_PLAYBACK_RATE_CHANGE,
EVENT_BANDWIDTH,
}) })
@interface VideoEvents { @interface VideoEvents {
} }
@ -103,7 +106,6 @@ class VideoEventEmitter {
private static final String EVENT_PROP_DURATION = "duration"; private static final String EVENT_PROP_DURATION = "duration";
private static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration"; private static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration";
private static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration"; private static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration";
private static final String EVENT_PROP_BITRATE_ESTIMATE = "bitrateEstimate";
private static final String EVENT_PROP_CURRENT_TIME = "currentTime"; private static final String EVENT_PROP_CURRENT_TIME = "currentTime";
private static final String EVENT_PROP_SEEK_TIME = "seekTime"; private static final String EVENT_PROP_SEEK_TIME = "seekTime";
private static final String EVENT_PROP_NATURAL_SIZE = "naturalSize"; private static final String EVENT_PROP_NATURAL_SIZE = "naturalSize";
@ -123,6 +125,8 @@ class VideoEventEmitter {
private static final String EVENT_PROP_TIMED_METADATA = "metadata"; private static final String EVENT_PROP_TIMED_METADATA = "metadata";
private static final String EVENT_PROP_BITRATE_ESTIMATE = "bitrateEstimate";
void setViewId(int viewId) { void setViewId(int viewId) {
this.viewId = viewId; this.viewId = viewId;
@ -164,15 +168,20 @@ class VideoEventEmitter {
receiveEvent(EVENT_LOAD, event); receiveEvent(EVENT_LOAD, event);
} }
void progressChanged(double currentPosition, double bufferedDuration, double seekableDuration, double bitRateEstimate) { void progressChanged(double currentPosition, double bufferedDuration, double seekableDuration) {
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D); event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D);
event.putDouble(EVENT_PROP_PLAYABLE_DURATION, bufferedDuration / 1000D); event.putDouble(EVENT_PROP_PLAYABLE_DURATION, bufferedDuration / 1000D);
event.putDouble(EVENT_PROP_SEEKABLE_DURATION, seekableDuration / 1000D); event.putDouble(EVENT_PROP_SEEKABLE_DURATION, seekableDuration / 1000D);
event.putDouble(EVENT_PROP_BITRATE_ESTIMATE, bitRateEstimate / 1000D);
receiveEvent(EVENT_PROGRESS, event); receiveEvent(EVENT_PROGRESS, event);
} }
void bandwidthReport(double bitRateEstimate) {
WritableMap event = Arguments.createMap();
event.putDouble(EVENT_PROP_BITRATE_ESTIMATE, bitRateEstimate / 1000D);
receiveEvent(EVENT_BANDWIDTH, event);
}
void seek(long currentPosition, long seekTime) { void seek(long currentPosition, long seekTime) {
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D); event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D);