react-native-video-trim 2.2.3 → 2.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -56,6 +56,11 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
56
56
 
57
57
  private ReactApplicationContext mContext;
58
58
  private VideoView mVideoView;
59
+
60
+ // mediaPlayer is used for both video/audio
61
+ // the reason we use mediaPlayer for Video: https://stackoverflow.com/a/73361868/7569705
62
+ // the videoPlayer is to solve the issue after manually seek -> hit play -> it starts from a position slightly before with the one we just sought to
63
+ private MediaPlayer mediaPlayer;
59
64
  private ImageView mPlayView;
60
65
  private LinearLayout mThumbnailContainer;
61
66
  private Uri mSourceUri;
@@ -96,7 +101,6 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
96
101
  private TextView cancelBtn;
97
102
  private FrameLayout audioBannerView;
98
103
  private boolean isVideoType = true;
99
- private MediaPlayer audioPlayer;
100
104
  private ImageView failToLoadBtn;
101
105
 
102
106
  private String mOutputExt = "mp4";
@@ -110,6 +114,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
110
114
  private String alertOnFailTitle = "Error";
111
115
  private String alertOnFailMessage = "Fail to load media. Possibly invalid file or no network connection";
112
116
  private String alertOnFailCloseText = "Close";
117
+ private View currentSelectedhandle;
113
118
 
