mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add PreloadMediaSource.clear to discard the preloading period
PiperOrigin-RevId: 633167081
This commit is contained in:
parent
71e36ac6d2
commit
0db23ae904
@ -26,6 +26,7 @@
|
|||||||
source or take other actions.
|
source or take other actions.
|
||||||
* Fix bug where silence skipping at the end of items can trigger a
|
* Fix bug where silence skipping at the end of items can trigger a
|
||||||
playback exception.
|
playback exception.
|
||||||
|
* Add `clear` to `PreloadMediaSource` to discard the preloading period.
|
||||||
* Transformer:
|
* Transformer:
|
||||||
* Work around a decoder bug where the number of audio channels was capped
|
* Work around a decoder bug where the number of audio channels was capped
|
||||||
at stereo when handling PCM input.
|
at stereo when handling PCM input.
|
||||||
|
@ -259,6 +259,21 @@ public final class PreloadMediaSource extends WrappingMediaSource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the preloading {@link PreloadMediaPeriod} in {@link PreloadMediaSource}.
|
||||||
|
*
|
||||||
|
* <p>Can be called from any thread.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
preloadHandler.post(
|
||||||
|
() -> {
|
||||||
|
if (preloadingMediaPeriodAndKey != null) {
|
||||||
|
mediaSource.releasePeriod(preloadingMediaPeriodAndKey.first.mediaPeriod);
|
||||||
|
preloadingMediaPeriodAndKey = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void prepareSourceInternal() {
|
protected void prepareSourceInternal() {
|
||||||
if (isUsedByPlayer() && !onUsedByPlayerNotified) {
|
if (isUsedByPlayer() && !onUsedByPlayerNotified) {
|
||||||
@ -337,8 +352,7 @@ public final class PreloadMediaSource extends WrappingMediaSource {
|
|||||||
&& preloadMediaPeriod == checkNotNull(playingPreloadedMediaPeriodAndId).first) {
|
&& preloadMediaPeriod == checkNotNull(playingPreloadedMediaPeriodAndId).first) {
|
||||||
playingPreloadedMediaPeriodAndId = null;
|
playingPreloadedMediaPeriodAndId = null;
|
||||||
}
|
}
|
||||||
MediaPeriod periodToRelease = preloadMediaPeriod.mediaPeriod;
|
mediaSource.releasePeriod(preloadMediaPeriod.mediaPeriod);
|
||||||
mediaSource.releasePeriod(periodToRelease);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,6 +29,7 @@ import static org.robolectric.Shadows.shadowOf;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.Timeline;
|
import androidx.media3.common.Timeline;
|
||||||
@ -36,16 +37,21 @@ import androidx.media3.common.Tracks;
|
|||||||
import androidx.media3.common.util.SystemClock;
|
import androidx.media3.common.util.SystemClock;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.datasource.DefaultDataSource;
|
import androidx.media3.datasource.DefaultDataSource;
|
||||||
|
import androidx.media3.datasource.TransferListener;
|
||||||
import androidx.media3.exoplayer.Renderer;
|
import androidx.media3.exoplayer.Renderer;
|
||||||
import androidx.media3.exoplayer.RendererCapabilities;
|
import androidx.media3.exoplayer.RendererCapabilities;
|
||||||
import androidx.media3.exoplayer.RendererConfiguration;
|
import androidx.media3.exoplayer.RendererConfiguration;
|
||||||
import androidx.media3.exoplayer.RenderersFactory;
|
import androidx.media3.exoplayer.RenderersFactory;
|
||||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||||
import androidx.media3.exoplayer.audio.AudioRendererEventListener;
|
import androidx.media3.exoplayer.audio.AudioRendererEventListener;
|
||||||
|
import androidx.media3.exoplayer.drm.DrmSessionEventListener;
|
||||||
|
import androidx.media3.exoplayer.drm.DrmSessionManager;
|
||||||
import androidx.media3.exoplayer.metadata.MetadataOutput;
|
import androidx.media3.exoplayer.metadata.MetadataOutput;
|
||||||
import androidx.media3.exoplayer.source.MediaPeriod;
|
import androidx.media3.exoplayer.source.MediaPeriod;
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
import androidx.media3.exoplayer.source.MediaSource;
|
||||||
|
import androidx.media3.exoplayer.source.MediaSourceEventListener;
|
||||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
||||||
|
import androidx.media3.exoplayer.source.TrackGroupArray;
|
||||||
import androidx.media3.exoplayer.text.TextOutput;
|
import androidx.media3.exoplayer.text.TextOutput;
|
||||||
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
|
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
|
||||||
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||||
@ -57,6 +63,7 @@ import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
|||||||
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;
|
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;
|
||||||
import androidx.media3.exoplayer.video.VideoRendererEventListener;
|
import androidx.media3.exoplayer.video.VideoRendererEventListener;
|
||||||
import androidx.media3.test.utils.FakeAudioRenderer;
|
import androidx.media3.test.utils.FakeAudioRenderer;
|
||||||
|
import androidx.media3.test.utils.FakeMediaPeriod;
|
||||||
import androidx.media3.test.utils.FakeMediaSource;
|
import androidx.media3.test.utils.FakeMediaSource;
|
||||||
import androidx.media3.test.utils.FakeMediaSourceFactory;
|
import androidx.media3.test.utils.FakeMediaSourceFactory;
|
||||||
import androidx.media3.test.utils.FakeTimeline;
|
import androidx.media3.test.utils.FakeTimeline;
|
||||||
@ -795,6 +802,83 @@ public final class PreloadMediaSourceTest {
|
|||||||
verify(internalSourceReference.get(), times(2)).createPeriod(any(), any(), anyLong());
|
verify(internalSourceReference.get(), times(2)).createPeriod(any(), any(), anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clear_preloadingPeriodReleased() throws Exception {
|
||||||
|
AtomicBoolean onPreparedCalled = new AtomicBoolean();
|
||||||
|
PreloadMediaSource.PreloadControl preloadControl =
|
||||||
|
new PreloadMediaSource.PreloadControl() {
|
||||||
|
@Override
|
||||||
|
public boolean onTimelineRefreshed(PreloadMediaSource mediaSource) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepared(PreloadMediaSource mediaSource) {
|
||||||
|
onPreparedCalled.set(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onContinueLoadingRequested(
|
||||||
|
PreloadMediaSource mediaSource, long bufferedPositionUs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUsedByPlayer(PreloadMediaSource mediaSource) {}
|
||||||
|
};
|
||||||
|
MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class);
|
||||||
|
AtomicBoolean preloadingMediaPeriodReleased = new AtomicBoolean();
|
||||||
|
when(mockMediaSourceFactory.createMediaSource(any()))
|
||||||
|
.thenReturn(
|
||||||
|
new FakeMediaSource() {
|
||||||
|
@Override
|
||||||
|
protected MediaPeriod createMediaPeriod(
|
||||||
|
MediaPeriodId id,
|
||||||
|
TrackGroupArray trackGroupArray,
|
||||||
|
Allocator allocator,
|
||||||
|
MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher,
|
||||||
|
DrmSessionManager drmSessionManager,
|
||||||
|
DrmSessionEventListener.EventDispatcher drmEventDispatcher,
|
||||||
|
@Nullable TransferListener transferListener) {
|
||||||
|
return new FakeMediaPeriod(
|
||||||
|
trackGroupArray,
|
||||||
|
allocator,
|
||||||
|
FakeTimeline.TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US,
|
||||||
|
mediaSourceEventDispatcher) {
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
preloadingMediaPeriodReleased.set(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TrackSelector trackSelector =
|
||||||
|
new DefaultTrackSelector(ApplicationProvider.getApplicationContext());
|
||||||
|
trackSelector.init(() -> {}, bandwidthMeter);
|
||||||
|
PreloadMediaSource.Factory preloadMediaSourceFactory =
|
||||||
|
new PreloadMediaSource.Factory(
|
||||||
|
mockMediaSourceFactory,
|
||||||
|
preloadControl,
|
||||||
|
trackSelector,
|
||||||
|
bandwidthMeter,
|
||||||
|
getRendererCapabilities(renderersFactory),
|
||||||
|
allocator,
|
||||||
|
Util.getCurrentOrMainLooper());
|
||||||
|
PreloadMediaSource preloadMediaSource =
|
||||||
|
preloadMediaSourceFactory.createMediaSource(
|
||||||
|
new MediaItem.Builder()
|
||||||
|
.setUri(Uri.parse("asset://android_asset/media/mp4/sample.mp4"))
|
||||||
|
.build());
|
||||||
|
preloadMediaSource.preload(/* startPositionUs= */ 0L);
|
||||||
|
runMainLooperUntil(onPreparedCalled::get);
|
||||||
|
|
||||||
|
preloadMediaSource.clear();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
assertThat(preloadingMediaPeriodReleased.get()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void releaseSourceByAllExternalCallers_preloadNotCalledBefore_releaseInternalSource() {
|
public void releaseSourceByAllExternalCallers_preloadNotCalledBefore_releaseInternalSource() {
|
||||||
PreloadMediaSource.PreloadControl preloadControl =
|
PreloadMediaSource.PreloadControl preloadControl =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user