11package org .schabi .newpipe .player .mediasource ;
22
3- import androidx .annotation .NonNull ;
4-
53import com .google .android .exoplayer2 .MediaItem ;
4+ import com .google .android .exoplayer2 .Timeline ;
5+ import com .google .android .exoplayer2 .source .CompositeMediaSource ;
6+ import com .google .android .exoplayer2 .source .MediaPeriod ;
67import com .google .android .exoplayer2 .source .MediaSource ;
7- import com .google .android .exoplayer2 .source .WrappingMediaSource ;
8+ import com .google .android .exoplayer2 .upstream .Allocator ;
9+ import com .google .android .exoplayer2 .upstream .TransferListener ;
810
911import org .schabi .newpipe .player .mediaitem .MediaItemTag ;
1012import org .schabi .newpipe .player .playqueue .PlayQueueItem ;
1113
12- public class LoadedMediaSource extends WrappingMediaSource implements ManagedMediaSource {
14+ import androidx .annotation .NonNull ;
15+ import androidx .annotation .Nullable ;
16+
17+ public class LoadedMediaSource extends CompositeMediaSource <Integer > implements ManagedMediaSource {
18+ private final MediaSource source ;
1319 private final PlayQueueItem stream ;
1420 private final MediaItem mediaItem ;
1521 private final long expireTimestamp ;
1622
1723 /**
18- * Uses a {@link WrappingMediaSource } to wrap one child {@link MediaSource}
24+ * Uses a {@link CompositeMediaSource } to wrap one or more child {@link MediaSource}s
1925 * containing actual media. This wrapper {@link LoadedMediaSource} holds the expiration
2026 * timestamp as a {@link ManagedMediaSource} to allow explicit playlist management under
2127 * {@link ManagedMediaSourcePlaylist}.
@@ -30,7 +36,7 @@ public LoadedMediaSource(@NonNull final MediaSource source,
3036 @ NonNull final MediaItemTag tag ,
3137 @ NonNull final PlayQueueItem stream ,
3238 final long expireTimestamp ) {
33- super ( source ) ;
39+ this . source = source ;
3440 this .stream = stream ;
3541 this .expireTimestamp = expireTimestamp ;
3642
@@ -45,6 +51,51 @@ private boolean isExpired() {
4551 return System .currentTimeMillis () >= expireTimestamp ;
4652 }
4753
54+ /**
55+ * Delegates the preparation of child {@link MediaSource}s to the
56+ * {@link CompositeMediaSource} wrapper. Since all {@link LoadedMediaSource}s use only
57+ * a single child media, the child id of 0 is always used (sonar doesn't like null as id here).
58+ *
59+ * @param mediaTransferListener A data transfer listener that will be registered by the
60+ * {@link CompositeMediaSource} for child source preparation.
61+ */
62+ @ Override
63+ protected void prepareSourceInternal (@ Nullable final TransferListener mediaTransferListener ) {
64+ super .prepareSourceInternal (mediaTransferListener );
65+ prepareChildSource (0 , source );
66+ }
67+
68+ /**
69+ * When any child {@link MediaSource} is prepared, the refreshed {@link Timeline} can
70+ * be listened to here. But since {@link LoadedMediaSource} has only a single child source,
71+ * this method is called only once until {@link #releaseSourceInternal()} is called.
72+ * <br><br>
73+ * On refresh, the {@link CompositeMediaSource} delegate will be notified with the
74+ * new {@link Timeline}, otherwise {@link #createPeriod(MediaPeriodId, Allocator, long)}
75+ * will not be called and playback may be stalled.
76+ *
77+ * @param id The unique id used to prepare the child source.
78+ * @param mediaSource The child source whose source info has been refreshed.
79+ * @param timeline The new timeline of the child source.
80+ */
81+ @ Override
82+ protected void onChildSourceInfoRefreshed (final Integer id ,
83+ final MediaSource mediaSource ,
84+ final Timeline timeline ) {
85+ refreshSourceInfo (timeline );
86+ }
87+
88+ @ Override
89+ public MediaPeriod createPeriod (final MediaPeriodId id , final Allocator allocator ,
90+ final long startPositionUs ) {
91+ return source .createPeriod (id , allocator , startPositionUs );
92+ }
93+
94+ @ Override
95+ public void releasePeriod (final MediaPeriod mediaPeriod ) {
96+ source .releasePeriod (mediaPeriod );
97+ }
98+
4899 @ NonNull
49100 @ Override
50101 public MediaItem getMediaItem () {
0 commit comments