From e7bc263c4d2ae856f38a710b3e127dc83f6a99a0 Mon Sep 17 00:00:00 2001 From: kimvde Date: Mon, 30 Jan 2023 14:09:39 +0000 Subject: [PATCH] Pass an EditedMediaItem to AssetLoader.Factory PiperOrigin-RevId: 505671326 --- .../exoplayer2/transformer/AssetLoader.java | 57 +++++------------- .../transformer/CompositeAssetLoader.java | 22 +++---- .../DefaultAssetLoaderFactory.java | 25 +------- .../transformer/ExoPlayerAssetLoader.java | 60 ++++--------------- .../transformer/TransformerInternal.java | 6 +- .../transformer/ExoPlayerAssetLoaderTest.java | 8 +-- .../transformer/TransformerEndToEndTest.java | 18 +----- 7 files changed, 46 insertions(+), 150 deletions(-) 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 a6c1d44efa..aaad240e9f 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 @@ -22,9 +22,7 @@ import android.os.Looper; import androidx.annotation.IntDef; import androidx.annotation.IntRange; import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.MediaItem; import com.google.common.collect.ImmutableMap; -import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -37,60 +35,33 @@ import java.lang.annotation.Target; * *

Only audio and video samples are supported. Both audio and video tracks can be provided by a * single asset loader, but outputting multiple tracks of the same type is not supported. + * + *