114
119
  public VideoTrimmerView(ReactApplicationContext context, ReadableMap config, AttributeSet attrs) {
115
120
  this(context, attrs, 0, config);
@@ -171,11 +176,11 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
171
176
 
172
177
  mVideoView.setOnPreparedListener(mp -> {
173
178
  mp.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
179
+ mediaPlayer = mp;
174
180
  mediaPrepared();
175
181
  });
176
182
 
177
183
  mVideoView.setOnErrorListener(this::onFailToLoadMedia);
178
-
179
184
  mVideoView.setOnCompletionListener(mp -> mediaCompleted());
180
185
  } else {
181
186
  mVideoView.setVisibility(View.GONE);
@@ -183,16 +188,16 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
183
188
  audioBannerView.setVisibility(View.VISIBLE);
184
189
  audioBannerView.animate().alpha(1f).setDuration(500).start();
185
190
 
186
- audioPlayer = new MediaPlayer();
191
+ mediaPlayer = new MediaPlayer();
187
192
  try {
188
- audioPlayer.setDataSource(videoURI.toString());
189
- audioPlayer.setOnPreparedListener(mp -> {
193
+ mediaPlayer.setDataSource(videoURI.toString());
194
+ mediaPlayer.setOnPreparedListener(mp -> {
190
195
  mediaPrepared();
191
196
  });
192
- audioPlayer.setOnCompletionListener(mp -> mediaCompleted());
193
- audioPlayer.setOnErrorListener(this::onFailToLoadMedia);
197
+ mediaPlayer.setOnCompletionListener(mp -> mediaCompleted());
198
+ mediaPlayer.setOnErrorListener(this::onFailToLoadMedia);
194
199
 
195
- audioPlayer.prepareAsync(); // use prepareAsync to avoid blocking the main thread
200
+ mediaPlayer.prepareAsync(); // use prepareAsync to avoid blocking the main thread
196
201
  } catch (IOException e) {
197
202
  e.printStackTrace();
198
203
  mediaFailed();
@@ -239,7 +244,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
239
244
  }
240
245
 
241
246
  private void mediaPrepared() {
242
- mDuration = isVideoType ? mVideoView.getDuration() : audioPlayer.getDuration();
247
+ mDuration = mediaPlayer.getDuration();
243
248
  mMaxDuration = Math.min(mMaxDuration, mDuration);
244
249
 
245
250
  if (isVideoType) {
@@ -327,46 +332,23 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
327
332
  }
328
333
 
329
334
  private void playOrPause() {
330
- if (isVideoType) {
331
- if (mVideoView.isPlaying()) {
332
- onMediaPause();
333
- } else {
334
- // if current video time >= end time, seek to start time
335
- if (mVideoView.getCurrentPosition() >= endTime) {
336
- seekTo(startTime, true);
337
- }
338
- mVideoView.start();
339
- startTimingRunnable();
340
- }
341
- setPlayPauseViewIcon(mVideoView.isPlaying());
342
-
335
+ if (mediaPlayer.isPlaying()) {
336
+ onMediaPause();
343
337
  } else {
344
- if (audioPlayer.isPlaying()) {
345
- onMediaPause();
346
- } else {
347
- if (audioPlayer.getCurrentPosition() >= endTime) {
348
- seekTo(startTime, true);
349
- }
350
- audioPlayer.start();
351
- startTimingRunnable();
338
+ if (mediaPlayer.getCurrentPosition() >= endTime) {
339
+ seekTo(startTime, true);
352
340
  }
353
- setPlayPauseViewIcon(audioPlayer.isPlaying());
341
+ mediaPlayer.start();
342
+ startTimingRunnable();
354
343
  }
344
+ setPlayPauseViewIcon(mediaPlayer.isPlaying());
355
345
  }
356
346
 
357
347
  public void onMediaPause() {
358
- if (isVideoType) {
359
- if (mVideoView.isPlaying()) {
360
- mTimingHandler.removeCallbacks(mTimingRunnable);
361
- mVideoView.pause();
362
- setPlayPauseViewIcon(false);
363
- }
364
- } else {
365
- if (audioPlayer.isPlaying()) {
366
- mTimingHandler.removeCallbacks(mTimingRunnable);
367
- audioPlayer.pause();
368
- setPlayPauseViewIcon(false);
369
- }
348
+ if (mediaPlayer.isPlaying()) {
349
+ mTimingHandler.removeCallbacks(mTimingRunnable);
350
+ mediaPlayer.pause();
351
+ setPlayPauseViewIcon(false);
370
352
  }
371
353
  }
372
354
 
@@ -402,10 +384,10 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
402
384
  }
403
385
 
404
386
  private void seekTo(long msec, boolean needUpdateProgress) {
405
- if (isVideoType) {
406
- mVideoView.seekTo((int) msec);
387
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
388
+ mediaPlayer.seekTo((int) msec, MediaPlayer.SEEK_CLOSEST);
407
389
  } else {
408
- audioPlayer.seekTo((int) msec);
390
+ mediaPlayer.seekTo((int) msec);
409
391
  }
410
392
 
411
393
  updateCurrentTime(needUpdateProgress);
@@ -438,9 +420,15 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
438
420
  e.printStackTrace();
439
421
  }
440
422
 
441
- if (audioPlayer != null) {
442
- audioPlayer.stop();
443
- audioPlayer.release();
423
+ try {
424
+ if (mediaPlayer != null) {
425
+ mediaPlayer.stop();
426
+ mediaPlayer.release();
427
+ }
428
+ } catch (IllegalStateException e) {
429
+ // if it's video, resource is released with the view, and here we also call .release which will throw exception
430
+ e.printStackTrace();
431
+ Log.d(TAG, "onDestroy mediaPlayer is already released");
444
432
  }
445
433
  }
446
434
 
@@ -533,13 +521,21 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
533
521
  mTimingRunnable = new Runnable() {
534
522
  @Override
535
523
  public void run() {
536
- int currentPosition;
537
- if (isVideoType) {
538
- currentPosition = mVideoView.getCurrentPosition();
539
- } else {
540
- currentPosition = audioPlayer.getCurrentPosition();
524
+ // prevent crashing when video is playing and we close editor
525
+ try {
526
+ if (mediaPlayer == null || !mediaPlayer.isPlaying()) {
527
+ mTimingHandler.removeCallbacks(mTimingRunnable);
528
+ return;
529
+ }
530
+ } catch (IllegalStateException e) {
531
+ e.printStackTrace();
532
+ mTimingHandler.removeCallbacks(mTimingRunnable);
533
+ Log.d(TAG, "startTimingRunnable mediaPlayer is already released");
534
+ return;
541
535
  }
542
536
 
537
+ int currentPosition = mediaPlayer.getCurrentPosition();
538
+
543
539
  if (currentPosition >= endTime) {
544
540
  onMediaPause();
545
541
  seekTo(endTime, true); // Ensure exact end time display
@@ -555,12 +551,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
555
551
  private void updateCurrentTime(boolean needUpdateProgress) {
556
552
  // TODO: check the case after drag the progress indicator and hit play, it'll play a little bit earlier than the progress indicator
557
553
 
558
- int currentPosition;
559
- if (isVideoType) {
560
- currentPosition = mVideoView.getCurrentPosition();
561
- } else {
562
- currentPosition = audioPlayer.getCurrentPosition();
563
- }
554
+ int currentPosition = mediaPlayer.getCurrentPosition();
564
555
 
565
556
  int duration = mDuration;
566
557
 
@@ -568,6 +559,8 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
568
559
  currentPosition = duration;
569
560
  } else if (currentPosition >= endTime - 100) {
570
561
  currentPosition = (int) endTime;
562
+ } else if (currentPosition <= startTime + 100) {
563
+ currentPosition = (int) startTime;
571
564
  }
572
565
 
573
566
  String currentTime = formatTime(currentPosition);
@@ -583,9 +576,13 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
583
576
  // Update progressIndicator position
584
577
  float indicatorPosition = (float) currentPosition / duration * (trimmerContainerBg.getWidth() - progressIndicator.getWidth()) + leadingHandle.getWidth();
585
578
 
586
- float rightBoundary = trimmerContainer.getX() + trimmerContainer.getWidth() - progressIndicator.getWidth();
587
-
588
- progressIndicator.setX(Math.min(rightBoundary, indicatorPosition));
579
+ if (currentSelectedhandle == leadingHandle) {
580
+ float leftBoundary = trimmerContainer.getX();
581
+ progressIndicator.setX(Math.max(leftBoundary, indicatorPosition));
582
+ } else {
583
+ float rightBoundary = trimmerContainer.getX() + trimmerContainer.getWidth() - progressIndicator.getWidth();
584
+ progressIndicator.setX(Math.min(rightBoundary, indicatorPosition));
585
+ }
589
586
  }
590
587
  }
591
588
 
@@ -655,6 +652,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
655
652
  handle.setOnTouchListener((view, event) -> {
656
653
  switch (event.getAction()) {
657
654
  case MotionEvent.ACTION_DOWN:
655
+ currentSelectedhandle = handle;
658
656
  didClampWhilePanning = false;
659
657
  onMediaPause();
660
658
  fadeOutProgressIndicator();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-video-trim",
3
- "version": "2.2.3",
3
+ "version": "2.2.5",
4
4
  "description": "Video trimmer for your React Native app",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",