react-native-video-trim 2.2.4 → 2.2.6
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,9 +56,11 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
56
56
|
|
|
57
57
|
private ReactApplicationContext mContext;
|
|
58
58
|
private VideoView mVideoView;
|
|
59
|
-
|
|
59
|
+
|
|
60
|
+
// mediaPlayer is used for both video/audio
|
|
61
|
+
// the reason we use mediaPlayer for Video: https://stackoverflow.com/a/73361868/7569705
|
|
60
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
|
|
61
|
-
private MediaPlayer
|
|
63
|
+
private MediaPlayer mediaPlayer;
|
|
62
64
|
private ImageView mPlayView;
|
|
63
65
|
private LinearLayout mThumbnailContainer;
|
|
64
66
|
private Uri mSourceUri;
|
|
@@ -99,7 +101,6 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
99
101
|
private TextView cancelBtn;
|
|
100
102
|
private FrameLayout audioBannerView;
|
|
101
103
|
private boolean isVideoType = true;
|
|
102
|
-
private MediaPlayer audioPlayer;
|
|
103
104
|
private ImageView failToLoadBtn;
|
|
104
105
|
|
|
105
106
|
private String mOutputExt = "mp4";
|
|
@@ -175,12 +176,11 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
175
176
|
|
|
176
177
|
mVideoView.setOnPreparedListener(mp -> {
|
|
177
178
|
mp.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
|
|
179
|
+
mediaPlayer = mp;
|
|
178
180
|
mediaPrepared();
|
|
179
|
-
videoPlayer = mp;
|
|
180
181
|
});
|
|
181
182
|
|
|
182
183
|
mVideoView.setOnErrorListener(this::onFailToLoadMedia);
|
|
183
|
-
|
|
184
184
|
mVideoView.setOnCompletionListener(mp -> mediaCompleted());
|
|
185
185
|
} else {
|
|
186
186
|
mVideoView.setVisibility(View.GONE);
|
|
@@ -188,16 +188,16 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
188
188
|
audioBannerView.setVisibility(View.VISIBLE);
|
|
189
189
|
audioBannerView.animate().alpha(1f).setDuration(500).start();
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
mediaPlayer = new MediaPlayer();
|
|
192
192
|
try {
|
|
193
|
-
|
|
194
|
-
|
|
193
|
+
mediaPlayer.setDataSource(videoURI.toString());
|
|
194
|
+
mediaPlayer.setOnPreparedListener(mp -> {
|
|
195
195
|
mediaPrepared();
|
|
196
196
|
});
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
mediaPlayer.setOnCompletionListener(mp -> mediaCompleted());
|
|
198
|
+
mediaPlayer.setOnErrorListener(this::onFailToLoadMedia);
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
mediaPlayer.prepareAsync(); // use prepareAsync to avoid blocking the main thread
|
|
201
201
|
} catch (IOException e) {
|
|
202
202
|
e.printStackTrace();
|
|
203
203
|
mediaFailed();
|
|
@@ -244,7 +244,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
private void mediaPrepared() {
|
|
247
|
-
mDuration =
|
|
247
|
+
mDuration = mediaPlayer.getDuration();
|
|
248
248
|
mMaxDuration = Math.min(mMaxDuration, mDuration);
|
|
249
249
|
|
|
250
250
|
if (isVideoType) {
|
|
@@ -327,52 +327,29 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
private void mediaCompleted() {
|
|
330
|
-
|
|
331
|
-
|
|
330
|
+
onMediaPause();
|
|
331
|
+
|
|
332
|
+
// when mediaCompleted is called, the endTime may not be exactly at the end of the video (can be slightly before), therefore we should seek to exact position on ended
|
|
333
|
+
seekTo(endTime, true);
|
|
332
334
|
}
|
|
333
335
|
|
|
334
336
|
private void playOrPause() {
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
onMediaPause();
|
|
338
|
-
} else {
|
|
339
|
-
// if current video time >= end time, seek to start time
|
|
340
|
-
if (mVideoView.getCurrentPosition() >= endTime) {
|
|
341
|
-
seekTo(startTime, true);
|
|
342
|
-
}
|
|
343
|
-
mVideoView.start();
|
|
344
|
-
startTimingRunnable();
|
|
345
|
-
}
|
|
346
|
-
setPlayPauseViewIcon(mVideoView.isPlaying());
|
|
347
|
-
|
|
337
|
+
if (mediaPlayer.isPlaying()) {
|
|
338
|
+
onMediaPause();
|
|
348
339
|
} else {
|
|
349
|
-
if (
|
|
350
|
-
|
|
351
|
-
} else {
|
|
352
|
-
if (audioPlayer.getCurrentPosition() >= endTime) {
|
|
353
|
-
seekTo(startTime, true);
|
|
354
|
-
}
|
|
355
|
-
audioPlayer.start();
|
|
356
|
-
startTimingRunnable();
|
|
340
|
+
if (mediaPlayer.getCurrentPosition() >= endTime) {
|
|
341
|
+
seekTo(startTime, true);
|
|
357
342
|
}
|
|
358
|
-
|
|
343
|
+
mediaPlayer.start();
|
|
344
|
+
startTimingRunnable();
|
|
359
345
|
}
|
|
346
|
+
setPlayPauseViewIcon(mediaPlayer.isPlaying());
|
|
360
347
|
}
|
|
361
348
|
|
|
362
349
|
public void onMediaPause() {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
mVideoView.pause();
|
|
367
|
-
setPlayPauseViewIcon(false);
|
|
368
|
-
}
|
|
369
|
-
} else {
|
|
370
|
-
if (audioPlayer.isPlaying()) {
|
|
371
|
-
mTimingHandler.removeCallbacks(mTimingRunnable);
|
|
372
|
-
audioPlayer.pause();
|
|
373
|
-
setPlayPauseViewIcon(false);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
350
|
+
mTimingHandler.removeCallbacks(mTimingRunnable);
|
|
351
|
+
mediaPlayer.pause();
|
|
352
|
+
setPlayPauseViewIcon(false);
|
|
376
353
|
}
|
|
377
354
|
|
|
378
355
|
public void setOnTrimVideoListener(VideoTrimListener onTrimVideoListener) {
|
|
@@ -407,14 +384,10 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
407
384
|
}
|
|
408
385
|
|
|
409
386
|
private void seekTo(long msec, boolean needUpdateProgress) {
|
|
410
|
-
if (
|
|
411
|
-
|
|
412
|
-
videoPlayer.seekTo((int) msec, MediaPlayer.SEEK_CLOSEST);
|
|
413
|
-
} else {
|
|
414
|
-
mVideoView.seekTo((int) msec);
|
|
415
|
-
}
|
|
387
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
388
|
+
mediaPlayer.seekTo((int) msec, MediaPlayer.SEEK_CLOSEST);
|
|
416
389
|
} else {
|
|
417
|
-
|
|
390
|
+
mediaPlayer.seekTo((int) msec);
|
|
418
391
|
}
|
|
419
392
|
|
|
420
393
|
updateCurrentTime(needUpdateProgress);
|
|
@@ -447,9 +420,15 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
447
420
|
e.printStackTrace();
|
|
448
421
|
}
|
|
449
422
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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");
|
|
453
432
|
}
|
|
454
433
|
}
|
|
455
434
|
|
|
@@ -542,19 +521,13 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
542
521
|
mTimingRunnable = new Runnable() {
|
|
543
522
|
@Override
|
|
544
523
|
public void run() {
|
|
545
|
-
|
|
546
|
-
if (isVideoType) {
|
|
547
|
-
currentPosition = mVideoView.getCurrentPosition();
|
|
548
|
-
} else {
|
|
549
|
-
currentPosition = audioPlayer.getCurrentPosition();
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
if (currentPosition >= endTime) {
|
|
553
|
-
onMediaPause();
|
|
554
|
-
seekTo(endTime, true); // Ensure exact end time display
|
|
555
|
-
} else {
|
|
524
|
+
try {
|
|
556
525
|
updateCurrentTime(true);
|
|
557
526
|
mTimingHandler.postDelayed(this, TIMING_UPDATE_INTERVAL);
|
|
527
|
+
} catch (IllegalStateException e) {
|
|
528
|
+
e.printStackTrace();
|
|
529
|
+
mTimingHandler.removeCallbacks(mTimingRunnable);
|
|
530
|
+
// this is to catch the error thrown if we close editor while playing (mediaPlayer is released)
|
|
558
531
|
}
|
|
559
532
|
}
|
|
560
533
|
};
|
|
@@ -562,15 +535,7 @@ public class VideoTrimmerView extends FrameLayout implements IVideoTrimmerView {
|
|
|
562
535
|
}
|
|
563
536
|
|
|
564
537
|
private void updateCurrentTime(boolean needUpdateProgress) {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
int currentPosition;
|
|
568
|
-
if (isVideoType) {
|
|
569
|
-
currentPosition = mVideoView.getCurrentPosition();
|
|
570
|
-
} else {
|
|
571
|
-
currentPosition = audioPlayer.getCurrentPosition();
|
|
572
|
-
}
|
|
573
|
-
|
|
538
|
+
int currentPosition = mediaPlayer.getCurrentPosition();
|
|
574
539
|
int duration = mDuration;
|
|
575
540
|
|
|
576
541
|
if (currentPosition >= duration - 100) {
|