feat: add isSeeking
to onPlaybackStateChanged
(#3899)
* feat: add `isSeeking` to `onPlaybackStateChanged`` * refactor `onSeek` event emit logic * fix rebase
This commit is contained in:
parent
b25e43ee79
commit
111a5d2163
@ -69,7 +69,7 @@ class VideoEventEmitter {
|
|||||||
lateinit var onVideoError: (errorString: String, exception: Exception, errorCode: String) -> Unit
|
lateinit var onVideoError: (errorString: String, exception: Exception, errorCode: String) -> Unit
|
||||||
lateinit var onVideoProgress: (currentPosition: Long, bufferedDuration: Long, seekableDuration: Long, currentPlaybackTime: Double) -> Unit
|
lateinit var onVideoProgress: (currentPosition: Long, bufferedDuration: Long, seekableDuration: Long, currentPlaybackTime: Double) -> Unit
|
||||||
lateinit var onVideoBandwidthUpdate: (bitRateEstimate: Long, height: Int, width: Int, trackId: String) -> Unit
|
lateinit var onVideoBandwidthUpdate: (bitRateEstimate: Long, height: Int, width: Int, trackId: String) -> Unit
|
||||||
lateinit var onVideoPlaybackStateChanged: (isPlaying: Boolean) -> Unit
|
lateinit var onVideoPlaybackStateChanged: (isPlaying: Boolean, isSeeking: Boolean) -> Unit
|
||||||
lateinit var onVideoSeek: (currentPosition: Long, seekTime: Long) -> Unit
|
lateinit var onVideoSeek: (currentPosition: Long, seekTime: Long) -> Unit
|
||||||
lateinit var onVideoEnd: () -> Unit
|
lateinit var onVideoEnd: () -> Unit
|
||||||
lateinit var onVideoFullscreenPlayerWillPresent: () -> Unit
|
lateinit var onVideoFullscreenPlayerWillPresent: () -> Unit
|
||||||
@ -158,9 +158,10 @@ class VideoEventEmitter {
|
|||||||
putString("trackId", trackId)
|
putString("trackId", trackId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onVideoPlaybackStateChanged = { isPlaying ->
|
onVideoPlaybackStateChanged = { isPlaying, isSeeking ->
|
||||||
event.dispatch(EventTypes.EVENT_PLAYBACK_STATE_CHANGED) {
|
event.dispatch(EventTypes.EVENT_PLAYBACK_STATE_CHANGED) {
|
||||||
putBoolean("isPlaying", isPlaying)
|
putBoolean("isPlaying", isPlaying)
|
||||||
|
putBoolean("isSeeking", isSeeking)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onVideoSeek = { currentPosition, seekTime ->
|
onVideoSeek = { currentPosition, seekTime ->
|
||||||
|
@ -221,6 +221,13 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
private boolean useCache = false;
|
private boolean useCache = false;
|
||||||
private ControlsConfig controlsConfig = new ControlsConfig();
|
private ControlsConfig controlsConfig = new ControlsConfig();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When user is seeking first called is on onPositionDiscontinuity -> DISCONTINUITY_REASON_SEEK
|
||||||
|
* Then we set if to false when playback is back in onIsPlayingChanged -> true
|
||||||
|
*/
|
||||||
|
private boolean isSeeking = false;
|
||||||
|
private long seekPosition = -1;
|
||||||
|
|
||||||
// Props from React
|
// Props from React
|
||||||
private Source source = new Source();
|
private Source source = new Source();
|
||||||
private boolean repeat;
|
private boolean repeat;
|
||||||
@ -1618,6 +1625,11 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPaused && isSeeking && !buffering) {
|
||||||
|
eventEmitter.onVideoSeek.invoke(player.getCurrentPosition(), seekPosition);
|
||||||
|
isSeeking = false;
|
||||||
|
}
|
||||||
|
|
||||||
isBuffering = buffering;
|
isBuffering = buffering;
|
||||||
eventEmitter.onVideoBuffer.invoke(buffering);
|
eventEmitter.onVideoBuffer.invoke(buffering);
|
||||||
}
|
}
|
||||||
@ -1625,7 +1637,8 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
@Override
|
@Override
|
||||||
public void onPositionDiscontinuity(@NonNull Player.PositionInfo oldPosition, @NonNull Player.PositionInfo newPosition, @Player.DiscontinuityReason int reason) {
|
public void onPositionDiscontinuity(@NonNull Player.PositionInfo oldPosition, @NonNull Player.PositionInfo newPosition, @Player.DiscontinuityReason int reason) {
|
||||||
if (reason == Player.DISCONTINUITY_REASON_SEEK) {
|
if (reason == Player.DISCONTINUITY_REASON_SEEK) {
|
||||||
eventEmitter.onVideoSeek.invoke(player.getCurrentPosition(), newPosition.positionMs % 1000); // time are in seconds /°\
|
isSeeking = true;
|
||||||
|
seekPosition = newPosition.positionMs;
|
||||||
if (isUsingContentResolution) {
|
if (isUsingContentResolution) {
|
||||||
// We need to update the selected track to make sure that it still matches user selection if track list has changed in this period
|
// We need to update the selected track to make sure that it still matches user selection if track list has changed in this period
|
||||||
setSelectedTrack(C.TRACK_TYPE_VIDEO, videoTrackType, videoTrackValue);
|
setSelectedTrack(C.TRACK_TYPE_VIDEO, videoTrackType, videoTrackValue);
|
||||||
@ -1676,7 +1689,15 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onIsPlayingChanged(boolean isPlaying) {
|
public void onIsPlayingChanged(boolean isPlaying) {
|
||||||
eventEmitter.onVideoPlaybackStateChanged.invoke(isPlaying);
|
if (isPlaying && isSeeking) {
|
||||||
|
eventEmitter.onVideoSeek.invoke(player.getCurrentPosition(), seekPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
eventEmitter.onVideoPlaybackStateChanged.invoke(isPlaying, isSeeking);
|
||||||
|
|
||||||
|
if (isPlaying) {
|
||||||
|
isSeeking = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -297,14 +297,16 @@ Callback function that is called when the playback state changes.
|
|||||||
Payload:
|
Payload:
|
||||||
|
|
||||||
| Property | Type | Description |
|
| Property | Type | Description |
|
||||||
| --------- | ----------- | ------------------------------------------------- |
|
| --------- | ----------- | -------------------------------------------------- |
|
||||||
| isPlaying | boolean | Boolean indicating if the media is playing or not |
|
| isPlaying | boolean | Boolean indicating if the media is playing or not |
|
||||||
|
| isSeeking | boolean | Boolean indicating if the player is seeking or not |
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
isPlaying: true,
|
isPlaying: true,
|
||||||
|
isSeeking: false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -758,8 +758,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
let seekTime: NSNumber! = info["time"] as! NSNumber
|
let seekTime: NSNumber! = info["time"] as! NSNumber
|
||||||
let seekTolerance: NSNumber! = info["tolerance"] as! NSNumber
|
let seekTolerance: NSNumber! = info["tolerance"] as! NSNumber
|
||||||
let item: AVPlayerItem? = _player?.currentItem
|
let item: AVPlayerItem? = _player?.currentItem
|
||||||
guard item != nil, let player = _player, let item, item.status == AVPlayerItem.Status.readyToPlay else {
|
|
||||||
_pendingSeek = true
|
_pendingSeek = true
|
||||||
|
|
||||||
|
guard item != nil, let player = _player, let item, item.status == AVPlayerItem.Status.readyToPlay else {
|
||||||
_pendingSeekTime = seekTime.floatValue
|
_pendingSeekTime = seekTime.floatValue
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1486,7 +1488,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
|
|
||||||
guard _isPlaying != isPlaying else { return }
|
guard _isPlaying != isPlaying else { return }
|
||||||
_isPlaying = isPlaying
|
_isPlaying = isPlaying
|
||||||
onVideoPlaybackStateChanged?(["isPlaying": isPlaying, "target": reactTag as Any])
|
onVideoPlaybackStateChanged?(["isPlaying": isPlaying, "isSeeking": self._pendingSeek == true, "target": reactTag as Any])
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>) {
|
func handlePlaybackRateChange(player: AVPlayer, change: NSKeyValueObservedChange<Float>) {
|
||||||
|
@ -189,6 +189,7 @@ export type OnSeekData = Readonly<{
|
|||||||
|
|
||||||
export type OnPlaybackStateChangedData = Readonly<{
|
export type OnPlaybackStateChangedData = Readonly<{
|
||||||
isPlaying: boolean;
|
isPlaying: boolean;
|
||||||
|
isSeeking: boolean;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type OnTimedMetadataData = Readonly<{
|
export type OnTimedMetadataData = Readonly<{
|
||||||
|
Loading…
Reference in New Issue
Block a user