fix: ensure progress is sent before onEnd
callback (#3872)
* fix: add onProgress event before onEnd
This commit is contained in:
parent
adedc052f0
commit
7133c96cac
@ -57,9 +57,7 @@ class Source {
|
||||
}
|
||||
|
||||
/** return true if this and src are equals */
|
||||
fun isEquals(source: Source): Boolean {
|
||||
return this == source
|
||||
}
|
||||
fun isEquals(source: Source): Boolean = this == source
|
||||
|
||||
/** Metadata to display in notification */
|
||||
class Metadata {
|
||||
|
@ -258,29 +258,36 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
private long lastBufferDuration = -1;
|
||||
private long lastDuration = -1;
|
||||
|
||||
private void updateProgress() {
|
||||
if (player != null) {
|
||||
if (playerControlView != null && isPlayingAd() && controls) {
|
||||
playerControlView.hide();
|
||||
}
|
||||
long bufferedDuration = player.getBufferedPercentage() * player.getDuration() / 100;
|
||||
long duration = player.getDuration();
|
||||
long pos = player.getCurrentPosition();
|
||||
if (pos > duration) {
|
||||
pos = duration;
|
||||
}
|
||||
|
||||
if (lastPos != pos
|
||||
|| lastBufferDuration != bufferedDuration
|
||||
|| lastDuration != duration) {
|
||||
lastPos = pos;
|
||||
lastBufferDuration = bufferedDuration;
|
||||
lastDuration = duration;
|
||||
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration(), getPositionInFirstPeriodMsForCurrentWindow(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final Handler progressHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.what == SHOW_PROGRESS) {
|
||||
if (player != null) {
|
||||
if (playerControlView != null && isPlayingAd() && controls) {
|
||||
playerControlView.hide();
|
||||
}
|
||||
long pos = player.getCurrentPosition();
|
||||
long bufferedDuration = player.getBufferedPercentage() * player.getDuration() / 100;
|
||||
long duration = player.getDuration();
|
||||
|
||||
if (lastPos != pos
|
||||
|| lastBufferDuration != bufferedDuration
|
||||
|| lastDuration != duration) {
|
||||
lastPos = pos;
|
||||
lastBufferDuration = bufferedDuration;
|
||||
lastDuration = duration;
|
||||
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration(), getPositionInFirstPeriodMsForCurrentWindow(pos));
|
||||
}
|
||||
msg = obtainMessage(SHOW_PROGRESS);
|
||||
sendMessageDelayed(msg, Math.round(mProgressUpdateInterval));
|
||||
}
|
||||
updateProgress();
|
||||
msg = obtainMessage(SHOW_PROGRESS);
|
||||
sendMessageDelayed(msg, Math.round(mProgressUpdateInterval));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1337,6 +1344,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
break;
|
||||
case Player.STATE_ENDED:
|
||||
text += "ended";
|
||||
updateProgress();
|
||||
eventEmitter.end();
|
||||
onStopPlayback();
|
||||
setKeepScreenOn(false);
|
||||
@ -1614,6 +1622,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
||||
// so we need to explicitly detect it.
|
||||
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION
|
||||
&& player.getRepeatMode() == Player.REPEAT_MODE_ONE) {
|
||||
updateProgress();
|
||||
eventEmitter.end();
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
|
||||
// MARK: - Progress
|
||||
|
||||
func sendProgressUpdate() {
|
||||
func sendProgressUpdate(didEnd: Bool = false) {
|
||||
#if !USE_GOOGLE_IMA
|
||||
// If we dont use Ads and onVideoProgress is not defined we dont need to run this code
|
||||
guard onVideoProgress != nil else { return }
|
||||
@ -334,11 +334,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
}
|
||||
let currentPlaybackTime = _player?.currentItem?.currentDate()
|
||||
let duration = CMTimeGetSeconds(playerDuration)
|
||||
let currentTimeSecs = CMTimeGetSeconds(currentTime ?? .zero)
|
||||
var currentTimeSecs = CMTimeGetSeconds(currentTime ?? .zero)
|
||||
|
||||
NotificationCenter.default.post(name: NSNotification.Name("RCTVideo_progress"), object: nil, userInfo: [
|
||||
"progress": NSNumber(value: currentTimeSecs / duration),
|
||||
])
|
||||
if currentTimeSecs > duration || didEnd {
|
||||
currentTimeSecs = duration
|
||||
}
|
||||
|
||||
if currentTimeSecs >= 0 {
|
||||
#if USE_GOOGLE_IMA
|
||||
@ -348,10 +348,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
}
|
||||
#endif
|
||||
onVideoProgress?([
|
||||
"currentTime": NSNumber(value: Float(currentTimeSecs)),
|
||||
"currentTime": currentTimeSecs,
|
||||
"playableDuration": RCTVideoUtils.calculatePlayableDuration(_player, withSource: _source),
|
||||
"atValue": NSNumber(value: currentTime?.value ?? .zero),
|
||||
"currentPlaybackTime": NSNumber(value: NSNumber(value: Double(currentPlaybackTime?.timeIntervalSince1970 ?? 0 * 1000)).int64Value),
|
||||
"atValue": currentTime?.value ?? .zero,
|
||||
"currentPlaybackTime": NSNumber(value: Double(currentPlaybackTime?.timeIntervalSince1970 ?? 0 * 1000)).int64Value,
|
||||
"target": reactTag,
|
||||
"seekableDuration": RCTVideoUtils.calculateSeekableDuration(_player),
|
||||
])
|
||||
@ -1570,6 +1570,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
||||
|
||||
@objc
|
||||
func handlePlayerItemDidReachEnd(notification: NSNotification!) {
|
||||
sendProgressUpdate(didEnd: true)
|
||||
onVideoEnd?(["target": reactTag as Any])
|
||||
#if USE_GOOGLE_IMA
|
||||
if notification.object as? AVPlayerItem == _player?.currentItem {
|
||||
|
Loading…
Reference in New Issue
Block a user