An asset loader is responsible for {@linkplain EditedMediaItem.Builder#setRemoveAudio(boolean) + * removing audio} or {@linkplain EditedMediaItem.Builder#setRemoveVideo(boolean) video} if + * requested. + * + *

If {@linkplain EditedMediaItem.Builder#setFlattenForSlowMotion(boolean) slow motion + * flattening} is requested, the asset loader should flatten the video track for media containing + * slow motion markers. This is usually done prior to decoding. The audio samples are flattened + * after they are output by the {@link AssetLoader}, because this is done on decoded samples. */ public interface AssetLoader { - /** - * 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}. - */ + /** A factory for {@link AssetLoader} instances. */ interface Factory { /** - * Sets whether to remove the audio samples from the output (if any). + * Creates an {@link AssetLoader} instance. * - *

The audio and video cannot both be removed because the output would not contain any - * samples. - */ - @CanIgnoreReturnValue - Factory setRemoveAudio(boolean removeAudio); - - /** - * Sets whether to remove the video samples from the output (if any). - * - *

The audio and video cannot both be removed because the output would not contain any - * samples. - */ - @CanIgnoreReturnValue - Factory setRemoveVideo(boolean removeVideo); - - /** - * Sets whether the video samples should be flattened prior to decoding for media containing - * slow motion markers. - * - *

The audio samples are flattened after they are output by the {@link AssetLoader}, because - * this is done on decoded samples. - * - *

For more information on slow motion flattening, see {@link - * EditedMediaItem.Builder#setFlattenForSlowMotion(boolean)}. - */ - @CanIgnoreReturnValue - Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion); - - /** - * 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 editedMediaItem The {@link EditedMediaItem} 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(MediaItem mediaItem, Looper looper, Listener listener); + AssetLoader createAssetLoader( + EditedMediaItem editedMediaItem, Looper looper, Listener listener); } /** diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/CompositeAssetLoader.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/CompositeAssetLoader.java index efbacc2fc5..3147f4eed8 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/CompositeAssetLoader.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/CompositeAssetLoader.java @@ -25,7 +25,6 @@ import android.view.Surface; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.HandlerWrapper; @@ -44,7 +43,7 @@ import java.util.concurrent.atomic.AtomicLong; */ /* package */ final class CompositeAssetLoader implements AssetLoader, AssetLoader.Listener { - private final List mediaItems; + private final List editedMediaItems; private final AtomicInteger currentMediaItemIndex; private final AssetLoader.Factory assetLoaderFactory; private final HandlerWrapper handler; @@ -58,12 +57,12 @@ import java.util.concurrent.atomic.AtomicLong; private volatile long currentDurationUs; public CompositeAssetLoader( - List mediaItems, + List editedMediaItems, AssetLoader.Factory assetLoaderFactory, Looper looper, Listener listener, Clock clock) { - this.mediaItems = mediaItems; + this.editedMediaItems = editedMediaItems; this.assetLoaderFactory = assetLoaderFactory; compositeAssetLoaderListener = listener; currentMediaItemIndex = new AtomicInteger(); @@ -75,7 +74,7 @@ import java.util.concurrent.atomic.AtomicLong; // constructor. @SuppressWarnings("nullness:argument.type.incompatible") AssetLoader currentAssetLoader = - assetLoaderFactory.createAssetLoader(mediaItems.get(0), looper, /* listener= */ this); + assetLoaderFactory.createAssetLoader(editedMediaItems.get(0), looper, /* listener= */ this); this.currentAssetLoader = currentAssetLoader; } @@ -87,7 +86,7 @@ import java.util.concurrent.atomic.AtomicLong; @Override public @Transformer.ProgressState int getProgress(ProgressHolder progressHolder) { int progressState = currentAssetLoader.getProgress(progressHolder); - int mediaItemCount = mediaItems.size(); + int mediaItemCount = editedMediaItems.size(); if (mediaItemCount == 1 || progressState == PROGRESS_STATE_NOT_STARTED) { return progressState; } @@ -116,7 +115,7 @@ import java.util.concurrent.atomic.AtomicLong; @Override public void onDurationUs(long durationUs) { currentDurationUs = durationUs; - if (mediaItems.size() == 1) { + if (editedMediaItems.size() == 1) { compositeAssetLoaderListener.onDurationUs(durationUs); } else if (currentMediaItemIndex.get() == 0) { // TODO(b/252537210): support silent audio track for sequence of AssetLoaders (silent audio @@ -194,7 +193,7 @@ import java.util.concurrent.atomic.AtomicLong; DecoderInputBuffer inputBuffer = checkStateNotNull(sampleConsumer.getInputBuffer()); if (inputBuffer.isEndOfStream()) { nonEndedTracks.decrementAndGet(); - if (currentMediaItemIndex.get() < mediaItems.size() - 1) { + if (currentMediaItemIndex.get() < editedMediaItems.size() - 1) { if (nonEndedTracks.get() == 0) { switchAssetLoader(); } @@ -233,7 +232,7 @@ import java.util.concurrent.atomic.AtomicLong; @Override public void signalEndOfVideoInput() { nonEndedTracks.decrementAndGet(); - if (currentMediaItemIndex.get() < mediaItems.size() - 1) { + if (currentMediaItemIndex.get() < editedMediaItems.size() - 1) { if (nonEndedTracks.get() == 0) { switchAssetLoader(); sampleConsumer.setVideoOffsetToAddUs(totalDurationUs.get()); @@ -248,10 +247,11 @@ import java.util.concurrent.atomic.AtomicLong; handler.post( () -> { currentAssetLoader.release(); - MediaItem mediaItem = mediaItems.get(currentMediaItemIndex.incrementAndGet()); + EditedMediaItem editedMediaItem = + editedMediaItems.get(currentMediaItemIndex.incrementAndGet()); currentAssetLoader = assetLoaderFactory.createAssetLoader( - mediaItem, + editedMediaItem, checkNotNull(Looper.myLooper()), /* listener= */ CompositeAssetLoader.this); currentAssetLoader.start(); 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 ca491e273b..87c00e8d30 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 @@ -18,10 +18,8 @@ package com.google.android.exoplayer2.transformer; import android.content.Context; import android.os.Looper; -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 { @@ -62,28 +60,9 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { new ExoPlayerAssetLoader.Factory(context, decoderFactory, clock, mediaSourceFactory); } - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setRemoveAudio(boolean removeAudio) { - return assetLoaderFactory.setRemoveAudio(removeAudio); - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setRemoveVideo(boolean removeVideo) { - return assetLoaderFactory.setRemoveVideo(removeVideo); - } - - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion) { - assetLoaderFactory.setFlattenVideoForSlowMotion(flattenVideoForSlowMotion); - return this; - } - @Override public AssetLoader createAssetLoader( - MediaItem mediaItem, Looper looper, AssetLoader.Listener listener) { - return assetLoaderFactory.createAssetLoader(mediaItem, looper, listener); + EditedMediaItem editedMediaItem, Looper looper, AssetLoader.Listener listener) { + return assetLoaderFactory.createAssetLoader(editedMediaItem, looper, listener); } } 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 96c0c96edd..59d321e225 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 @@ -36,7 +36,6 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.DefaultLoadControl; import com.google.android.exoplayer2.ExoPlayer; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Renderer; @@ -54,7 +53,6 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.video.VideoRendererEventListener; import com.google.common.collect.ImmutableMap; -import com.google.errorprone.annotations.CanIgnoreReturnValue; /** An {@link AssetLoader} implementation that uses an {@link ExoPlayer} to load samples. */ public final class ExoPlayerAssetLoader implements AssetLoader { @@ -67,10 +65,6 @@ public final class ExoPlayerAssetLoader implements AssetLoader { private final Clock clock; @Nullable private final MediaSource.Factory mediaSourceFactory; - private boolean removeAudio; - private boolean removeVideo; - private boolean flattenVideoForSlowMotion; - /** * Creates an instance using a {@link DefaultMediaSourceFactory}. * @@ -110,51 +104,22 @@ public final class ExoPlayerAssetLoader implements AssetLoader { } @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 - public AssetLoader createAssetLoader(MediaItem mediaItem, Looper looper, Listener listener) { + public AssetLoader createAssetLoader( + EditedMediaItem editedMediaItem, Looper looper, Listener listener) { MediaSource.Factory mediaSourceFactory = this.mediaSourceFactory; if (mediaSourceFactory == null) { DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory(); - if (flattenVideoForSlowMotion) { + if (editedMediaItem.flattenForSlowMotion) { defaultExtractorsFactory.setMp4ExtractorFlags(Mp4Extractor.FLAG_READ_SEF_DATA); } mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory); } return new ExoPlayerAssetLoader( - context, - mediaItem, - removeAudio, - removeVideo, - flattenVideoForSlowMotion, - mediaSourceFactory, - decoderFactory, - looper, - listener, - clock); + context, editedMediaItem, mediaSourceFactory, decoderFactory, looper, listener, clock); } } - private final MediaItem mediaItem; + private final EditedMediaItem editedMediaItem; private final CapturingDecoderFactory decoderFactory; private final ExoPlayer player; @@ -162,16 +127,13 @@ public final class ExoPlayerAssetLoader implements AssetLoader { private ExoPlayerAssetLoader( Context context, - MediaItem mediaItem, - boolean removeAudio, - boolean removeVideo, - boolean flattenForSlowMotion, + EditedMediaItem editedMediaItem, MediaSource.Factory mediaSourceFactory, Codec.DecoderFactory decoderFactory, Looper looper, Listener listener, Clock clock) { - this.mediaItem = mediaItem; + this.editedMediaItem = editedMediaItem; this.decoderFactory = new CapturingDecoderFactory(decoderFactory); DefaultTrackSelector trackSelector = new DefaultTrackSelector(context); @@ -193,7 +155,11 @@ public final class ExoPlayerAssetLoader implements AssetLoader { new ExoPlayer.Builder( context, new RenderersFactoryImpl( - removeAudio, removeVideo, flattenForSlowMotion, this.decoderFactory, listener)) + editedMediaItem.removeAudio, + editedMediaItem.removeVideo, + editedMediaItem.flattenForSlowMotion, + this.decoderFactory, + listener)) .setMediaSourceFactory(mediaSourceFactory) .setTrackSelector(trackSelector) .setLoadControl(loadControl) @@ -212,7 +178,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader { @Override public void start() { - player.setMediaItem(mediaItem); + player.setMediaItem(editedMediaItem.mediaItem); player.prepare(); progressState = PROGRESS_STATE_WAITING_FOR_AVAILABILITY; } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java index 8583004c02..effa643ea1 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java @@ -136,11 +136,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; Looper internalLooper = internalHandlerThread.getLooper(); ComponentListener componentListener = new ComponentListener(editedMediaItem, fallbackListener); assetLoader = - assetLoaderFactory - .setRemoveAudio(editedMediaItem.removeAudio) - .setRemoveVideo(editedMediaItem.removeVideo) - .setFlattenVideoForSlowMotion(editedMediaItem.flattenForSlowMotion) - .createAssetLoader(editedMediaItem.mediaItem, internalLooper, componentListener); + assetLoaderFactory.createAssetLoader(editedMediaItem, internalLooper, componentListener); samplePipelines = new ArrayList<>(); muxerWrapper = new MuxerWrapper(outputPath, muxerFactory, componentListener); transformerConditionVariable = new ConditionVariable(); diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java index e65351111c..e3188551f5 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java @@ -117,12 +117,10 @@ public class ExoPlayerAssetLoaderTest { Looper looper, AssetLoader.Listener listener, Clock clock) { Context context = ApplicationProvider.getApplicationContext(); Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context); - MediaItem mediaItem = MediaItem.fromUri("asset:///media/mp4/sample.mp4"); + EditedMediaItem editedMediaItem = + new EditedMediaItem.Builder(MediaItem.fromUri("asset:///media/mp4/sample.mp4")).build(); return new ExoPlayerAssetLoader.Factory(context, decoderFactory, clock) - .setRemoveAudio(false) - .setRemoveVideo(false) - .setFlattenVideoForSlowMotion(false) - .createAssetLoader(mediaItem, looper, listener); + .createAssetLoader(editedMediaItem, looper, listener); } private static final class FakeSampleConsumer implements SampleConsumer { diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java index cd17185654..38a3a75c6a 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java @@ -1229,22 +1229,8 @@ public final class TransformerEndToEndTest { } @Override - public AssetLoader.Factory setRemoveAudio(boolean removeAudio) { - return this; - } - - @Override - public AssetLoader.Factory setRemoveVideo(boolean removeVideo) { - return this; - } - - @Override - public AssetLoader.Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion) { - return this; - } - - @Override - public AssetLoader createAssetLoader(MediaItem mediaItem, Looper looper, Listener listener) { + public AssetLoader createAssetLoader( + EditedMediaItem editedMediaItem, Looper looper, Listener listener) { return new FakeAssetLoader(listener, supportedOutputTypes, sampleConsumerRef); } }