VEX-3245: Buffer Progress UI While Paused (#7)
Add support for onBufferProgress prop on Android to get buffer data even when the player is paused.
This commit is contained in:
parent
cba88fa9d8
commit
93604b2c25
@ -1,5 +1,7 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
- Add support for `onBufferProgress` on Android for getting buffer data even when the player is paused
|
||||||
|
|
||||||
- Fix Android AudioFocus bug that could cause player to not respond to play/pause in some instances [#2311](https://github.com/react-native-video/react-native-video/pull/2311)
|
- Fix Android AudioFocus bug that could cause player to not respond to play/pause in some instances [#2311](https://github.com/react-native-video/react-native-video/pull/2311)
|
||||||
|
|
||||||
### Version 5.1.0-alpha9
|
### Version 5.1.0-alpha9
|
||||||
|
13
README.md
13
README.md
@ -321,6 +321,7 @@ var styles = StyleSheet.create({
|
|||||||
### Event props
|
### Event props
|
||||||
* [onAudioBecomingNoisy](#onaudiobecomingnoisy)
|
* [onAudioBecomingNoisy](#onaudiobecomingnoisy)
|
||||||
* [onBandwidthUpdate](#onbandwidthupdate)
|
* [onBandwidthUpdate](#onbandwidthupdate)
|
||||||
|
* [onBufferProgress](#onbufferprogress)
|
||||||
* [onEnd](#onend)
|
* [onEnd](#onend)
|
||||||
* [onExternalPlaybackChange](#onexternalplaybackchange)
|
* [onExternalPlaybackChange](#onexternalplaybackchange)
|
||||||
* [onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent)
|
* [onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent)
|
||||||
@ -944,6 +945,18 @@ Note: On Android ExoPlayer, you must set the [reportBandwidth](#reportbandwidth)
|
|||||||
|
|
||||||
Platforms: Android ExoPlayer
|
Platforms: Android ExoPlayer
|
||||||
|
|
||||||
|
|
||||||
|
#### onBufferProgress
|
||||||
|
Callback function that is called on a set interval which contains the buffer start and end position in ms.
|
||||||
|
|
||||||
|
Payload:
|
||||||
|
Property | Type | Description
|
||||||
|
--- | --- | ---
|
||||||
|
start | number | The buffer start (ms)
|
||||||
|
end | number | The buffer end (ms)
|
||||||
|
|
||||||
|
Platforms: Android ExoPlayer
|
||||||
|
|
||||||
#### onEnd
|
#### onEnd
|
||||||
Callback function that is called when the player reaches the end of the media.
|
Callback function that is called when the player reaches the end of the media.
|
||||||
|
|
||||||
|
7
Video.js
7
Video.js
@ -233,6 +233,12 @@ export default class Video extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_onBufferProgress = (event) => {
|
||||||
|
if (this.props.onBufferProgress) {
|
||||||
|
this.props.onBufferProgress(event.nativeEvent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
_onGetLicense = (event) => {
|
_onGetLicense = (event) => {
|
||||||
if (this.props.drm && this.props.drm.getLicense instanceof Function) {
|
if (this.props.drm && this.props.drm.getLicense instanceof Function) {
|
||||||
const data = event.nativeEvent;
|
const data = event.nativeEvent;
|
||||||
@ -311,6 +317,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,
|
||||||
|
onVideoBufferProgress: this._onBufferProgress,
|
||||||
onVideoBandwidthUpdate: this._onBandwidthUpdate,
|
onVideoBandwidthUpdate: this._onBandwidthUpdate,
|
||||||
onTimedMetadata: this._onTimedMetadata,
|
onTimedMetadata: this._onTimedMetadata,
|
||||||
onVideoAudioBecomingNoisy: this._onAudioBecomingNoisy,
|
onVideoAudioBecomingNoisy: this._onAudioBecomingNoisy,
|
||||||
|
@ -81,6 +81,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
@SuppressLint("ViewConstructor")
|
@SuppressLint("ViewConstructor")
|
||||||
class ReactExoplayerView extends FrameLayout implements
|
class ReactExoplayerView extends FrameLayout implements
|
||||||
@ -137,6 +139,7 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
||||||
|
|
||||||
private Handler mainHandler;
|
private Handler mainHandler;
|
||||||
|
private Timer bufferCheckTimer;
|
||||||
|
|
||||||
// Props from React
|
// Props from React
|
||||||
private int backBufferDurationMs = DefaultLoadControl.DEFAULT_BACK_BUFFER_DURATION_MS;
|
private int backBufferDurationMs = DefaultLoadControl.DEFAULT_BACK_BUFFER_DURATION_MS;
|
||||||
@ -415,6 +418,40 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startBufferCheckTimer() {
|
||||||
|
SimpleExoPlayer player = this.player;
|
||||||
|
VideoEventEmitter eventEmitter = this.eventEmitter;
|
||||||
|
Handler mainHandler = this.mainHandler;
|
||||||
|
|
||||||
|
if (this.bufferCheckTimer != null) {
|
||||||
|
this.stopBufferCheckTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bufferCheckTimer = new Timer();
|
||||||
|
TimerTask bufferCheckTimerTask = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mainHandler != null) {
|
||||||
|
mainHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (player != null) {
|
||||||
|
double bufferedDuration = (double) (player.getBufferedPercentage() * player.getDuration() / 100);
|
||||||
|
eventEmitter.bufferProgress(0d, bufferedDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.bufferCheckTimer.scheduleAtFixedRate(bufferCheckTimerTask, 500, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopBufferCheckTimer() {
|
||||||
|
this.bufferCheckTimer.cancel();
|
||||||
|
this.bufferCheckTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
private void initializePlayer() {
|
private void initializePlayer() {
|
||||||
ReactExoplayerView self = this;
|
ReactExoplayerView self = this;
|
||||||
// This ensures all props have been settled, to avoid async racing conditions.
|
// This ensures all props have been settled, to avoid async racing conditions.
|
||||||
@ -506,6 +543,7 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
initializePlayerControl();
|
initializePlayerControl();
|
||||||
setControls(controls);
|
setControls(controls);
|
||||||
applyModifiers();
|
applyModifiers();
|
||||||
|
startBufferCheckTimer();
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
}
|
}
|
||||||
@ -597,6 +635,7 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
|
|
||||||
private void releasePlayer() {
|
private void releasePlayer() {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
|
stopBufferCheckTimer();
|
||||||
updateResumePosition();
|
updateResumePosition();
|
||||||
player.release();
|
player.release();
|
||||||
player.removeMetadataOutput(this);
|
player.removeMetadataOutput(this);
|
||||||
|
@ -42,6 +42,7 @@ class VideoEventEmitter {
|
|||||||
private static final String EVENT_RESUME = "onPlaybackResume";
|
private static final String EVENT_RESUME = "onPlaybackResume";
|
||||||
private static final String EVENT_READY = "onReadyForDisplay";
|
private static final String EVENT_READY = "onReadyForDisplay";
|
||||||
private static final String EVENT_BUFFER = "onVideoBuffer";
|
private static final String EVENT_BUFFER = "onVideoBuffer";
|
||||||
|
private static final String EVENT_BUFFER_PROGRESS = "onVideoBufferProgress";
|
||||||
private static final String EVENT_IDLE = "onVideoIdle";
|
private static final String EVENT_IDLE = "onVideoIdle";
|
||||||
private static final String EVENT_TIMED_METADATA = "onTimedMetadata";
|
private static final String EVENT_TIMED_METADATA = "onTimedMetadata";
|
||||||
private static final String EVENT_AUDIO_BECOMING_NOISY = "onVideoAudioBecomingNoisy";
|
private static final String EVENT_AUDIO_BECOMING_NOISY = "onVideoAudioBecomingNoisy";
|
||||||
@ -63,6 +64,7 @@ class VideoEventEmitter {
|
|||||||
EVENT_RESUME,
|
EVENT_RESUME,
|
||||||
EVENT_READY,
|
EVENT_READY,
|
||||||
EVENT_BUFFER,
|
EVENT_BUFFER,
|
||||||
|
EVENT_BUFFER_PROGRESS,
|
||||||
EVENT_IDLE,
|
EVENT_IDLE,
|
||||||
EVENT_TIMED_METADATA,
|
EVENT_TIMED_METADATA,
|
||||||
EVENT_AUDIO_BECOMING_NOISY,
|
EVENT_AUDIO_BECOMING_NOISY,
|
||||||
@ -87,6 +89,7 @@ class VideoEventEmitter {
|
|||||||
EVENT_RESUME,
|
EVENT_RESUME,
|
||||||
EVENT_READY,
|
EVENT_READY,
|
||||||
EVENT_BUFFER,
|
EVENT_BUFFER,
|
||||||
|
EVENT_BUFFER_PROGRESS,
|
||||||
EVENT_IDLE,
|
EVENT_IDLE,
|
||||||
EVENT_TIMED_METADATA,
|
EVENT_TIMED_METADATA,
|
||||||
EVENT_AUDIO_BECOMING_NOISY,
|
EVENT_AUDIO_BECOMING_NOISY,
|
||||||
@ -104,6 +107,8 @@ class VideoEventEmitter {
|
|||||||
private static final String EVENT_PROP_STEP_FORWARD = "canStepForward";
|
private static final String EVENT_PROP_STEP_FORWARD = "canStepForward";
|
||||||
private static final String EVENT_PROP_STEP_BACKWARD = "canStepBackward";
|
private static final String EVENT_PROP_STEP_BACKWARD = "canStepBackward";
|
||||||
|
|
||||||
|
private static final String EVENT_PROP_BUFFER_START = "bufferStart";
|
||||||
|
private static final String EVENT_PROP_BUFFER_END = "bufferEnd";
|
||||||
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";
|
||||||
@ -206,6 +211,13 @@ class VideoEventEmitter {
|
|||||||
receiveEvent(EVENT_BUFFER, map);
|
receiveEvent(EVENT_BUFFER, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bufferProgress(double start, double end) {
|
||||||
|
WritableMap map = Arguments.createMap();
|
||||||
|
map.putDouble(EVENT_PROP_BUFFER_START, start);
|
||||||
|
map.putDouble(EVENT_PROP_BUFFER_END, end);
|
||||||
|
receiveEvent(EVENT_BUFFER_PROGRESS, map);
|
||||||
|
}
|
||||||
|
|
||||||
void idle() {
|
void idle() {
|
||||||
receiveEvent(EVENT_IDLE, null);
|
receiveEvent(EVENT_IDLE, null);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user