15
15
*/
16
16
package androidx .media3 .exoplayer .source ;
17
17
18
+ import static androidx .media3 .common .util .Assertions .checkArgument ;
18
19
import static java .lang .Math .min ;
19
20
20
21
import androidx .media3 .common .C ;
21
22
import androidx .media3 .common .util .UnstableApi ;
22
23
import androidx .media3 .exoplayer .LoadingInfo ;
24
+ import com .google .common .collect .ImmutableList ;
25
+ import java .util .Collections ;
26
+ import java .util .List ;
23
27
24
28
/** A {@link SequenceableLoader} that encapsulates multiple other {@link SequenceableLoader}s. */
25
29
@ UnstableApi
26
30
public final class CompositeSequenceableLoader implements SequenceableLoader {
27
31
28
- private final SequenceableLoader [] loaders ;
32
+ private final ImmutableList < SequenceableLoaderWithTrackTypes > loadersWithTrackTypes ;
29
33
34
+ /**
35
+ * @deprecated Use {@link CompositeSequenceableLoader#CompositeSequenceableLoader(List, List)}
36
+ * instead.
37
+ */
38
+ @ Deprecated
30
39
public CompositeSequenceableLoader (SequenceableLoader [] loaders ) {
31
- this .loaders = loaders ;
40
+ this (
41
+ ImmutableList .copyOf (loaders ),
42
+ Collections .nCopies (loaders .length , ImmutableList .of (C .TRACK_TYPE_UNKNOWN )));
43
+ }
44
+
45
+ public CompositeSequenceableLoader (
46
+ List <? extends SequenceableLoader > loaders ,
47
+ List <List <@ C .TrackType Integer >> loaderTrackTypes ) {
48
+ ImmutableList .Builder <SequenceableLoaderWithTrackTypes > loaderAndTrackTypes =
49
+ ImmutableList .builder ();
50
+ checkArgument (loaders .size () == loaderTrackTypes .size ());
51
+ for (int i = 0 ; i < loaders .size (); i ++) {
52
+ loaderAndTrackTypes .add (
53
+ new SequenceableLoaderWithTrackTypes (loaders .get (i ), loaderTrackTypes .get (i )));
54
+ }
55
+ this .loadersWithTrackTypes = loaderAndTrackTypes .build ();
32
56
}
33
57
34
58
@ Override
35
59
public long getBufferedPositionUs () {
36
60
long bufferedPositionUs = Long .MAX_VALUE ;
37
- for (SequenceableLoader loader : loaders ) {
61
+ boolean hasAudioVideoTracks = false ;
62
+ long bufferedPositionAudioVideoUs = Long .MAX_VALUE ;
63
+ for (int i = 0 ; i < loadersWithTrackTypes .size (); i ++) {
64
+ SequenceableLoaderWithTrackTypes loader = loadersWithTrackTypes .get (i );
38
65
long loaderBufferedPositionUs = loader .getBufferedPositionUs ();
66
+ if (loader .getTrackTypes ().contains (C .TRACK_TYPE_AUDIO )
67
+ || loader .getTrackTypes ().contains (C .TRACK_TYPE_VIDEO )) {
68
+ hasAudioVideoTracks = true ;
69
+ if (loaderBufferedPositionUs != C .TIME_END_OF_SOURCE ) {
70
+ bufferedPositionAudioVideoUs =
71
+ min (bufferedPositionAudioVideoUs , loaderBufferedPositionUs );
72
+ }
73
+ }
39
74
if (loaderBufferedPositionUs != C .TIME_END_OF_SOURCE ) {
40
75
bufferedPositionUs = min (bufferedPositionUs , loaderBufferedPositionUs );
41
76
}
42
77
}
43
- return bufferedPositionUs == Long .MAX_VALUE ? C .TIME_END_OF_SOURCE : bufferedPositionUs ;
78
+ if (hasAudioVideoTracks ) {
79
+ return bufferedPositionAudioVideoUs != Long .MAX_VALUE
80
+ ? bufferedPositionAudioVideoUs
81
+ : C .TIME_END_OF_SOURCE ;
82
+ } else {
83
+ return bufferedPositionUs != Long .MAX_VALUE ? bufferedPositionUs : C .TIME_END_OF_SOURCE ;
84
+ }
44
85
}
45
86
46
87
@ Override
47
88
public long getNextLoadPositionUs () {
48
89
long nextLoadPositionUs = Long .MAX_VALUE ;
49
- for (SequenceableLoader loader : loaders ) {
50
- long loaderNextLoadPositionUs = loader .getNextLoadPositionUs ();
90
+ for (int i = 0 ; i < loadersWithTrackTypes . size (); i ++ ) {
91
+ long loaderNextLoadPositionUs = loadersWithTrackTypes . get ( i ) .getNextLoadPositionUs ();
51
92
if (loaderNextLoadPositionUs != C .TIME_END_OF_SOURCE ) {
52
93
nextLoadPositionUs = min (nextLoadPositionUs , loaderNextLoadPositionUs );
53
94
}
@@ -57,8 +98,8 @@ public long getNextLoadPositionUs() {
57
98
58
99
@ Override
59
100
public void reevaluateBuffer (long positionUs ) {
60
- for (SequenceableLoader loader : loaders ) {
61
- loader .reevaluateBuffer (positionUs );
101
+ for (int i = 0 ; i < loadersWithTrackTypes . size (); i ++ ) {
102
+ loadersWithTrackTypes . get ( i ) .reevaluateBuffer (positionUs );
62
103
}
63
104
}
64
105
@@ -72,13 +113,13 @@ public boolean continueLoading(LoadingInfo loadingInfo) {
72
113
if (nextLoadPositionUs == C .TIME_END_OF_SOURCE ) {
73
114
break ;
74
115
}
75
- for (SequenceableLoader loader : loaders ) {
76
- long loaderNextLoadPositionUs = loader .getNextLoadPositionUs ();
116
+ for (int i = 0 ; i < loadersWithTrackTypes . size (); i ++ ) {
117
+ long loaderNextLoadPositionUs = loadersWithTrackTypes . get ( i ) .getNextLoadPositionUs ();
77
118
boolean isLoaderBehind =
78
119
loaderNextLoadPositionUs != C .TIME_END_OF_SOURCE
79
120
&& loaderNextLoadPositionUs <= loadingInfo .playbackPositionUs ;
80
121
if (loaderNextLoadPositionUs == nextLoadPositionUs || isLoaderBehind ) {
81
- madeProgressThisIteration |= loader .continueLoading (loadingInfo );
122
+ madeProgressThisIteration |= loadersWithTrackTypes . get ( i ) .continueLoading (loadingInfo );
82
123
}
83
124
}
84
125
madeProgress |= madeProgressThisIteration ;
@@ -88,11 +129,54 @@ public boolean continueLoading(LoadingInfo loadingInfo) {
88
129
89
130
@ Override
90
131
public boolean isLoading () {
91
- for (SequenceableLoader loader : loaders ) {
92
- if (loader .isLoading ()) {
132
+ for (int i = 0 ; i < loadersWithTrackTypes . size (); i ++ ) {
133
+ if (loadersWithTrackTypes . get ( i ) .isLoading ()) {
93
134
return true ;
94
135
}
95
136
}
96
137
return false ;
97
138
}
139
+
140
+ private static final class SequenceableLoaderWithTrackTypes implements SequenceableLoader {
141
+
142
+ private final SequenceableLoader loader ;
143
+ private final ImmutableList <@ C .TrackType Integer > trackTypes ;
144
+
145
+ public SequenceableLoaderWithTrackTypes (
146
+ SequenceableLoader loader , List <@ C .TrackType Integer > trackTypes ) {
147
+ this .loader = loader ;
148
+ this .trackTypes = ImmutableList .copyOf (trackTypes );
149
+ }
150
+
151
+ public ImmutableList <@ C .TrackType Integer > getTrackTypes () {
152
+ return trackTypes ;
153
+ }
154
+
155
+ // SequenceableLoader implementation
156
+
157
+ @ Override
158
+ public long getBufferedPositionUs () {
159
+ return loader .getBufferedPositionUs ();
160
+ }
161
+
162
+ @ Override
163
+ public long getNextLoadPositionUs () {
164
+ return loader .getNextLoadPositionUs ();
165
+ }
166
+
167
+ @ Override
168
+ public boolean continueLoading (LoadingInfo loadingInfo ) {
169
+ return loader .continueLoading (loadingInfo );
170
+ }
171
+
172
+ @ Override
173
+ public boolean isLoading () {
174
+ return loader .isLoading ();
175
+ }
176
+
177
+ @ Override
178
+ public void reevaluateBuffer (long positionUs ) {
179
+ loader .reevaluateBuffer (positionUs );
180
+ }
181
+ }
98
182
}
0 commit comments