100100import java .util .concurrent .Executors ;
101101import java .util .concurrent .Callable ;
102102import java .util .concurrent .Future ;
103+ import java .util .concurrent .TimeUnit ;
103104import java .lang .Integer ;
104105
105106@ SuppressLint ("ViewConstructor" )
@@ -943,8 +944,24 @@ private void videoLoaded() {
943944 int width = videoFormat != null ? videoFormat .width : 0 ;
944945 int height = videoFormat != null ? videoFormat .height : 0 ;
945946 String trackId = videoFormat != null ? videoFormat .id : "-1" ;
946- eventEmitter .load (player .getDuration (), player .getCurrentPosition (), width , height ,
947- getAudioTrackInfo (), getTextTrackInfo (), getVideoTrackInfo (), trackId );
947+
948+ // Properties that must be accessed on the main thread
949+ long duration = player .getDuration ();
950+ long currentPosition = player .getCurrentPosition ();
951+ WritableArray audioTrackInfo = getAudioTrackInfo ();
952+ WritableArray textTrackInfo = getTextTrackInfo ();
953+ Timeline timelineRef = player .getCurrentTimeline ();
954+ int trackRendererIndex = getTrackRendererIndex (C .TRACK_TYPE_VIDEO );
955+
956+ ExecutorService es = Executors .newSingleThreadExecutor ();
957+ es .execute (new Runnable () {
958+ @ Override
959+ public void run () {
960+ // To prevent ANRs caused by getVideoTrackInfo we run this on a different thread and notify the player only when we're done
961+ eventEmitter .load (duration , currentPosition , width , height ,
962+ audioTrackInfo , textTrackInfo , getVideoTrackInfo (timelineRef , trackRendererIndex ), trackId );
963+ }
964+ });
948965 }
949966 }
950967
@@ -971,9 +988,9 @@ private WritableArray getAudioTrackInfo() {
971988 }
972989 return audioTracks ;
973990 }
974- private WritableArray getVideoTrackInfo () {
991+ private WritableArray getVideoTrackInfo (Timeline timelineRef , int trackRendererIndex ) {
975992
976- WritableArray contentVideoTracks = this .getVideoTrackInfoFromManifest ();
993+ WritableArray contentVideoTracks = this .getVideoTrackInfoFromManifest (timelineRef );
977994 if (contentVideoTracks != null ) {
978995 isUsingContentResolution = true ;
979996 return contentVideoTracks ;
@@ -982,12 +999,12 @@ private WritableArray getVideoTrackInfo() {
982999 WritableArray videoTracks = Arguments .createArray ();
9831000
9841001 MappingTrackSelector .MappedTrackInfo info = trackSelector .getCurrentMappedTrackInfo ();
985- int index = getTrackRendererIndex ( C . TRACK_TYPE_VIDEO );
986- if (info == null || index == C .INDEX_UNSET ) {
1002+
1003+ if (info == null || trackRendererIndex == C .INDEX_UNSET ) {
9871004 return videoTracks ;
9881005 }
9891006
990- TrackGroupArray groups = info .getTrackGroups (index );
1007+ TrackGroupArray groups = info .getTrackGroups (trackRendererIndex );
9911008 for (int i = 0 ; i < groups .length ; ++i ) {
9921009 TrackGroup group = groups .get (i );
9931010
@@ -998,8 +1015,7 @@ private WritableArray getVideoTrackInfo() {
9981015 videoTrack .putInt ("height" ,format .height == Format .NO_VALUE ? 0 : format .height );
9991016 videoTrack .putInt ("bitrate" , format .bitrate == Format .NO_VALUE ? 0 : format .bitrate );
10001017 videoTrack .putString ("codecs" , format .codecs != null ? format .codecs : "" );
1001- videoTrack .putString ("trackId" ,
1002- format .id == null ? String .valueOf (trackIndex ) : format .id );
1018+ videoTrack .putString ("trackId" , format .id == null ? String .valueOf (trackIndex ) : format .id );
10031019 if (isFormatSupported (format )) {
10041020 videoTracks .pushMap (videoTrack );
10051021 }
@@ -1009,11 +1025,14 @@ private WritableArray getVideoTrackInfo() {
10091025 return videoTracks ;
10101026 }
10111027
1012- private WritableArray getVideoTrackInfoFromManifest () {
1028+ private WritableArray getVideoTrackInfoFromManifest (Timeline timeline ) {
1029+ return this .getVideoTrackInfoFromManifest (timeline , 0 );
1030+ }
1031+
1032+ private WritableArray getVideoTrackInfoFromManifest (Timeline timelineRef , int retryCount ) {
10131033 ExecutorService es = Executors .newSingleThreadExecutor ();
10141034 final DataSource dataSource = this .mediaDataSourceFactory .createDataSource ();
10151035 final Uri sourceUri = this .srcUri ;
1016- final Timeline timelineRef = this .player .getCurrentTimeline ();
10171036 final long startTime = this .contentStartTime * 1000 - 100 ; // s -> ms with 100ms offset
10181037
10191038 Future <WritableArray > result = es .submit (new Callable <WritableArray >() {
@@ -1064,7 +1083,10 @@ public WritableArray call() throws Exception {
10641083 });
10651084
10661085 try {
1067- WritableArray results = result .get ();
1086+ WritableArray results = result .get (3000 , TimeUnit .MILLISECONDS );
1087+ if (results == null && retryCount < 1 ) {
1088+ return this .getVideoTrackInfoFromManifest (timelineRef , ++retryCount );
1089+ }
10681090 es .shutdown ();
10691091 return results ;
10701092 } catch (Exception e ) {}
0 commit comments