feat: implement startPosition (#3355)

* feat(android): implement startPosition

* feat(ios): implement startPosition

* feat: implement startPosition type

* docs: fix typo

* docs: update startPosition

* refactor: put startPosition inside source prop
- put startPosition inside source prop
- rename existing prop (startTime, endTime)

* docs: update startPosition property description

* fix: fix invalid assignments

* refactor: remove redundant optional chaining

* feat: allow "0" to work too
This commit is contained in:
YangJH
2023-11-24 20:52:46 +09:00
committed by GitHub
parent 0c0f3174cb
commit 2648502b36
9 changed files with 86 additions and 47 deletions

View File

@@ -192,8 +192,9 @@ public class ReactExoplayerView extends FrameLayout implements
// Props from React
private int backBufferDurationMs = DefaultLoadControl.DEFAULT_BACK_BUFFER_DURATION_MS;
private Uri srcUri;
private long startTimeMs = -1;
private long endTimeMs = -1;
private long startPositionMs = -1;
private long cropStartMs = -1;
private long cropEndMs = -1;
private String extension;
private boolean repeat;
private String audioTrackType;
@@ -662,7 +663,7 @@ public class ReactExoplayerView extends FrameLayout implements
private void initializePlayerSource(ReactExoplayerView self, DrmSessionManager drmSessionManager) {
ArrayList<MediaSource> mediaSourceList = buildTextSources();
MediaSource videoSource = buildMediaSource(self.srcUri, self.extension, drmSessionManager, startTimeMs, endTimeMs);
MediaSource videoSource = buildMediaSource(self.srcUri, self.extension, drmSessionManager, cropStartMs, cropEndMs);
MediaSource mediaSourceWithAds = null;
if (adTagUrl != null) {
MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory)
@@ -703,7 +704,12 @@ public class ReactExoplayerView extends FrameLayout implements
if (haveResumePosition) {
player.seekTo(resumeWindow, resumePosition);
}
player.prepare(mediaSource, !haveResumePosition, false);
if (startPositionMs >= 0) {
player.setMediaSource(mediaSource, startPositionMs);
} else {
player.setMediaSource(mediaSource, !haveResumePosition);
}
player.prepare();
playerNeedsSource = false;
reLayout(exoPlayerView);
@@ -761,7 +767,7 @@ public class ReactExoplayerView extends FrameLayout implements
}
}
private MediaSource buildMediaSource(Uri uri, String overrideExtension, DrmSessionManager drmSessionManager, long startTimeMs, long endTimeMs) {
private MediaSource buildMediaSource(Uri uri, String overrideExtension, DrmSessionManager drmSessionManager, long cropStartMs, long cropEndMs) {
if (uri == null) {
throw new IllegalStateException("Invalid video uri");
}
@@ -822,12 +828,12 @@ public class ReactExoplayerView extends FrameLayout implements
)
.createMediaSource(mediaItem);
if (startTimeMs >= 0 && endTimeMs >= 0) {
return new ClippingMediaSource(mediaSource, startTimeMs * 1000, endTimeMs * 1000);
} else if (startTimeMs >= 0) {
return new ClippingMediaSource(mediaSource, startTimeMs * 1000, TIME_END_OF_SOURCE);
} else if (endTimeMs >= 0) {
return new ClippingMediaSource(mediaSource, 0, endTimeMs * 1000);
if (cropStartMs >= 0 && cropEndMs >= 0) {
return new ClippingMediaSource(mediaSource, cropStartMs * 1000, cropEndMs * 1000);
} else if (cropStartMs >= 0) {
return new ClippingMediaSource(mediaSource, cropStartMs * 1000, TIME_END_OF_SOURCE);
} else if (cropEndMs >= 0) {
return new ClippingMediaSource(mediaSource, 0, cropEndMs * 1000);
}
return mediaSource;
@@ -1500,13 +1506,14 @@ public class ReactExoplayerView extends FrameLayout implements
// ReactExoplayerViewManager public api
public void setSrc(final Uri uri, final long startTimeMs, final long endTimeMs, final String extension, Map<String, String> headers) {
public void setSrc(final Uri uri, final long startPositionMs, final long cropStartMs, final long cropEndMs, final String extension, Map<String, String> headers) {
if (uri != null) {
boolean isSourceEqual = uri.equals(srcUri) && startTimeMs == this.startTimeMs && endTimeMs == this.endTimeMs;
boolean isSourceEqual = uri.equals(srcUri) && cropStartMs == this.cropStartMs && cropEndMs == this.cropEndMs;
hasDrmFailed = false;
this.srcUri = uri;
this.startTimeMs = startTimeMs;
this.endTimeMs = endTimeMs;
this.startPositionMs = startPositionMs;
this.cropStartMs = cropStartMs;
this.cropEndMs = cropEndMs;
this.extension = extension;
this.requestHeaders = headers;
this.mediaDataSourceFactory =
@@ -1524,8 +1531,9 @@ public class ReactExoplayerView extends FrameLayout implements
player.stop();
player.clearMediaItems();
this.srcUri = null;
this.startTimeMs = -1;
this.endTimeMs = -1;
this.startPositionMs = -1;
this.cropStartMs = -1;
this.cropEndMs = -1;
this.extension = null;
this.requestHeaders = null;
this.mediaDataSourceFactory = null;

View File

@@ -36,8 +36,9 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String REACT_CLASS = "RCTVideo";
private static final String PROP_SRC = "src";
private static final String PROP_SRC_URI = "uri";
private static final String PROP_SRC_START_TIME = "startTime";
private static final String PROP_SRC_END_TIME = "endTime";
private static final String PROP_SRC_START_POSITION = "startPosition";
private static final String PROP_SRC_CROP_START = "cropStart";
private static final String PROP_SRC_CROP_END = "cropEnd";
private static final String PROP_AD_TAG_URL = "adTagUrl";
private static final String PROP_SRC_TYPE = "type";
private static final String PROP_DRM = "drm";
@@ -75,6 +76,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_MIN_LOAD_RETRY_COUNT = "minLoadRetryCount";
private static final String PROP_MAXIMUM_BIT_RATE = "maxBitRate";
private static final String PROP_PLAY_IN_BACKGROUND = "playInBackground";
private static final String PROP_START_POSITION = "startPosition";
private static final String PROP_CONTENT_START_TIME = "contentStartTime";
private static final String PROP_DISABLE_FOCUS = "disableFocus";
private static final String PROP_DISABLE_BUFFERING = "disableBuffering";
@@ -151,8 +153,9 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
public void setSrc(final ReactExoplayerView videoView, @Nullable ReadableMap src) {
Context context = videoView.getContext().getApplicationContext();
String uriString = ReactBridgeUtils.safeGetString(src, PROP_SRC_URI, null);
int startTimeMs = ReactBridgeUtils.safeGetInt(src, PROP_SRC_START_TIME, -1);
int endTimeMs = ReactBridgeUtils.safeGetInt(src, PROP_SRC_END_TIME, -1);
int startPositionMs = ReactBridgeUtils.safeGetInt(src, PROP_START_POSITION, -1);
int cropStartMs = ReactBridgeUtils.safeGetInt(src, PROP_SRC_CROP_START, -1);
int cropEndMs = ReactBridgeUtils.safeGetInt(src, PROP_SRC_CROP_END, -1);
String extension = ReactBridgeUtils.safeGetString(src, PROP_SRC_TYPE, null);
Map<String, String> headers = src.hasKey(PROP_SRC_HEADERS) ? ReactBridgeUtils.toStringMap(src.getMap(PROP_SRC_HEADERS)) : new HashMap<>();
@@ -166,7 +169,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
Uri srcUri = Uri.parse(uriString);
if (srcUri != null) {
videoView.setSrc(srcUri, startTimeMs, endTimeMs, extension, headers);
videoView.setSrc(srcUri, startPositionMs, cropStartMs, cropEndMs, extension, headers);
}
} else {
int identifier = context.getResources().getIdentifier(