From 951b1319dfbca222f3acfce12640d6fd6d797b06 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Mon, 18 Jul 2022 14:42:04 +0200 Subject: [PATCH 1/2] Add WrappingMediaSource This is a CompositeMediaSource with a slightly simpler API. --- .../exoplayer/source/WrappingMediaSource.java | 80 +++++++++++++++++++ .../media3/exoplayer/ExoPlayerTest.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/WrappingMediaSource.java diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/WrappingMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/WrappingMediaSource.java new file mode 100644 index 0000000000..b098f350c0 --- /dev/null +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/WrappingMediaSource.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.exoplayer.source; + +import androidx.media3.common.Timeline; + +/** + * Single-child {@link CompositeMediaSource}. + */ +public abstract class WrappingMediaSource extends CompositeMediaSource { + + /** + * @deprecated - Use {@link #onChildSourceInfoRefreshed}. + */ + @Deprecated + @Override + protected final void onChildSourceInfoRefreshed( + Void id, MediaSource mediaSource, Timeline timeline + ) { + onChildSourceInfoRefreshed(timeline); + } + + /** + * Called when the source info has been refreshed. + * + * @param timeline The timeline of the source. + */ + protected abstract void onChildSourceInfoRefreshed(Timeline timeline); + + /** + * Prepares a source. + * + *

{@link #onChildSourceInfoRefreshed(Timeline)} will be called when the + * child source updates its timeline with the same {@code id} passed to this method. + * + *

If sources aren't explicitly released with {@link #releaseChildSource()} they will be + * released in {@link #releaseSourceInternal()}. + * + * @param mediaSource The child {@link MediaSource}. + */ + protected final void prepareChildSource(MediaSource mediaSource) { + prepareChildSource(CHILD_SOURCE_ID, mediaSource); + } + + /** + * Enables the child source. + */ + protected final void enableChildSource() { + enableChildSource(CHILD_SOURCE_ID); + } + + /** + * Disables the child source. + */ + protected final void disableChildSource() { + disableChildSource(CHILD_SOURCE_ID); + } + + /** + * Releases the child source. + */ + protected final void releaseChildSource() { + releaseChildSource(CHILD_SOURCE_ID); + } + + private static final Void CHILD_SOURCE_ID = null; +} diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java index 1e0b0338ba..7bcdc66887 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java @@ -128,6 +128,7 @@ import androidx.media3.exoplayer.source.MediaSourceEventListener; import androidx.media3.exoplayer.source.ShuffleOrder; import androidx.media3.exoplayer.source.SinglePeriodTimeline; import androidx.media3.exoplayer.source.TrackGroupArray; +import androidx.media3.exoplayer.source.WrappingMediaSource; import androidx.media3.exoplayer.source.ads.ServerSideAdInsertionMediaSource; import androidx.media3.exoplayer.trackselection.DefaultTrackSelector; import androidx.media3.exoplayer.upstream.Allocation; From ba9f3d8ebc3d48fa79230128708b53fb966b9815 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 15 Jul 2022 18:27:01 +0200 Subject: [PATCH 2/2] Replace usages of CompositeMediaSource with WrappingMediaSource --- .../media3/exoplayer/source/ClippingMediaSource.java | 6 +++--- .../media3/exoplayer/source/LoopingMediaSource.java | 9 +++++---- .../media3/exoplayer/source/MaskingMediaSource.java | 12 +++++------- .../androidx/media3/exoplayer/ExoPlayerTest.java | 9 ++++----- .../ima/ImaServerSideAdInsertionMediaSource.java | 9 ++++----- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java index fc63321d45..6c61911f70 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java @@ -41,7 +41,7 @@ import java.util.ArrayList; * positions. The wrapped source must consist of a single period. */ @UnstableApi -public final class ClippingMediaSource extends CompositeMediaSource { +public final class ClippingMediaSource extends WrappingMediaSource { /** Thrown when a {@link ClippingMediaSource} cannot clip its wrapped source. */ public static final class IllegalClippingException extends IOException { @@ -202,7 +202,7 @@ public final class ClippingMediaSource extends CompositeMediaSource { @Override protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { super.prepareSourceInternal(mediaTransferListener); - prepareChildSource(/* id= */ null, mediaSource); + prepareChildSource(mediaSource); } @Override @@ -242,7 +242,7 @@ public final class ClippingMediaSource extends CompositeMediaSource { } @Override - protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) { + protected void onChildSourceInfoRefreshed(Timeline timeline) { if (clippingError != null) { return; } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/LoopingMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/LoopingMediaSource.java index b3280a4c4e..8904857dc3 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/LoopingMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/LoopingMediaSource.java @@ -43,7 +43,7 @@ import java.util.Map; */ @Deprecated @UnstableApi -public final class LoopingMediaSource extends CompositeMediaSource { +public final class LoopingMediaSource extends WrappingMediaSource { private final MaskingMediaSource maskingMediaSource; private final int loopCount; @@ -95,7 +95,7 @@ public final class LoopingMediaSource extends CompositeMediaSource { @Override protected void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { super.prepareSourceInternal(mediaTransferListener); - prepareChildSource(/* id= */ null, maskingMediaSource); + prepareChildSource(maskingMediaSource); } @Override @@ -123,7 +123,7 @@ public final class LoopingMediaSource extends CompositeMediaSource { } @Override - protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) { + protected void onChildSourceInfoRefreshed(Timeline timeline) { Timeline loopingTimeline = loopCount != Integer.MAX_VALUE ? new LoopingTimeline(timeline, loopCount) @@ -134,7 +134,8 @@ public final class LoopingMediaSource extends CompositeMediaSource { @Override @Nullable protected MediaPeriodId getMediaPeriodIdForChildMediaPeriodId( - Void id, MediaPeriodId mediaPeriodId) { + Void id, MediaPeriodId mediaPeriodId + ) { return loopCount != Integer.MAX_VALUE ? childMediaPeriodIdToMediaPeriodId.get(mediaPeriodId) : mediaPeriodId; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MaskingMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MaskingMediaSource.java index 88cf290892..4d0a8bc8a8 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MaskingMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MaskingMediaSource.java @@ -37,7 +37,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; * structure is known. */ @UnstableApi -public final class MaskingMediaSource extends CompositeMediaSource { +public final class MaskingMediaSource extends WrappingMediaSource { private final MediaSource mediaSource; private final boolean useLazyPreparation; @@ -84,7 +84,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { super.prepareSourceInternal(mediaTransferListener); if (!useLazyPreparation) { hasStartedPreparing = true; - prepareChildSource(/* id= */ null, mediaSource); + prepareChildSource(mediaSource); } } @@ -115,7 +115,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { unpreparedMaskingMediaPeriod = mediaPeriod; if (!hasStartedPreparing) { hasStartedPreparing = true; - prepareChildSource(/* id= */ null, mediaSource); + prepareChildSource(mediaSource); } } return mediaPeriod; @@ -137,8 +137,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { } @Override - protected void onChildSourceInfoRefreshed( - Void id, MediaSource mediaSource, Timeline newTimeline) { + protected void onChildSourceInfoRefreshed(MediaSource mediaSource, Timeline newTimeline) { @Nullable MediaPeriodId idForMaskingPeriodPreparation = null; if (isPrepared) { timeline = timeline.cloneWithUpdatedTimeline(newTimeline); @@ -208,8 +207,7 @@ public final class MaskingMediaSource extends CompositeMediaSource { @Override @Nullable - protected MediaPeriodId getMediaPeriodIdForChildMediaPeriodId( - Void id, MediaPeriodId mediaPeriodId) { + protected MediaPeriodId getMediaPeriodIdForChildMediaPeriodId(MediaPeriodId mediaPeriodId) { return mediaPeriodId.copyWithPeriodUid(getExternalPeriodUid(mediaPeriodId.periodUid)); } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java index 7bcdc66887..378a2b7d24 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java @@ -3942,8 +3942,8 @@ public final class ExoPlayerTest { new TimelineWindowDefinition( /* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 10_000_000)); final ConcatenatingMediaSource underlyingSource = new ConcatenatingMediaSource(); - CompositeMediaSource delegatingMediaSource = - new CompositeMediaSource() { + WrappingMediaSource delegatingMediaSource = + new WrappingMediaSource() { @Override public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) { super.prepareSourceInternal(mediaTransferListener); @@ -3951,7 +3951,7 @@ public final class ExoPlayerTest { new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); underlyingSource.addMediaSource( new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)); - prepareChildSource(null, underlyingSource); + prepareChildSource(underlyingSource); } @Override @@ -3966,8 +3966,7 @@ public final class ExoPlayerTest { } @Override - protected void onChildSourceInfoRefreshed( - Void id, MediaSource mediaSource, Timeline timeline) { + protected void onChildSourceInfoRefreshed(Timeline timeline) { refreshSourceInfo(timeline); } diff --git a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java index e7d261c220..5ff636e50c 100644 --- a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java +++ b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java @@ -56,11 +56,11 @@ import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.datasource.TransferListener; import androidx.media3.exoplayer.drm.DrmSessionManagerProvider; -import androidx.media3.exoplayer.source.CompositeMediaSource; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.source.ForwardingTimeline; import androidx.media3.exoplayer.source.MediaPeriod; import androidx.media3.exoplayer.source.MediaSource; +import androidx.media3.exoplayer.source.WrappingMediaSource; import androidx.media3.exoplayer.source.ads.ServerSideAdInsertionMediaSource; import androidx.media3.exoplayer.source.ads.ServerSideAdInsertionMediaSource.AdPlaybackStateUpdater; import androidx.media3.exoplayer.source.ads.ServerSideAdInsertionUtil; @@ -108,7 +108,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** MediaSource for IMA server side inserted ad streams. */ @UnstableApi -public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSource { +public final class ImaServerSideAdInsertionMediaSource extends WrappingMediaSource { /** * Factory for creating {@link ImaServerSideAdInsertionMediaSource @@ -521,8 +521,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou } @Override - protected void onChildSourceInfoRefreshed( - Void id, MediaSource mediaSource, Timeline newTimeline) { + protected void onChildSourceInfoRefreshed(Timeline newTimeline) { refreshSourceInfo( new ForwardingTimeline(newTimeline) { @Override @@ -655,7 +654,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou .withIsServerSideInserted(/* adGroupIndex= */ 0, true); mainHandler.post(() -> setAdPlaybackState(liveAdPlaybackState)); } - prepareChildSource(/* id= */ null, serverSideAdInsertionMediaSource); + prepareChildSource(serverSideAdInsertionMediaSource); } // Static methods.