diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java index b14ca8c7c9..f6bbe37179 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java @@ -20,7 +20,6 @@ import android.content.Context; import android.os.Looper; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.MediaItem; -import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.util.Clock; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -34,10 +33,15 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; */ public interface AssetLoader { - /** A factory for {@link AssetLoader} instances. */ + /** + * A factory for {@link AssetLoader} instances. + * + *
The setters in this interface will be called with the values used to build and start the + * {@link Transformer}. + */ interface Factory { - /** Sets the context. */ + /** Sets the {@link Context}. */ @CanIgnoreReturnValue Factory setContext(Context context); @@ -76,10 +80,6 @@ public interface AssetLoader { @CanIgnoreReturnValue Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion); - /** Sets the {@link MediaSource.Factory} to be used to retrieve the samples. */ - @CanIgnoreReturnValue - Factory setMediaSourceFactory(MediaSource.Factory mediaSourceFactory); - /** Sets the {@link Codec.DecoderFactory} to be used to decode the samples (if necessary). */ @CanIgnoreReturnValue Factory setDecoderFactory(Codec.DecoderFactory decoderFactory); @@ -111,7 +111,7 @@ public interface AssetLoader { } /** - * A listener of asset loader events. + * A listener of {@link AssetLoader} events. * *
This listener is typically used in the following way: * diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java index f0f0287796..c5ab9d6365 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java @@ -16,112 +16,79 @@ package com.google.android.exoplayer2.transformer; -import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull; - import android.content.Context; import android.os.Looper; -import androidx.annotation.Nullable; import com.google.android.exoplayer2.MediaItem; -import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.util.Clock; import com.google.errorprone.annotations.CanIgnoreReturnValue; /** The default {@link AssetLoader.Factory} implementation. */ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { - @Nullable private Context context; - @Nullable private MediaItem mediaItem; - 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; + private final AssetLoader.Factory assetLoaderFactory; + + /** Creates an instance. */ + public DefaultAssetLoaderFactory() { + assetLoaderFactory = new ExoPlayerAssetLoader.Factory(); + } @Override @CanIgnoreReturnValue public AssetLoader.Factory setContext(Context context) { - this.context = context; - return this; + return assetLoaderFactory.setContext(context); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setMediaItem(MediaItem mediaItem) { - this.mediaItem = mediaItem; - return this; + return assetLoaderFactory.setMediaItem(mediaItem); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setRemoveAudio(boolean removeAudio) { - this.removeAudio = removeAudio; - return this; + return assetLoaderFactory.setRemoveAudio(removeAudio); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setRemoveVideo(boolean removeVideo) { - this.removeVideo = removeVideo; - return this; + return assetLoaderFactory.setRemoveVideo(removeVideo); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion) { - this.flattenVideoForSlowMotion = flattenVideoForSlowMotion; - return this; - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) { - this.mediaSourceFactory = mediaSourceFactory; + assetLoaderFactory.setFlattenVideoForSlowMotion(flattenVideoForSlowMotion); return this; } @Override @CanIgnoreReturnValue public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) { - this.decoderFactory = decoderFactory; - return this; + return assetLoaderFactory.setDecoderFactory(decoderFactory); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setLooper(Looper looper) { - this.looper = looper; - return this; + return assetLoaderFactory.setLooper(looper); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setListener(AssetLoader.Listener listener) { - this.listener = listener; - return this; + return assetLoaderFactory.setListener(listener); } @Override @CanIgnoreReturnValue public AssetLoader.Factory setClock(Clock clock) { - this.clock = clock; - return this; + return assetLoaderFactory.setClock(clock); } @Override public AssetLoader createAssetLoader() { - return new ExoPlayerAssetLoader( - checkStateNotNull(context), - checkStateNotNull(mediaItem), - removeAudio, - removeVideo, - flattenVideoForSlowMotion, - checkStateNotNull(mediaSourceFactory), - checkStateNotNull(decoderFactory), - checkStateNotNull(looper), - checkStateNotNull(listener), - checkStateNotNull(clock)); + return assetLoaderFactory.createAssetLoader(); } } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java index 356c33334f..d3b388efd2 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java @@ -24,11 +24,13 @@ import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STA import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_NO_TRANSFORMATION; import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_UNAVAILABLE; import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_WAITING_FOR_AVAILABILITY; +import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull; import static java.lang.Math.min; import android.content.Context; import android.os.Handler; import android.os.Looper; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.ExoPlayer; @@ -40,21 +42,146 @@ import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Tracks; import com.google.android.exoplayer2.audio.AudioRendererEventListener; +import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; +import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor; import com.google.android.exoplayer2.metadata.MetadataOutput; +import com.google.android.exoplayer2.source.DefaultMediaSourceFactory; import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.text.TextOutput; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.video.VideoRendererEventListener; +import com.google.errorprone.annotations.CanIgnoreReturnValue; -/* package */ final class ExoPlayerAssetLoader implements AssetLoader { +/** An {@link AssetLoader} implementation that uses an {@link ExoPlayer} to load samples. */ +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 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)}. + */ + 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) { + this.context = context; + return this; + } + + @Override + @CanIgnoreReturnValue + public AssetLoader.Factory setMediaItem(MediaItem mediaItem) { + this.mediaItem = mediaItem; + return this; + } + + @Override + @CanIgnoreReturnValue + public AssetLoader.Factory setRemoveAudio(boolean removeAudio) { + this.removeAudio = removeAudio; + return this; + } + + @Override + @CanIgnoreReturnValue + public AssetLoader.Factory setRemoveVideo(boolean removeVideo) { + this.removeVideo = removeVideo; + return this; + } + + @Override + @CanIgnoreReturnValue + public AssetLoader.Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion) { + this.flattenVideoForSlowMotion = flattenVideoForSlowMotion; + return this; + } + + @Override + @CanIgnoreReturnValue + public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) { + this.decoderFactory = decoderFactory; + return this; + } + + @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); + } + return new ExoPlayerAssetLoader( + context, + checkStateNotNull(mediaItem), + removeAudio, + removeVideo, + flattenVideoForSlowMotion, + mediaSourceFactory, + checkStateNotNull(decoderFactory), + checkStateNotNull(looper), + checkStateNotNull(listener), + checkStateNotNull(clock)); + } + } private final MediaItem mediaItem; private final ExoPlayer player; private @Transformer.ProgressState int progressState; - public ExoPlayerAssetLoader( + private ExoPlayerAssetLoader( Context context, MediaItem mediaItem, boolean removeAudio, diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java index 1da4662288..e37c144e9f 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformationRequest.java @@ -140,10 +140,10 @@ public final class TransformationRequest { *
If specifying a {@link MediaSource.Factory} using {@link - * Transformer.Builder#setMediaSourceFactory(MediaSource.Factory)}, make sure that {@link - * Mp4Extractor#FLAG_READ_SEF_DATA} is set on the {@link Mp4Extractor} used. Otherwise, the slow - * motion metadata will be ignored and the input won't be flattened. + *
If using an {@link ExoPlayerAssetLoader.Factory} with a provided {@link + * MediaSource.Factory}, make sure that {@link Mp4Extractor#FLAG_READ_SEF_DATA} is set on the + * {@link Mp4Extractor} used. Otherwise, the slow motion metadata will be ignored and the input + * won't be flattened. * *
Using slow motion flattening together with {@link
* com.google.android.exoplayer2.MediaItem.ClippingConfiguration} is not supported yet.
diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
index d2580a4944..1ebaafa68c 100644
--- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
+++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java
@@ -34,9 +34,6 @@ import com.google.android.exoplayer2.audio.SonicAudioProcessor;
import com.google.android.exoplayer2.effect.GlEffect;
import com.google.android.exoplayer2.effect.GlEffectsFrameProcessor;
import com.google.android.exoplayer2.effect.GlMatrixTransformation;
-import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
-import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
-import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.DebugViewProvider;
@@ -53,7 +50,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
-import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* A transformer to transform media inputs.
@@ -89,7 +85,6 @@ public final class Transformer {
private boolean removeVideo;
private boolean forceSilentAudio;
private ListenerSet The default value is a {@link DefaultMediaSourceFactory} built with the context provided
- * in {@linkplain #Builder(Context) the constructor}.
- *
- * @param mediaSourceFactory A {@link MediaSource.Factory}.
- * @return This builder.
- */
- @CanIgnoreReturnValue
- public Builder setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
- this.mediaSourceFactory = mediaSourceFactory;
- return this;
- }
-
/**
* Sets the {@link AssetLoader.Factory} to be used to retrieve the samples to transform.
*
@@ -476,13 +455,6 @@ public final class Transformer {
if (transformationRequest.videoMimeType != null) {
checkSampleMimeType(transformationRequest.videoMimeType);
}
- if (mediaSourceFactory == null) {
- DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
- if (transformationRequest.flattenForSlowMotion) {
- defaultExtractorsFactory.setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_SEF_DATA);
- }
- mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory);
- }
return new Transformer(
context,
transformationRequest,
@@ -492,7 +464,6 @@ public final class Transformer {
removeVideo,
forceSilentAudio,
listeners,
- mediaSourceFactory,
assetLoaderFactory,
decoderFactory,
encoderFactory,
@@ -618,7 +589,6 @@ public final class Transformer {
private final boolean removeVideo;
private final boolean forceSilentAudio;
private final ListenerSet