diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/AssetLoader.java b/libraries/transformer/src/main/java/androidx/media3/transformer/AssetLoader.java index 82b55cf371..3890a5f29c 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/AssetLoader.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/AssetLoader.java @@ -18,13 +18,11 @@ package androidx.media3.transformer; import static java.lang.annotation.ElementType.TYPE_USE; -import android.content.Context; import android.os.Looper; import androidx.annotation.IntDef; import androidx.annotation.IntRange; import androidx.media3.common.Format; import androidx.media3.common.MediaItem; -import androidx.media3.common.util.Clock; import androidx.media3.common.util.UnstableApi; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.lang.annotation.Documented; @@ -51,14 +49,6 @@ public interface AssetLoader { */ interface Factory { - /** Sets the {@link Context}. */ - @CanIgnoreReturnValue - Factory setContext(Context context); - - /** Sets the {@link MediaItem} to load. */ - @CanIgnoreReturnValue - Factory setMediaItem(MediaItem mediaItem); - /** * Sets whether to remove the audio samples from the output (if any). * @@ -94,30 +84,18 @@ public interface AssetLoader { @CanIgnoreReturnValue Factory setDecoderFactory(Codec.DecoderFactory decoderFactory); - /** - * Sets the {@link Looper} that's used to access the {@link AssetLoader} after it's been - * created. - */ - @CanIgnoreReturnValue - Factory setLooper(Looper looper); - - /** Sets the {@link Listener} on which the {@link AssetLoader} should notify of events. */ - @CanIgnoreReturnValue - Factory setListener(AssetLoader.Listener listener); - - /** - * The {@link Clock} to use. - * - *
Should always be {@link Clock#DEFAULT} except for testing. - */ - @CanIgnoreReturnValue - Factory setClock(Clock clock); - /** * Creates an {@link AssetLoader} instance. All the setters in this factory must be called * before creating the {@link AssetLoader}. + * + * @param mediaItem The {@link MediaItem} to load. + * @param looper The {@link Looper} that's used to access the {@link AssetLoader} after it's + * been created. + * @param listener The {@link Listener} on which the {@link AssetLoader} should notify of + * events. + * @return An {@link AssetLoader}. */ - AssetLoader createAssetLoader(); + AssetLoader createAssetLoader(MediaItem mediaItem, Looper looper, Listener listener); } /** diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultAssetLoaderFactory.java b/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultAssetLoaderFactory.java index 8a19b01639..117a9ead04 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultAssetLoaderFactory.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultAssetLoaderFactory.java @@ -21,6 +21,7 @@ import android.os.Looper; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Clock; import androidx.media3.common.util.UnstableApi; +import androidx.media3.exoplayer.source.MediaSource; import com.google.errorprone.annotations.CanIgnoreReturnValue; /** The default {@link AssetLoader.Factory} implementation. */ @@ -29,21 +30,18 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { private final AssetLoader.Factory assetLoaderFactory; - /** Creates an instance. */ - public DefaultAssetLoaderFactory() { - assetLoaderFactory = new ExoPlayerAssetLoader.Factory(); - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setContext(Context context) { - return assetLoaderFactory.setContext(context); - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setMediaItem(MediaItem mediaItem) { - return assetLoaderFactory.setMediaItem(mediaItem); + /** + * Creates an instance. + * + * @param context The {@link Context}. + * @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to + * transform when an {@link ExoPlayerAssetLoader} is used. + * @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for + * testing. + */ + public DefaultAssetLoaderFactory( + Context context, MediaSource.Factory mediaSourceFactory, Clock clock) { + assetLoaderFactory = new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, clock); } @Override @@ -72,25 +70,8 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { } @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setLooper(Looper looper) { - return assetLoaderFactory.setLooper(looper); - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setListener(AssetLoader.Listener listener) { - return assetLoaderFactory.setListener(listener); - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setClock(Clock clock) { - return assetLoaderFactory.setClock(clock); - } - - @Override - public AssetLoader createAssetLoader() { - return assetLoaderFactory.createAssetLoader(); + public AssetLoader createAssetLoader( + MediaItem mediaItem, Looper looper, AssetLoader.Listener listener) { + return assetLoaderFactory.createAssetLoader(mediaItem, looper, listener); } } diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/ExoPlayerAssetLoader.java b/libraries/transformer/src/main/java/androidx/media3/transformer/ExoPlayerAssetLoader.java index bbf5f5a80a..e6f903f864 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/ExoPlayerAssetLoader.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/ExoPlayerAssetLoader.java @@ -48,13 +48,10 @@ import androidx.media3.exoplayer.Renderer; import androidx.media3.exoplayer.RenderersFactory; import androidx.media3.exoplayer.audio.AudioRendererEventListener; import androidx.media3.exoplayer.metadata.MetadataOutput; -import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.text.TextOutput; import androidx.media3.exoplayer.trackselection.DefaultTrackSelector; import androidx.media3.exoplayer.video.VideoRendererEventListener; -import androidx.media3.extractor.DefaultExtractorsFactory; -import androidx.media3.extractor.mp4.Mp4Extractor; import com.google.errorprone.annotations.CanIgnoreReturnValue; /** An {@link AssetLoader} implementation that uses an {@link ExoPlayer} to load samples. */ @@ -64,48 +61,28 @@ public final class ExoPlayerAssetLoader implements AssetLoader { /** An {@link AssetLoader.Factory} for {@link ExoPlayerAssetLoader} instances. */ public static final class Factory implements AssetLoader.Factory { - @Nullable private Context context; - @Nullable private MediaItem mediaItem; + private final Context context; + private final MediaSource.Factory mediaSourceFactory; + private final Clock clock; + private boolean removeAudio; private boolean removeVideo; private boolean flattenVideoForSlowMotion; - @Nullable private MediaSource.Factory mediaSourceFactory; @Nullable private Codec.DecoderFactory decoderFactory; - @Nullable private Looper looper; - @Nullable private AssetLoader.Listener listener; - @Nullable private Clock clock; /** * Creates an instance. * - *
The {@link ExoPlayerAssetLoader} instances produced use a {@link
- * DefaultMediaSourceFactory} built with the context provided in {@linkplain
- * #setContext(Context)}.
+ * @param context The {@link Context}.
+ * @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to
+ * transform.
+ * @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
+ * testing.
*/
- public Factory() {}
-
- /**
- * Creates an instance.
- *
- * @param mediaSourceFactory The {@link MediaSource.Factory} to be used to retrieve the samples
- * to transform.
- */
- public Factory(MediaSource.Factory mediaSourceFactory) {
- this.mediaSourceFactory = mediaSourceFactory;
- }
-
- @Override
- @CanIgnoreReturnValue
- public AssetLoader.Factory setContext(Context context) {
+ public Factory(Context context, MediaSource.Factory mediaSourceFactory, Clock clock) {
this.context = context;
- return this;
- }
-
- @Override
- @CanIgnoreReturnValue
- public AssetLoader.Factory setMediaItem(MediaItem mediaItem) {
- this.mediaItem = mediaItem;
- return this;
+ this.mediaSourceFactory = mediaSourceFactory;
+ this.clock = clock;
}
@Override
@@ -137,47 +114,18 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
}
@Override
- @CanIgnoreReturnValue
- public AssetLoader.Factory setLooper(Looper looper) {
- this.looper = looper;
- return this;
- }
-
- @Override
- @CanIgnoreReturnValue
- public AssetLoader.Factory setListener(AssetLoader.Listener listener) {
- this.listener = listener;
- return this;
- }
-
- @Override
- @CanIgnoreReturnValue
- public AssetLoader.Factory setClock(Clock clock) {
- this.clock = clock;
- return this;
- }
-
- @Override
- public AssetLoader createAssetLoader() {
- Context context = checkStateNotNull(this.context);
- if (mediaSourceFactory == null) {
- DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
- if (flattenVideoForSlowMotion) {
- defaultExtractorsFactory.setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_SEF_DATA);
- }
- mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
- }
+ public AssetLoader createAssetLoader(MediaItem mediaItem, Looper looper, Listener listener) {
return new ExoPlayerAssetLoader(
context,
- checkStateNotNull(mediaItem),
+ mediaItem,
removeAudio,
removeVideo,
flattenVideoForSlowMotion,
mediaSourceFactory,
checkStateNotNull(decoderFactory),
- checkStateNotNull(looper),
- checkStateNotNull(listener),
- checkStateNotNull(clock));
+ looper,
+ listener,
+ clock);
}
}
diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
index dc5ce658b3..c4aca97801 100644
--- a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
+++ b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
@@ -43,6 +43,10 @@ import androidx.media3.effect.GlEffect;
import androidx.media3.effect.GlEffectsFrameProcessor;
import androidx.media3.effect.GlMatrixTransformation;
import androidx.media3.exoplayer.audio.SonicAudioProcessor;
+import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
+import androidx.media3.exoplayer.source.MediaSource;
+import androidx.media3.extractor.DefaultExtractorsFactory;
+import androidx.media3.extractor.mp4.Mp4Extractor;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.lang.annotation.Documented;
@@ -86,7 +90,7 @@ public final class Transformer {
private boolean removeVideo;
private boolean forceSilentAudio;
private ListenerSet The default value is a {@link DefaultAssetLoaderFactory}.
+ * The default value is a {@link DefaultAssetLoaderFactory} built with a {@link
+ * DefaultMediaSourceFactory}.
*
* @param assetLoaderFactory An {@link AssetLoader.Factory}.
* @return This builder.
@@ -456,6 +460,15 @@ public final class Transformer {
if (transformationRequest.videoMimeType != null) {
checkSampleMimeType(transformationRequest.videoMimeType);
}
+ if (assetLoaderFactory == null) {
+ DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
+ if (transformationRequest.flattenForSlowMotion) {
+ defaultExtractorsFactory.setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_SEF_DATA);
+ }
+ MediaSource.Factory mediaSourceFactory =
+ new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
+ assetLoaderFactory = new DefaultAssetLoaderFactory(context, mediaSourceFactory, clock);
+ }
return new Transformer(
context,
transformationRequest,
diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java
index bdd86b7eec..d3aeccb102 100644
--- a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java
+++ b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java
@@ -161,16 +161,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
ComponentListener componentListener = new ComponentListener(mediaItem, fallbackListener);
assetLoader =
assetLoaderFactory
- .setContext(context)
- .setMediaItem(mediaItem)
.setRemoveAudio(removeAudio)
.setRemoveVideo(removeVideo)
.setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion)
.setDecoderFactory(this.decoderFactory)
- .setLooper(internalLooper)
- .setListener(componentListener)
- .setClock(clock)
- .createAssetLoader();
+ .createAssetLoader(mediaItem, internalLooper, componentListener);
samplePipelines = new ArrayList<>();
silentSamplePipelineIndex = C.INDEX_UNSET;
dequeueBufferConditionVariable = new ConditionVariable();
diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/ExoPlayerAssetLoaderTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/ExoPlayerAssetLoaderTest.java
index 4e5d9cabfc..092e986e09 100644
--- a/libraries/transformer/src/test/java/androidx/media3/transformer/ExoPlayerAssetLoaderTest.java
+++ b/libraries/transformer/src/test/java/androidx/media3/transformer/ExoPlayerAssetLoaderTest.java
@@ -27,6 +27,8 @@ import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Clock;
import androidx.media3.decoder.DecoderInputBuffer;
+import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
+import androidx.media3.exoplayer.source.MediaSource;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.time.Duration;
@@ -116,18 +118,14 @@ public class ExoPlayerAssetLoaderTest {
private static AssetLoader getAssetLoader(
Looper looper, AssetLoader.Listener listener, Clock clock) {
Context context = ApplicationProvider.getApplicationContext();
+ MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context);
MediaItem mediaItem = MediaItem.fromUri("asset:///media/mp4/sample.mp4");
- return new ExoPlayerAssetLoader.Factory()
- .setContext(context)
- .setMediaItem(mediaItem)
+ return new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, clock)
.setRemoveAudio(false)
.setRemoveVideo(false)
.setFlattenVideoForSlowMotion(false)
.setDecoderFactory(new DefaultDecoderFactory(context))
- .setLooper(looper)
- .setListener(listener)
- .setClock(clock)
- .createAssetLoader();
+ .createAssetLoader(mediaItem, looper, listener);
}
private static final class FakeSampleConsumer implements SampleConsumer {
diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java
index 69a1cc27ff..e4801dd86c 100644
--- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java
+++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java
@@ -16,7 +16,6 @@
package androidx.media3.transformer;
-import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.test.utils.robolectric.RobolectricUtil.runLooperUntil;
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_DECODED;
import static androidx.media3.transformer.AssetLoader.SUPPORTED_OUTPUT_TYPE_ENCODED;
@@ -47,7 +46,6 @@ import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
-import androidx.media3.common.util.Clock;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.audio.SonicAudioProcessor;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
@@ -529,7 +527,8 @@ public final class TransformerEndToEndTest {
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(
context, new SlowExtractorsFactory(/* delayBetweenReadsMs= */ 10));
- AssetLoader.Factory assetLoaderFactory = new ExoPlayerAssetLoader.Factory(mediaSourceFactory);
+ AssetLoader.Factory assetLoaderFactory =
+ new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, clock);
Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ 1);
Transformer transformer =
createTransformerBuilder(/* enableFallback= */ false)
@@ -1079,8 +1078,6 @@ public final class TransformerEndToEndTest {
private final @SupportedOutputTypes int supportedOutputTypes;
@Nullable private final AtomicReference