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