Fix issue where ProgressiveMediaPeriod fails assertPrepared

In `PreloadMediaSource` we accesses the `MediaPeriod.getBufferedPositionUs()` when we receive `onContinueLoadingRequested()` from the period. For `ProgressiveMediaPeriod` which requires loading a portion of media file to get it prepared, there is a chance that it needs more than one round of `onContinueLoadingRequested()` -> `continueLoading()` to complete preparation, for example, when the  `setContinueLoadingIntervalBytes()` is small enough to not include the full information for preparation. Thus we should avoid `MediaPeriod.getBufferedPositionUs()` being called before period is prepared, as it will fail at `assertPrepared`.

Issue: androidx/media#2315

PiperOrigin-RevId: 746490375
(cherry picked from commit 344f249511ad67a42d8328e79102f02bbbec5201)
This commit is contained in:
tianyifeng 2025-04-11 09:32:59 -07:00 committed by tonihei
parent 24a8185f4d
commit d7234a6a4e
3 changed files with 41 additions and 224 deletions

View File

@ -1,131 +1,14 @@
# Release notes # Release notes
* ExoPlayer:
* Fix issue where `ProgressiveMediaPeriod` throws an
`IllegalStateException` as `PreloadMediaSource` attempts to call its
`getBufferedDurationUs()` before it is prepared
([#2315](https://github.com/androidx/media/issues/2315)).
* Cast extension: * Cast extension:
* Add support for playlist metadata * Add support for playlist metadata
([#2235](https://github.com/androidx/media/pull/2235)). ([#2235](https://github.com/androidx/media/pull/2235)).
### Unreleased changes
* Common Library:
* Add `PlaybackParameters.withPitch(float)` method for easily copying a
`PlaybackParameters` with a new `pitch` value
([#2257](https://github.com/androidx/media/issues/2257)).
* ExoPlayer:
* Fix sending `CmcdData` in manifest requests for DASH, HLS, and
SmoothStreaming ([#2253](https://github.com/androidx/media/pull/2253)).
<<<<<<< HEAD
=======
* Fix issue where media item transition fails due to recoverable renderer
error during initialization of the next media item
([#2229](https://github.com/androidx/media/issues/2229)).
* Add `ExoPlayer.setScrubbingModeEnabled(boolean)` method. This optimizes
the player for many frequent seeks (for example, from a user dragging a
scrubber bar around).
* `AdPlaybackState.withAdDurationsUs(long[][])` can be used after ad
groups have been removed. The user still needs to pass in an array of
durations for removed ad groups which can be empty or null
([#2267](https://github.com/androidx/media/issues/2267)).
>>>>>>> d133300627 (Make AdPlaybackState.withAdDurationsUs work with removed ad groups)
* Transformer:
* Track Selection:
* Extractors:
* MP3: Use duration and data size from unseekable Xing, VBRI and similar
variable bitrate metadata when falling back to constant bitrate seeking
due to `FLAG_ENABLE_CONSTANT_BITRATE_SEEKING(_ALWAYS)`
([#2194](https://github.com/androidx/media/issues/2194)).
* MP4: Parse `alternate_group` from the `tkhd` box and expose it as an
`Mp4AlternateGroupData` entry in each track's `Format.metadata`
([#2242](https://github.com/androidx/media/issues/2242)).
* DataSource:
* Audio:
* Allow constant power upmixing/downmixing in DefaultAudioMixer.
* Fix offload issue where position might get stuck when playing a playlist
of short content
([#1920](https://github.com/androidx/media/issues/1920)).
* Video:
* Add experimental `ExoPlayer` API to include the
`MediaCodec.BUFFER_FLAG_DECODE_ONLY` flag when queuing decode-only input
buffers. This flag will signal the decoder to skip the decode-only
buffers thereby resulting in faster seeking. Enable it with
`DefaultRenderersFactory.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag`.
* Text:
* Metadata:
* Image:
* DataSource:
* DRM:
* Effect:
* Add `Presentation.createForShortSide(int)` that creates a `Presentation`
that ensures the shortest side always matches the given value,
regardless of input orientation.
* Muxers:
* `writeSampleData()` API now uses muxer specific `BufferInfo` class
instead of `MediaCodec.BufferInfo`.
* IMA extension:
* Session:
* Lower aggregation timeout for platform `MediaSession` callbacks from 500
to 100 milliseconds and add an experimental setter to allow apps to
configure this value.
* Fix issue where notifications reappear after they have been dismissed by
the user ([#2302](https://github.com/androidx/media/issues/2302)).
* Fix a bug where the `PlayerWrapper` returned a single-item timeline when
the wrapped player is actually empty. This happened when the wrapped
player doesn't have `COMMAND_GET_TIMELINE` available while
`COMMAND_GET_CURRENT_MEDIA_ITEM` is available and the wrapped player is
empty ([#2320](https://github.com/androidx/media/issues/2320)).
* Fix a bug where calling
`MediaSessionService.setMediaNotificationProvider` is silently ignored
after other interactions with the service like
`setForegroundServiceTimeoutMs`
([#2305](https://github.com/androidx/media/issues/2305)).
* UI:
* Enable `PlayerSurface` to work with `ExoPlayer.setVideoEffects` and
`CompositionPlayer`.
* Fix bug where `PlayerSurface` can't be recomposed with a new `Player`.
* Downloads:
* Add partial download support for progressive streams. Apps can prepare a
progressive stream with `DownloadHelper`, and request a
`DownloadRequest` from the helper with specifying the time-based media
start and end positions that the download should cover. The returned
`DownloadRequest` carries the resolved byte range, with which a
`ProgressiveDownloader` can be created and download the content
correspondingly.
* OkHttp extension:
* Cronet extension:
* RTMP extension:
* HLS extension:
* Fix issue where chunk duration wasn't set in `CmcdData` for HLS media,
causing an assertion failure when processing encrypted media segments
([#2312](https://github.com/androidx/media/issues/2312)).
* DASH extension:
* Smooth Streaming extension:
* RTSP extension:
* Add support for URI with RTSPT scheme as a way to configure the RTSP
session to use TCP
([#1484](https://github.com/androidx/media/issues/1484)).
* Decoder extensions (FFmpeg, VP9, AV1, etc.):
* MIDI extension:
* Leanback extension:
* Cast extension:
* Test Utilities:
* Demo app:
* Add `PlaybackSpeedPopUpButton` Composable UI element to be part of
`ExtraControls` in `demo-compose`.
* Remove deprecated symbols:
* Removed deprecated `SegmentDownloader` constructor
`SegmentDownloader(MediaItem, Parser<M>, CacheDataSource.Factory,
Executor)` and the corresponding constructors in its subclasses
`DashDownloader`, `HlsDownloader` and `SsDownloader`.
* Removed deprecated `Player.hasNext()`, `Player.hasNextWindow()`. Use
`Player.hasNextMediaItem()` instead.
* Removed deprecated `Player.next()`. Use `Player.seekToNextMediaItem()`
instead.
* Removed deprecated `Player.seekToPreviousWindow()`. Use
`Player.seekToPreviousMediaItem()` instead.
* Removed deprecated `Player.seekToNextWindow()`. Use
`Player.seekToNextMediaItem()` instead.
* Removed deprecated `BaseAudioProcessor` in `exoplayer` module. Use
`BaseAudioProcessor` under `common` module.
## 1.6 ## 1.6
### 1.6.0 (2025-03-26) ### 1.6.0 (2025-03-26)

View File

@ -505,17 +505,18 @@ public final class PreloadMediaSource extends WrappingMediaSource {
return; return;
} }
PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod; PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod;
long bufferedPositionUs = mediaPeriod.getBufferedPositionUs(); if (prepared) {
if (prepared && bufferedPositionUs == C.TIME_END_OF_SOURCE) { long bufferedPositionUs = mediaPeriod.getBufferedPositionUs();
preloadControl.onLoadedToTheEndOfSource(PreloadMediaSource.this); if (bufferedPositionUs == C.TIME_END_OF_SOURCE) {
stopPreloading(); preloadControl.onLoadedToTheEndOfSource(PreloadMediaSource.this);
return; stopPreloading();
} return;
if (prepared }
&& !preloadControl.onContinueLoadingRequested( if (!preloadControl.onContinueLoadingRequested(
PreloadMediaSource.this, bufferedPositionUs - periodStartPositionUs)) { PreloadMediaSource.this, bufferedPositionUs - periodStartPositionUs)) {
stopPreloading(); stopPreloading();
return; return;
}
} }
preloadMediaPeriod.continueLoading( preloadMediaPeriod.continueLoading(
new LoadingInfo.Builder().setPlaybackPositionUs(periodStartPositionUs).build()); new LoadingInfo.Builder().setPlaybackPositionUs(periodStartPositionUs).build());

View File

@ -90,12 +90,13 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public final class PreloadMediaSourceTest { public final class PreloadMediaSourceTest {
private static final int LOADING_CHECK_INTERVAL_BYTES = 10 * 1024; private static final int LOADING_CHECK_INTERVAL_BYTES = 32;
private static final int TARGET_PRELOAD_DURATION_US = 10000; private static final int TARGET_PRELOAD_DURATION_US = 10000;
private Allocator allocator; private Allocator allocator;
private BandwidthMeter bandwidthMeter; private BandwidthMeter bandwidthMeter;
private RenderersFactory renderersFactory; private RenderersFactory renderersFactory;
private MediaItem mediaItem;
@Before @Before
public void setUp() { public void setUp() {
@ -112,6 +113,10 @@ public final class PreloadMediaSourceTest {
SystemClock.DEFAULT.createHandler(handler.getLooper(), /* callback= */ null), SystemClock.DEFAULT.createHandler(handler.getLooper(), /* callback= */ null),
audioListener) audioListener)
}; };
mediaItem =
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/long_1080p_lowbitrate.mp4"))
.build();
} }
@Test @Test
@ -146,11 +151,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadMediaSourceReference.get() != null); runMainLooperUntil(() -> preloadMediaSourceReference.get() != null);
@ -191,11 +192,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadMediaSourceReference.get() != null); runMainLooperUntil(() -> preloadMediaSourceReference.get() != null);
@ -235,11 +232,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
@ -266,11 +259,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
AtomicReference<MediaSource> externalCallerMediaSourceReference = new AtomicReference<>(); AtomicReference<MediaSource> externalCallerMediaSourceReference = new AtomicReference<>();
MediaSource.MediaSourceCaller externalCaller = MediaSource.MediaSourceCaller externalCaller =
@ -315,11 +304,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadMediaSourceReference.get() != null); runMainLooperUntil(() -> preloadMediaSourceReference.get() != null);
@ -388,11 +373,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadExceptionReference.get() != null); runMainLooperUntil(() -> preloadExceptionReference.get() != null);
@ -472,11 +453,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadExceptionReference.get() != null); runMainLooperUntil(() -> preloadExceptionReference.get() != null);
@ -583,11 +560,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(() -> preloadExceptionReference.get() != null); runMainLooperUntil(() -> preloadExceptionReference.get() != null);
@ -615,11 +588,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
FakeMediaSource wrappedMediaSource = mediaSourceFactory.getLastCreatedSource(); FakeMediaSource wrappedMediaSource = mediaSourceFactory.getLastCreatedSource();
wrappedMediaSource.setAllowPreparation(false); wrappedMediaSource.setAllowPreparation(false);
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
@ -653,11 +622,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
@ -727,11 +692,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
@ -808,11 +769,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
@ -876,11 +833,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
@ -923,11 +876,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean(); AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller = MediaSource.MediaSourceCaller externalCaller =
(source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true); (source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true);
@ -976,11 +925,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean(); AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller = MediaSource.MediaSourceCaller externalCaller =
(source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true); (source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true);
@ -1031,11 +976,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
AtomicBoolean externalCaller1SourceInfoRefreshedCalled = new AtomicBoolean(); AtomicBoolean externalCaller1SourceInfoRefreshedCalled = new AtomicBoolean();
AtomicBoolean externalCaller2SourceInfoRefreshedCalled = new AtomicBoolean(); AtomicBoolean externalCaller2SourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller1 = MediaSource.MediaSourceCaller externalCaller1 =
@ -1090,11 +1031,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
preloadMediaSource.releasePreloadMediaSource(); preloadMediaSource.releasePreloadMediaSource();
@ -1140,11 +1077,7 @@ public final class PreloadMediaSourceTest {
getRendererCapabilities(renderersFactory), getRendererCapabilities(renderersFactory),
allocator, allocator,
Util.getCurrentOrMainLooper()); Util.getCurrentOrMainLooper());
PreloadMediaSource preloadMediaSource = PreloadMediaSource preloadMediaSource = preloadMediaSourceFactory.createMediaSource(mediaItem);
preloadMediaSourceFactory.createMediaSource(
new MediaItem.Builder()
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
.build());
AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean(); AtomicBoolean externalCallerSourceInfoRefreshedCalled = new AtomicBoolean();
MediaSource.MediaSourceCaller externalCaller = MediaSource.MediaSourceCaller externalCaller =
(source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true); (source, timeline) -> externalCallerSourceInfoRefreshedCalled.set(true);