@picsa/capacitor-video-player 8.0.1 → 8.0.3
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.
|
@@ -301,7 +301,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
301
301
|
new PlayerView.ControllerVisibilityListener() {
|
|
302
302
|
@Override
|
|
303
303
|
public void onVisibilityChanged(int visibility) {
|
|
304
|
-
linearLayout
|
|
304
|
+
if (linearLayout != null) {
|
|
305
|
+
linearLayout.setVisibility(visibility);
|
|
306
|
+
}
|
|
305
307
|
}
|
|
306
308
|
}
|
|
307
309
|
);
|
|
@@ -310,6 +312,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
310
312
|
new Player.Listener() {
|
|
311
313
|
@Override
|
|
312
314
|
public void onPlayerStateChanged(boolean playWhenReady, int state) {
|
|
315
|
+
if (isFragmentDestroyed || player == null || styledPlayerView == null) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
313
318
|
String stateString;
|
|
314
319
|
Map<String, Object> info = new HashMap<String, Object>() {
|
|
315
320
|
{
|
|
@@ -546,7 +551,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
546
551
|
|
|
547
552
|
@Override
|
|
548
553
|
protected void onPostExecute(Bitmap result) {
|
|
549
|
-
cast_image
|
|
554
|
+
if (cast_image != null) {
|
|
555
|
+
cast_image.setImageBitmap(result);
|
|
556
|
+
}
|
|
550
557
|
}
|
|
551
558
|
}
|
|
552
559
|
|
|
@@ -554,14 +561,16 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
554
561
|
* Show controller
|
|
555
562
|
*/
|
|
556
563
|
public void showController() {
|
|
557
|
-
styledPlayerView
|
|
564
|
+
if (styledPlayerView != null) {
|
|
565
|
+
styledPlayerView.showController();
|
|
566
|
+
}
|
|
558
567
|
}
|
|
559
568
|
|
|
560
569
|
/**
|
|
561
570
|
* isControllerIsFullyVisible
|
|
562
571
|
*/
|
|
563
572
|
public boolean isControllerIsFullyVisible() {
|
|
564
|
-
return styledPlayerView.isControllerFullyVisible();
|
|
573
|
+
return styledPlayerView != null && styledPlayerView.isControllerFullyVisible();
|
|
565
574
|
}
|
|
566
575
|
|
|
567
576
|
/**
|
|
@@ -587,6 +596,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
587
596
|
if (
|
|
588
597
|
!isInPictureInPictureMode &&
|
|
589
598
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
|
|
599
|
+
packageManager != null &&
|
|
590
600
|
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) &&
|
|
591
601
|
Boolean.TRUE.equals(isPIPModeeEnabled) &&
|
|
592
602
|
Boolean.TRUE.equals(pipEnabled) &&
|
|
@@ -599,18 +609,21 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
599
609
|
}
|
|
600
610
|
|
|
601
611
|
private void resizePressed() {
|
|
612
|
+
if (styledPlayerView == null) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
602
615
|
if (resizeStatus == AspectRatioFrameLayout.RESIZE_MODE_FIT) {
|
|
603
616
|
styledPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
|
|
604
617
|
resizeStatus = AspectRatioFrameLayout.RESIZE_MODE_FILL;
|
|
605
|
-
resizeBtn.setImageResource(R.drawable.ic_zoom);
|
|
618
|
+
if (resizeBtn != null) resizeBtn.setImageResource(R.drawable.ic_zoom);
|
|
606
619
|
} else if (resizeStatus == AspectRatioFrameLayout.RESIZE_MODE_FILL) {
|
|
607
620
|
styledPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
|
|
608
621
|
resizeStatus = AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
|
|
609
|
-
resizeBtn.setImageResource(R.drawable.ic_fit);
|
|
622
|
+
if (resizeBtn != null) resizeBtn.setImageResource(R.drawable.ic_fit);
|
|
610
623
|
} else {
|
|
611
624
|
styledPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
|
|
612
625
|
resizeStatus = AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
|
613
|
-
resizeBtn.setImageResource(R.drawable.ic_expand);
|
|
626
|
+
if (resizeBtn != null) resizeBtn.setImageResource(R.drawable.ic_expand);
|
|
614
627
|
}
|
|
615
628
|
}
|
|
616
629
|
|
|
@@ -645,7 +658,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
645
658
|
* Perform pictureInPictureMode Action
|
|
646
659
|
*/
|
|
647
660
|
private void pictureInPictureMode() {
|
|
648
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
|
|
661
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
|
|
649
662
|
// Store activity reference to avoid multiple getActivity() calls and check for null
|
|
650
663
|
// Fragment may be detached from activity during transitions or configuration changes
|
|
651
664
|
Activity activity = getActivity();
|
|
@@ -653,9 +666,13 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
653
666
|
Log.v(TAG, "pictureInPictureMode: activity is null");
|
|
654
667
|
return;
|
|
655
668
|
}
|
|
656
|
-
styledPlayerView
|
|
657
|
-
|
|
658
|
-
|
|
669
|
+
if (styledPlayerView != null) {
|
|
670
|
+
styledPlayerView.setUseController(false);
|
|
671
|
+
styledPlayerView.setControllerAutoShow(false);
|
|
672
|
+
}
|
|
673
|
+
if (linearLayout != null) {
|
|
674
|
+
linearLayout.setVisibility(View.INVISIBLE);
|
|
675
|
+
}
|
|
659
676
|
Log.v(TAG, "PIP break 1");
|
|
660
677
|
// require android O or higher
|
|
661
678
|
if (
|
|
@@ -663,9 +680,13 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
663
680
|
) {
|
|
664
681
|
pictureInPictureParams = new PictureInPictureParams.Builder();
|
|
665
682
|
// setup aspect ratio of the PIP window; fall back to 16:9 for audio-only or not-yet-decoded video
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
683
|
+
if (player != null) {
|
|
684
|
+
VideoSize videoSize = player.getVideoSize();
|
|
685
|
+
if (videoSize != VideoSize.UNKNOWN) {
|
|
686
|
+
pictureInPictureParams.setAspectRatio(new Rational(videoSize.width, videoSize.height));
|
|
687
|
+
} else {
|
|
688
|
+
pictureInPictureParams.setAspectRatio(new Rational(16, 9));
|
|
689
|
+
}
|
|
669
690
|
} else {
|
|
670
691
|
pictureInPictureParams.setAspectRatio(new Rational(16, 9));
|
|
671
692
|
}
|
|
@@ -726,12 +747,10 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
726
747
|
if (castContext != null && Boolean.TRUE.equals(chromecast) && castPlayer != null && castPlayer.isCastSessionAvailable()) return;
|
|
727
748
|
|
|
728
749
|
initializePlayer();
|
|
729
|
-
if (player.getCurrentPosition() != 0) {
|
|
750
|
+
if (player != null && player.getCurrentPosition() != 0) {
|
|
730
751
|
firstReadyToPlay = false;
|
|
731
752
|
play();
|
|
732
753
|
}
|
|
733
|
-
} else {
|
|
734
|
-
getActivity().finishAndRemoveTask();
|
|
735
754
|
}
|
|
736
755
|
}
|
|
737
756
|
}
|
|
@@ -743,11 +762,16 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
743
762
|
public void onStop() {
|
|
744
763
|
super.onStop();
|
|
745
764
|
boolean isAppBackground = false;
|
|
746
|
-
if (Boolean.TRUE.equals(bkModeEnabled)) isAppBackground = isApplicationSentToBackground(context);
|
|
765
|
+
if (context != null && Boolean.TRUE.equals(bkModeEnabled)) isAppBackground = isApplicationSentToBackground(context);
|
|
747
766
|
if (isInPictureInPictureMode) {
|
|
748
|
-
linearLayout
|
|
767
|
+
if (linearLayout != null) {
|
|
768
|
+
linearLayout.setVisibility(View.VISIBLE);
|
|
769
|
+
}
|
|
749
770
|
playerExit();
|
|
750
|
-
getActivity()
|
|
771
|
+
Activity activity = getActivity();
|
|
772
|
+
if (activity != null) {
|
|
773
|
+
activity.finishAndRemoveTask();
|
|
774
|
+
}
|
|
751
775
|
}
|
|
752
776
|
}
|
|
753
777
|
|
|
@@ -756,12 +780,12 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
756
780
|
*/
|
|
757
781
|
@Override
|
|
758
782
|
public void onDestroy() {
|
|
759
|
-
isFragmentDestroyed
|
|
760
|
-
|
|
761
|
-
// Release player before calling super to ensure proper cleanup order
|
|
783
|
+
// Release player before setting isFragmentDestroyed and calling super to ensure proper cleanup order
|
|
762
784
|
releasePlayer();
|
|
785
|
+
isFragmentDestroyed = true;
|
|
763
786
|
|
|
764
|
-
// Clean up
|
|
787
|
+
// Clean up handlers
|
|
788
|
+
handler.removeCallbacks(mRunnable);
|
|
765
789
|
if (mainHandler != null) {
|
|
766
790
|
mainHandler.removeCallbacksAndMessages(null);
|
|
767
791
|
mainHandler = null;
|
|
@@ -781,6 +805,18 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
781
805
|
super.onDetach();
|
|
782
806
|
}
|
|
783
807
|
|
|
808
|
+
/**
|
|
809
|
+
* Perform onDestroyView Action
|
|
810
|
+
*/
|
|
811
|
+
@Override
|
|
812
|
+
public void onDestroyView() {
|
|
813
|
+
if (styledPlayerView != null) {
|
|
814
|
+
styledPlayerView.setPlayer(null);
|
|
815
|
+
styledPlayerView = null;
|
|
816
|
+
}
|
|
817
|
+
super.onDestroyView();
|
|
818
|
+
}
|
|
819
|
+
|
|
784
820
|
/**
|
|
785
821
|
* Perform onPause Action
|
|
786
822
|
*/
|
|
@@ -791,7 +827,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
791
827
|
castContext.removeCastStateListener(castStateListener);
|
|
792
828
|
}
|
|
793
829
|
boolean isAppBackground = false;
|
|
794
|
-
if (Boolean.TRUE.equals(bkModeEnabled)) isAppBackground = isApplicationSentToBackground(context);
|
|
830
|
+
if (context != null && Boolean.TRUE.equals(bkModeEnabled)) isAppBackground = isApplicationSentToBackground(context);
|
|
795
831
|
|
|
796
832
|
if (!isInPictureInPictureMode) {
|
|
797
833
|
if (Util.SDK_INT < 24) {
|
|
@@ -807,7 +843,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
807
843
|
}
|
|
808
844
|
}
|
|
809
845
|
} else {
|
|
810
|
-
if (linearLayout.getVisibility() == View.VISIBLE) {
|
|
846
|
+
if (linearLayout != null && linearLayout.getVisibility() == View.VISIBLE) {
|
|
811
847
|
linearLayout.setVisibility(View.INVISIBLE);
|
|
812
848
|
}
|
|
813
849
|
if ((isInPictureInPictureMode || isAppBackground) && player != null) play();
|
|
@@ -843,6 +879,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
843
879
|
}
|
|
844
880
|
|
|
845
881
|
private void releasePlayerInternal() {
|
|
882
|
+
if (styledPlayerView != null) {
|
|
883
|
+
styledPlayerView.setPlayer(null);
|
|
884
|
+
}
|
|
846
885
|
if (player != null && !isFragmentDestroyed) {
|
|
847
886
|
try {
|
|
848
887
|
playWhenReady = player.getPlayWhenReady();
|
|
@@ -892,6 +931,12 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
892
931
|
public void onResume() {
|
|
893
932
|
super.onResume();
|
|
894
933
|
//if (chromecast && castContext != null) castContext.addCastStateListener(castStateListener);
|
|
934
|
+
// Skip resume handling when the view was never inflated (orphaned fragment
|
|
935
|
+
// recreation after process death returns an empty View in onCreateView, so
|
|
936
|
+
// styledPlayerView stays null while async removal is still pending).
|
|
937
|
+
if (styledPlayerView == null) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
895
940
|
if (!isInPictureInPictureMode) {
|
|
896
941
|
hideSystemUi();
|
|
897
942
|
if ((Util.SDK_INT < 24 || player == null)) {
|
|
@@ -934,15 +979,26 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
934
979
|
* Leave the fullsreen mode and reset the status bar to visible
|
|
935
980
|
*/
|
|
936
981
|
private void showSystemUI() {
|
|
937
|
-
getActivity()
|
|
938
|
-
|
|
939
|
-
|
|
982
|
+
Activity activity = getActivity();
|
|
983
|
+
if (activity != null && activity.getWindow() != null) {
|
|
984
|
+
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
985
|
+
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
986
|
+
View decorView = activity.getWindow().getDecorView();
|
|
987
|
+
if (decorView != null) {
|
|
988
|
+
decorView.setSystemUiVisibility(View.VISIBLE);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
940
991
|
}
|
|
941
992
|
|
|
942
993
|
/**
|
|
943
994
|
* Initialize the player
|
|
944
995
|
*/
|
|
945
996
|
private void initializePlayer() {
|
|
997
|
+
// Guard against orphaned fragment recreations where onCreateView returned
|
|
998
|
+
// an empty View without inflating the layout (styledPlayerView is null).
|
|
999
|
+
if (styledPlayerView == null) {
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
946
1002
|
if (player == null) {
|
|
947
1003
|
ExoTrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory();
|
|
948
1004
|
trackSelector = new DefaultTrackSelector(context, videoTrackSelectionFactory);
|
|
@@ -1004,15 +1060,18 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1004
1060
|
}
|
|
1005
1061
|
|
|
1006
1062
|
private void setSubtitle(boolean transparent) {
|
|
1063
|
+
if (styledPlayerView == null || styledPlayerView.getSubtitleView() == null) {
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1007
1066
|
int foreground;
|
|
1008
1067
|
int background;
|
|
1009
1068
|
if (!transparent) {
|
|
1010
1069
|
foreground = Color.WHITE;
|
|
1011
1070
|
background = Color.BLACK;
|
|
1012
|
-
if (stForeColor.length() > 4 && stForeColor.substring(0, 4).equals("rgba")) {
|
|
1071
|
+
if (stForeColor != null && stForeColor.length() > 4 && stForeColor.substring(0, 4).equals("rgba")) {
|
|
1013
1072
|
foreground = getColorFromRGBA(stForeColor);
|
|
1014
1073
|
}
|
|
1015
|
-
if (stBackColor.length() > 4 && stBackColor.substring(0, 4).equals("rgba")) {
|
|
1074
|
+
if (stBackColor != null && stBackColor.length() > 4 && stBackColor.substring(0, 4).equals("rgba")) {
|
|
1016
1075
|
background = getColorFromRGBA(stBackColor);
|
|
1017
1076
|
}
|
|
1018
1077
|
} else {
|
|
@@ -1024,7 +1083,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1024
1083
|
.setStyle(
|
|
1025
1084
|
new CaptionStyleCompat(foreground, background, Color.TRANSPARENT, CaptionStyleCompat.EDGE_TYPE_NONE, Color.WHITE, null)
|
|
1026
1085
|
);
|
|
1027
|
-
styledPlayerView.getSubtitleView().setFixedTextSize(TypedValue.COMPLEX_UNIT_DIP, stFontSize);
|
|
1086
|
+
styledPlayerView.getSubtitleView().setFixedTextSize(TypedValue.COMPLEX_UNIT_DIP, stFontSize != null ? stFontSize : 16);
|
|
1028
1087
|
styledPlayerView.setShowSubtitleButton(true);
|
|
1029
1088
|
}
|
|
1030
1089
|
|
|
@@ -1187,7 +1246,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1187
1246
|
* Fast Forward TV
|
|
1188
1247
|
*/
|
|
1189
1248
|
private void fastForward(long position, int times) {
|
|
1190
|
-
if (position < mDuration - videoStep) {
|
|
1249
|
+
if (player != null && position < mDuration - videoStep) {
|
|
1191
1250
|
if (player.isPlaying()) {
|
|
1192
1251
|
player.setPlayWhenReady(false);
|
|
1193
1252
|
}
|
|
@@ -1200,7 +1259,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1200
1259
|
* Rewind TV
|
|
1201
1260
|
*/
|
|
1202
1261
|
private void rewind(long position, int times) {
|
|
1203
|
-
if (position > videoStep) {
|
|
1262
|
+
if (player != null && position > videoStep) {
|
|
1204
1263
|
if (player.isPlaying()) {
|
|
1205
1264
|
player.setPlayWhenReady(false);
|
|
1206
1265
|
}
|
|
@@ -1213,7 +1272,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1213
1272
|
* Play Pause TV
|
|
1214
1273
|
*/
|
|
1215
1274
|
private void play_pause() {
|
|
1216
|
-
|
|
1275
|
+
if (player != null) {
|
|
1276
|
+
player.setPlayWhenReady(!player.isPlaying());
|
|
1277
|
+
}
|
|
1217
1278
|
}
|
|
1218
1279
|
|
|
1219
1280
|
/**
|
|
@@ -1221,7 +1282,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1221
1282
|
* @return boolean
|
|
1222
1283
|
*/
|
|
1223
1284
|
public boolean isPlaying() {
|
|
1224
|
-
return player.isPlaying();
|
|
1285
|
+
return player != null && player.isPlaying();
|
|
1225
1286
|
}
|
|
1226
1287
|
|
|
1227
1288
|
/**
|
|
@@ -1301,6 +1362,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1301
1362
|
* @return int in seconds
|
|
1302
1363
|
*/
|
|
1303
1364
|
public int getDuration() {
|
|
1365
|
+
if (player == null) {
|
|
1366
|
+
return 0;
|
|
1367
|
+
}
|
|
1304
1368
|
return player.getDuration() == UNKNOWN_TIME ? 0 : (int) (player.getDuration() / 1000);
|
|
1305
1369
|
}
|
|
1306
1370
|
|
|
@@ -1327,8 +1391,12 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1327
1391
|
|
|
1328
1392
|
try {
|
|
1329
1393
|
if (isInPictureInPictureMode) {
|
|
1330
|
-
styledPlayerView
|
|
1331
|
-
|
|
1394
|
+
if (styledPlayerView != null) {
|
|
1395
|
+
styledPlayerView.setUseController(false);
|
|
1396
|
+
}
|
|
1397
|
+
if (linearLayout != null) {
|
|
1398
|
+
linearLayout.setVisibility(View.INVISIBLE);
|
|
1399
|
+
}
|
|
1332
1400
|
}
|
|
1333
1401
|
long seekPosition = player.getCurrentPosition() == UNKNOWN_TIME
|
|
1334
1402
|
? 0
|
|
@@ -1344,7 +1412,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1344
1412
|
* @return float
|
|
1345
1413
|
*/
|
|
1346
1414
|
public float getVolume() {
|
|
1347
|
-
return player.getVolume();
|
|
1415
|
+
return player != null ? player.getVolume() : curVolume;
|
|
1348
1416
|
}
|
|
1349
1417
|
|
|
1350
1418
|
/**
|
|
@@ -1353,7 +1421,10 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1353
1421
|
*/
|
|
1354
1422
|
public void setVolume(float _volume) {
|
|
1355
1423
|
float volume = Math.min(Math.max(0, _volume), 1L);
|
|
1356
|
-
|
|
1424
|
+
curVolume = volume;
|
|
1425
|
+
if (player != null) {
|
|
1426
|
+
player.setVolume(volume);
|
|
1427
|
+
}
|
|
1357
1428
|
}
|
|
1358
1429
|
|
|
1359
1430
|
/**
|
|
@@ -1370,8 +1441,10 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1370
1441
|
*/
|
|
1371
1442
|
public void setRate(float _rate) {
|
|
1372
1443
|
videoRate = _rate;
|
|
1373
|
-
|
|
1374
|
-
|
|
1444
|
+
if (player != null) {
|
|
1445
|
+
PlaybackParameters param = new PlaybackParameters(videoRate != null ? videoRate : 1.0f);
|
|
1446
|
+
player.setPlaybackParameters(param);
|
|
1447
|
+
}
|
|
1375
1448
|
}
|
|
1376
1449
|
|
|
1377
1450
|
/**
|
|
@@ -1380,11 +1453,13 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1380
1453
|
*/
|
|
1381
1454
|
public void setMuted(boolean _isMuted) {
|
|
1382
1455
|
isMuted = _isMuted;
|
|
1383
|
-
if (
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1456
|
+
if (player != null) {
|
|
1457
|
+
if (isMuted) {
|
|
1458
|
+
curVolume = player.getVolume();
|
|
1459
|
+
player.setVolume(0L);
|
|
1460
|
+
} else {
|
|
1461
|
+
player.setVolume(curVolume);
|
|
1462
|
+
}
|
|
1388
1463
|
}
|
|
1389
1464
|
}
|
|
1390
1465
|
|
|
@@ -1401,7 +1476,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1401
1476
|
* @param button
|
|
1402
1477
|
*/
|
|
1403
1478
|
private void mediaRouteButtonColorWhite(MediaRouteButton button) {
|
|
1404
|
-
if (button == null) return;
|
|
1479
|
+
if (button == null || getContext() == null) return;
|
|
1405
1480
|
Context castContext = new ContextThemeWrapper(getContext(), androidx.mediarouter.R.style.Theme_MediaRouter);
|
|
1406
1481
|
|
|
1407
1482
|
TypedArray a = castContext.obtainStyledAttributes(
|
|
@@ -1456,7 +1531,6 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1456
1531
|
*/
|
|
1457
1532
|
private void resetVariables() {
|
|
1458
1533
|
vType = null;
|
|
1459
|
-
styledPlayerView = null;
|
|
1460
1534
|
playWhenReady = true;
|
|
1461
1535
|
firstReadyToPlay = true;
|
|
1462
1536
|
isEnded = false;
|
|
@@ -1498,6 +1572,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1498
1572
|
task.addOnCompleteListener(new OnCompleteListener<CastContext>() {
|
|
1499
1573
|
@Override
|
|
1500
1574
|
public void onComplete(Task<CastContext> task) {
|
|
1575
|
+
if (isFragmentDestroyed || !isAdded() || context == null || mediaRouteButton == null) {
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1501
1578
|
if (task.isSuccessful()) {
|
|
1502
1579
|
castContext = task.getResult();
|
|
1503
1580
|
castPlayer = new CastPlayer(castContext);
|
|
@@ -1514,6 +1591,9 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1514
1591
|
|
|
1515
1592
|
castStateListener =
|
|
1516
1593
|
state -> {
|
|
1594
|
+
if (mediaRouteButton == null) {
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1517
1597
|
if (state == CastState.NO_DEVICES_AVAILABLE) {
|
|
1518
1598
|
mediaRouteButton.setVisibility(View.GONE);
|
|
1519
1599
|
} else {
|
|
@@ -1551,35 +1631,53 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1551
1631
|
@Override
|
|
1552
1632
|
public void onCastSessionAvailable() {
|
|
1553
1633
|
isCastSession = true;
|
|
1554
|
-
final Long videoPosition = player.getCurrentPosition();
|
|
1555
|
-
if (Boolean.TRUE.equals(pipEnabled)) {
|
|
1634
|
+
final Long videoPosition = player != null ? player.getCurrentPosition() : 0L;
|
|
1635
|
+
if (pipBtn != null && Boolean.TRUE.equals(pipEnabled)) {
|
|
1556
1636
|
pipBtn.setVisibility(View.GONE);
|
|
1557
1637
|
}
|
|
1558
|
-
resizeBtn
|
|
1559
|
-
|
|
1560
|
-
|
|
1638
|
+
if (resizeBtn != null) {
|
|
1639
|
+
resizeBtn.setVisibility(View.GONE);
|
|
1640
|
+
}
|
|
1641
|
+
if (player != null) {
|
|
1642
|
+
player.setPlayWhenReady(false);
|
|
1643
|
+
}
|
|
1644
|
+
if (cast_image != null) {
|
|
1645
|
+
cast_image.setVisibility(View.VISIBLE);
|
|
1646
|
+
}
|
|
1561
1647
|
castPlayer.setMediaItem(mediaItem, videoPosition);
|
|
1562
|
-
styledPlayerView
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1648
|
+
if (styledPlayerView != null) {
|
|
1649
|
+
styledPlayerView.setPlayer(castPlayer);
|
|
1650
|
+
styledPlayerView.setControllerShowTimeoutMs(0);
|
|
1651
|
+
styledPlayerView.setControllerHideOnTouch(false);
|
|
1652
|
+
//We perform a click because for some weird reason, the layout is black until the user clicks on it
|
|
1653
|
+
styledPlayerView.performClick();
|
|
1654
|
+
}
|
|
1567
1655
|
}
|
|
1568
1656
|
|
|
1569
1657
|
@Override
|
|
1570
1658
|
public void onCastSessionUnavailable() {
|
|
1571
1659
|
isCastSession = false;
|
|
1572
|
-
final Long videoPosition = castPlayer.getCurrentPosition();
|
|
1573
|
-
if (Boolean.TRUE.equals(pipEnabled)) {
|
|
1660
|
+
final Long videoPosition = castPlayer != null ? castPlayer.getCurrentPosition() : 0L;
|
|
1661
|
+
if (pipBtn != null && Boolean.TRUE.equals(pipEnabled)) {
|
|
1574
1662
|
pipBtn.setVisibility(View.VISIBLE);
|
|
1575
1663
|
}
|
|
1576
|
-
resizeBtn
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
styledPlayerView
|
|
1664
|
+
if (resizeBtn != null) {
|
|
1665
|
+
resizeBtn.setVisibility(View.VISIBLE);
|
|
1666
|
+
}
|
|
1667
|
+
if (cast_image != null) {
|
|
1668
|
+
cast_image.setVisibility(View.GONE);
|
|
1669
|
+
}
|
|
1670
|
+
if (styledPlayerView != null) {
|
|
1671
|
+
styledPlayerView.setPlayer(player);
|
|
1672
|
+
}
|
|
1673
|
+
if (player != null) {
|
|
1674
|
+
player.setPlayWhenReady(true);
|
|
1675
|
+
player.seekTo(videoPosition);
|
|
1676
|
+
}
|
|
1677
|
+
if (styledPlayerView != null) {
|
|
1678
|
+
styledPlayerView.setControllerShowTimeoutMs(3000);
|
|
1679
|
+
styledPlayerView.setControllerHideOnTouch(true);
|
|
1680
|
+
}
|
|
1583
1681
|
}
|
|
1584
1682
|
}
|
|
1585
1683
|
);
|
|
@@ -1591,7 +1689,7 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1591
1689
|
Map<String, Object> info = new HashMap<String, Object>() {
|
|
1592
1690
|
{
|
|
1593
1691
|
put("fromPlayerId", playerId);
|
|
1594
|
-
put("currentTime", String.valueOf(player.getCurrentPosition() / 1000));
|
|
1692
|
+
put("currentTime", String.valueOf(player != null ? player.getCurrentPosition() / 1000 : 0));
|
|
1595
1693
|
}
|
|
1596
1694
|
};
|
|
1597
1695
|
switch (state) {
|
|
@@ -1629,6 +1727,8 @@ public class FullscreenExoPlayerFragment extends Fragment {
|
|
|
1629
1727
|
}
|
|
1630
1728
|
|
|
1631
1729
|
private void adjustAspectRatio() {
|
|
1632
|
-
styledPlayerView
|
|
1730
|
+
if (styledPlayerView != null) {
|
|
1731
|
+
styledPlayerView.setResizeMode(resizeStatus);
|
|
1732
|
+
}
|
|
1633
1733
|
}
|
|
1634
1734
|
}
|
|
@@ -78,6 +78,9 @@ public class PickerVideoFragment extends Fragment {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
private void loadVideos() {
|
|
81
|
+
if (context == null) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
81
84
|
String[] projection = {
|
|
82
85
|
MediaStore.Video.Media._ID,
|
|
83
86
|
MediaStore.Video.Media.DISPLAY_NAME,
|
|
@@ -92,37 +95,46 @@ public class PickerVideoFragment extends Fragment {
|
|
|
92
95
|
collection = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
Cursor cursor =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
try (Cursor cursor = context.getContentResolver().query(collection, projection, null, null, sortOrder)) {
|
|
99
|
+
if (cursor != null) {
|
|
100
|
+
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
|
|
101
|
+
int titleColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
|
|
102
|
+
int durationColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION);
|
|
100
103
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
while (cursor.moveToNext()) {
|
|
105
|
+
long id = cursor.getLong(idColumn);
|
|
106
|
+
String title = cursor.getString(titleColumn);
|
|
107
|
+
int duration = cursor.getInt(durationColumn);
|
|
105
108
|
|
|
106
|
-
|
|
109
|
+
Uri data = ContentUris.withAppendedId(collection, id);
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
String duration_formatted;
|
|
112
|
+
int sec = (duration / 1000) % 60;
|
|
113
|
+
int min = (duration / (1000 * 60)) % 60;
|
|
114
|
+
int hrs = duration / (1000 * 60 * 60);
|
|
112
115
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
if (hrs == 0) {
|
|
117
|
+
duration_formatted = String.valueOf(min).concat(":".concat(String.format(Locale.UK, "%02d", sec)));
|
|
118
|
+
} else {
|
|
119
|
+
duration_formatted = String.valueOf(hrs).concat(
|
|
120
|
+
":".concat(String.format(Locale.UK, "%02d", min).concat(":".concat(String.format(Locale.UK, "%02d", sec))))
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
Log.v(TAG, "**** video " + id + " " + title + " " + duration_formatted + " ****");
|
|
124
|
+
videosList.add(new ModelVideo(id, data, title, duration_formatted));
|
|
122
125
|
}
|
|
123
|
-
Log.v(TAG, "**** video " + id + " " + title + " " + duration_formatted + " ****");
|
|
124
|
-
videosList.add(new ModelVideo(id, data, title, duration_formatted));
|
|
125
126
|
}
|
|
127
|
+
} catch (Exception e) {
|
|
128
|
+
Log.e(TAG, "Error loading videos from media store", e);
|
|
126
129
|
}
|
|
127
130
|
}
|
|
131
|
+
|
|
132
|
+
@Override
|
|
133
|
+
public void onDestroyView() {
|
|
134
|
+
recyclerView = null;
|
|
135
|
+
recyclerViewLayoutManager = null;
|
|
136
|
+
adapterVideoList = null;
|
|
137
|
+
view = null;
|
|
138
|
+
super.onDestroyView();
|
|
139
|
+
}
|
|
128
140
|
}
|