Expose currentPlaybackTime when live stream video (#1944)
* added trackId to exoplayer onLoad callback * added trackInfo to bandwidth callback * syntax fix * syntax fix * version update * sending complete logcat for media playback exception ExoPlaybackException * version bump * package publish changes * Live playback fix * Version bump * import fix * version bump * configurable preferredForwardBufferDuration * configurable preferredForwardBufferDuration * version update * Exposing time * exo player window current tsp * return type * Current window timestamp in epoch * iOS changes * version update * Updated package.json * updated version * CurrentTime bug fix * Updated package.json * Updated currentPlaybackTime * Updated currentPlayback logic * Updated package.json * Bug fix * Added semicolon * updated package.json * Updated ReactVideoView * updated verison * Revert package.json changes * Update ReactVideoView.java * Use standard log * Document preferredForwardBufferDuration (iOS) * Document currentPlaybackTime * Document trackId * Update CHANGELOG.md * Update CHANGELOG.md * Update README.md * Update CHANGELOG.md Co-authored-by: anubansal <anu.bansal@curefit.com> Co-authored-by: Sivakumar J <sivakumar@curefit.com> Co-authored-by: parikshit <parikshit@curefit.com> Co-authored-by: anubansal92 <40559524+anubansal92@users.noreply.github.com> Co-authored-by: Rishu Agrawal <rishu.agrawal@v.curefit.com> Co-authored-by: rishu-curefit <54575330+rishu-curefit@users.noreply.github.com>
This commit is contained in:
@@ -64,6 +64,7 @@ import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
import java.net.CookieHandler;
|
||||
@@ -161,7 +162,7 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
) {
|
||||
long pos = player.getCurrentPosition();
|
||||
long bufferedDuration = player.getBufferedPercentage() * player.getDuration() / 100;
|
||||
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration());
|
||||
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration(), getPositionInFirstPeriodMsForCurrentWindow(pos));
|
||||
msg = obtainMessage(SHOW_PROGRESS);
|
||||
sendMessageDelayed(msg, Math.round(mProgressUpdateInterval));
|
||||
}
|
||||
@@ -169,6 +170,14 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public double getPositionInFirstPeriodMsForCurrentWindow(long currentPosition) {
|
||||
Timeline.Window window = new Timeline.Window();
|
||||
if(!player.getCurrentTimeline().isEmpty()) {
|
||||
player.getCurrentTimeline().getWindow(player.getCurrentWindowIndex(), window);
|
||||
}
|
||||
return window.windowStartTimeMs + currentPosition;
|
||||
}
|
||||
|
||||
public ReactExoplayerView(ThemedReactContext context, ReactExoplayerConfig config) {
|
||||
super(context);
|
||||
@@ -257,7 +266,15 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
@Override
|
||||
public void onBandwidthSample(int elapsedMs, long bytes, long bitrate) {
|
||||
if (mReportBandwidth) {
|
||||
eventEmitter.bandwidthReport(bitrate);
|
||||
if (player == null) {
|
||||
eventEmitter.bandwidthReport(bitrate, 0, 0, "-1");
|
||||
} else {
|
||||
Format videoFormat = player.getVideoFormat();
|
||||
int width = videoFormat != null ? videoFormat.width : 0;
|
||||
int height = videoFormat != null ? videoFormat.height : 0;
|
||||
String trackId = videoFormat != null ? videoFormat.id : "-1";
|
||||
eventEmitter.bandwidthReport(bitrate, height, width, trackId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,8 +766,9 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
Format videoFormat = player.getVideoFormat();
|
||||
int width = videoFormat != null ? videoFormat.width : 0;
|
||||
int height = videoFormat != null ? videoFormat.height : 0;
|
||||
String trackId = videoFormat != null ? videoFormat.id : "-1";
|
||||
eventEmitter.load(player.getDuration(), player.getCurrentPosition(), width, height,
|
||||
getAudioTrackInfo(), getTextTrackInfo(), getVideoTrackInfo());
|
||||
getAudioTrackInfo(), getTextTrackInfo(), getVideoTrackInfo(), trackId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,7 +907,7 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException e) {
|
||||
String errorString = null;
|
||||
String errorString = "ExoPlaybackException type : " + e.type;
|
||||
Exception ex = e;
|
||||
if (e.type == ExoPlaybackException.TYPE_RENDERER) {
|
||||
Exception cause = e.getRendererException();
|
||||
@@ -914,12 +932,9 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
}
|
||||
else if (e.type == ExoPlaybackException.TYPE_SOURCE) {
|
||||
ex = e.getSourceException();
|
||||
errorString = getResources().getString(R.string.unrecognized_media_format);
|
||||
}
|
||||
if (errorString != null) {
|
||||
eventEmitter.error(errorString, ex);
|
||||
}
|
||||
eventEmitter.error(errorString, ex);
|
||||
playerNeedsSource = true;
|
||||
if (isBehindLiveWindow(e)) {
|
||||
clearResumePosition();
|
||||
@@ -930,12 +945,14 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
|
||||
private static boolean isBehindLiveWindow(ExoPlaybackException e) {
|
||||
Log.e("ExoPlayer Exception", e.toString());
|
||||
if (e.type != ExoPlaybackException.TYPE_SOURCE) {
|
||||
return false;
|
||||
}
|
||||
Throwable cause = e.getSourceException();
|
||||
while (cause != null) {
|
||||
if (cause instanceof BehindLiveWindowException) {
|
||||
if (cause instanceof BehindLiveWindowException ||
|
||||
cause instanceof HttpDataSource.HttpDataSourceException) {
|
||||
return true;
|
||||
}
|
||||
cause = cause.getCause();
|
||||
|
@@ -107,8 +107,10 @@ class VideoEventEmitter {
|
||||
private static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration";
|
||||
private static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration";
|
||||
private static final String EVENT_PROP_CURRENT_TIME = "currentTime";
|
||||
private static final String EVENT_PROP_CURRENT_PLAYBACK_TIME = "currentPlaybackTime";
|
||||
private static final String EVENT_PROP_SEEK_TIME = "seekTime";
|
||||
private static final String EVENT_PROP_NATURAL_SIZE = "naturalSize";
|
||||
private static final String EVENT_PROP_TRACK_ID = "trackId";
|
||||
private static final String EVENT_PROP_WIDTH = "width";
|
||||
private static final String EVENT_PROP_HEIGHT = "height";
|
||||
private static final String EVENT_PROP_ORIENTATION = "orientation";
|
||||
@@ -137,7 +139,7 @@ class VideoEventEmitter {
|
||||
}
|
||||
|
||||
void load(double duration, double currentPosition, int videoWidth, int videoHeight,
|
||||
WritableArray audioTracks, WritableArray textTracks, WritableArray videoTracks) {
|
||||
WritableArray audioTracks, WritableArray textTracks, WritableArray videoTracks, String trackId) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putDouble(EVENT_PROP_DURATION, duration / 1000D);
|
||||
event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D);
|
||||
@@ -151,7 +153,7 @@ class VideoEventEmitter {
|
||||
naturalSize.putString(EVENT_PROP_ORIENTATION, "portrait");
|
||||
}
|
||||
event.putMap(EVENT_PROP_NATURAL_SIZE, naturalSize);
|
||||
|
||||
event.putString(EVENT_PROP_TRACK_ID, trackId);
|
||||
event.putArray(EVENT_PROP_VIDEO_TRACKS, videoTracks);
|
||||
event.putArray(EVENT_PROP_AUDIO_TRACKS, audioTracks);
|
||||
event.putArray(EVENT_PROP_TEXT_TRACKS, textTracks);
|
||||
@@ -168,17 +170,21 @@ class VideoEventEmitter {
|
||||
receiveEvent(EVENT_LOAD, event);
|
||||
}
|
||||
|
||||
void progressChanged(double currentPosition, double bufferedDuration, double seekableDuration) {
|
||||
void progressChanged(double currentPosition, double bufferedDuration, double seekableDuration, double currentPlaybackTime) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D);
|
||||
event.putDouble(EVENT_PROP_PLAYABLE_DURATION, bufferedDuration / 1000D);
|
||||
event.putDouble(EVENT_PROP_SEEKABLE_DURATION, seekableDuration / 1000D);
|
||||
event.putDouble(EVENT_PROP_CURRENT_PLAYBACK_TIME, currentPlaybackTime);
|
||||
receiveEvent(EVENT_PROGRESS, event);
|
||||
}
|
||||
|
||||
void bandwidthReport(double bitRateEstimate) {
|
||||
void bandwidthReport(double bitRateEstimate, int height, int width, String id) {
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putDouble(EVENT_PROP_BITRATE, bitRateEstimate);
|
||||
event.putInt(EVENT_PROP_WIDTH, width);
|
||||
event.putInt(EVENT_PROP_HEIGHT, height);
|
||||
event.putString(EVENT_PROP_TRACK_ID, id);
|
||||
receiveEvent(EVENT_BANDWIDTH, event);
|
||||
}
|
||||
|
||||
@@ -226,7 +232,7 @@ class VideoEventEmitter {
|
||||
void error(String errorString, Exception exception) {
|
||||
WritableMap error = Arguments.createMap();
|
||||
error.putString(EVENT_PROP_ERROR_STRING, errorString);
|
||||
error.putString(EVENT_PROP_ERROR_EXCEPTION, exception.getMessage());
|
||||
error.putString(EVENT_PROP_ERROR_EXCEPTION, exception.toString());
|
||||
WritableMap event = Arguments.createMap();
|
||||
event.putMap(EVENT_PROP_ERROR, error);
|
||||
receiveEvent(EVENT_ERROR, event);
|
||||
|
Reference in New Issue
Block a user