diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/EditedMediaItem.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/EditedMediaItem.java index 4abc2f82e6..6fce04945e 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/EditedMediaItem.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/EditedMediaItem.java @@ -21,9 +21,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkState; import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor; import com.google.android.exoplayer2.source.MediaSource; -import com.google.common.collect.ImmutableList; import com.google.errorprone.annotations.CanIgnoreReturnValue; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** A {@link MediaItem} with the transformations to apply to it. */ public final class EditedMediaItem { @@ -36,7 +34,7 @@ public final class EditedMediaItem { private boolean removeAudio; private boolean removeVideo; private boolean flattenForSlowMotion; - private @MonotonicNonNull Effects effects; + private Effects effects; /** * Creates an instance. @@ -45,6 +43,7 @@ public final class EditedMediaItem { */ public Builder(MediaItem mediaItem) { this.mediaItem = mediaItem; + effects = Effects.EMPTY; } /** @@ -113,7 +112,7 @@ public final class EditedMediaItem { /** * Sets the {@link Effects} to apply to the {@link MediaItem}. * - *

The default value is an empty {@link Effects} instance. + *

The default value is {@link Effects#EMPTY}. * * @param effects The {@link Effects} to apply. * @return This builder. @@ -126,11 +125,6 @@ public final class EditedMediaItem { /** Builds an {@link EditedMediaItem} instance. */ public EditedMediaItem build() { - if (effects == null) { - effects = - new Effects( - /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of()); - } return new EditedMediaItem( mediaItem, removeAudio, removeVideo, flattenForSlowMotion, effects); } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Effects.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Effects.java index 180cb5744e..de62e336bb 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Effects.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Effects.java @@ -25,6 +25,11 @@ import com.google.common.collect.ImmutableList; /** Effects to apply to a {@link MediaItem}. */ public final class Effects { + /** An empty {@link Effects} instance. */ + public static final Effects EMPTY = + new Effects( + /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of()); + /** * The list of {@linkplain AudioProcessor audio processors} to apply to audio buffers. They are * applied in the order of the list, and buffers will only be modified by that {@link diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FallbackListener.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FallbackListener.java index 5cfa739208..e3045e2fb7 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FallbackListener.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/FallbackListener.java @@ -20,7 +20,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkState; import androidx.annotation.IntRange; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.Util; @@ -31,7 +30,7 @@ import com.google.android.exoplayer2.util.Util; */ /* package */ final class FallbackListener { - private final MediaItem mediaItem; + private final Composition composition; private final TransformationRequest originalTransformationRequest; private final ListenerSet transformerListeners; private final HandlerWrapper transformerListenerHandler; @@ -42,7 +41,7 @@ import com.google.android.exoplayer2.util.Util; /** * Creates a new instance. * - * @param mediaItem The {@link MediaItem} to transform. + * @param composition The {@link Composition} to transform. * @param transformerListeners The {@linkplain Transformer.Listener listeners} to call {@link * Transformer.Listener#onFallbackApplied} on. * @param transformerListenerHandler The {@link HandlerWrapper} to call {@link @@ -50,11 +49,11 @@ import com.google.android.exoplayer2.util.Util; * @param originalTransformationRequest The original {@link TransformationRequest}. */ public FallbackListener( - MediaItem mediaItem, + Composition composition, ListenerSet transformerListeners, HandlerWrapper transformerListenerHandler, TransformationRequest originalTransformationRequest) { - this.mediaItem = mediaItem; + this.composition = composition; this.transformerListeners = transformerListeners; this.transformerListenerHandler = transformerListenerHandler; this.originalTransformationRequest = originalTransformationRequest; @@ -79,7 +78,7 @@ import com.google.android.exoplayer2.util.Util; * *

Fallback is applied if the finalized {@code TransformationRequest} is different from the * original {@code TransformationRequest}. If fallback is applied, calls {@link - * Transformer.Listener#onFallbackApplied(MediaItem, TransformationRequest, + * Transformer.Listener#onFallbackApplied(Composition, TransformationRequest, * TransformationRequest)} once this method has been called for each track. * * @param transformationRequest The final {@link TransformationRequest} for a track. @@ -115,7 +114,7 @@ import com.google.android.exoplayer2.util.Util; /* eventFlag= */ C.INDEX_UNSET, listener -> listener.onFallbackApplied( - mediaItem, + composition, originalTransformationRequest, newFallbackTransformationRequest))); } 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 d72bdf4693..5b11fc860a 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 @@ -23,7 +23,6 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import androidx.annotation.IntDef; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -245,10 +244,10 @@ public final class TransformationRequest { * *

*/ 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 bf743ee22d..c84ce9675d 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 @@ -133,8 +133,8 @@ public final class Transformer { * Sets the {@link TransformationRequest} which configures the editing and transcoding options. * *

Actual applied values may differ, per device capabilities. {@link - * Listener#onFallbackApplied(MediaItem, TransformationRequest, TransformationRequest)} will be - * invoked with the actual applied values. + * Listener#onFallbackApplied(Composition, TransformationRequest, TransformationRequest)} will + * be invoked with the actual applied values. * * @param transformationRequest The {@link TransformationRequest}. * @return This builder. @@ -447,31 +447,42 @@ public final class Transformer { public interface Listener { /** - * @deprecated Use {@link #onTransformationCompleted(MediaItem, TransformationResult)} instead. + * @deprecated Use {@link #onTransformationCompleted(Composition, TransformationResult)} + * instead. */ @Deprecated default void onTransformationCompleted(MediaItem inputMediaItem) {} /** - * Called when the transformation is completed successfully. - * - * @param inputMediaItem The {@link MediaItem} for which the transformation is completed. - * @param result The {@link TransformationResult} of the transformation. + * @deprecated Use {@link #onTransformationCompleted(Composition, TransformationResult)} + * instead. */ + @Deprecated default void onTransformationCompleted(MediaItem inputMediaItem, TransformationResult result) { onTransformationCompleted(inputMediaItem); } /** - * @deprecated Use {@link #onTransformationError(MediaItem, TransformationResult, - * TransformationException)}. + * Called when the transformation is completed successfully. + * + * @param composition The {@link Composition} for which the transformation is completed. + * @param result The {@link TransformationResult} of the transformation. + */ + default void onTransformationCompleted(Composition composition, TransformationResult result) { + MediaItem mediaItem = composition.sequences.get(0).editedMediaItems.get(0).mediaItem; + onTransformationCompleted(mediaItem, result); + } + + /** + * @deprecated Use {@link #onTransformationError(Composition, TransformationResult, + * TransformationException)} instead. */ @Deprecated default void onTransformationError(MediaItem inputMediaItem, Exception exception) {} /** - * @deprecated Use {@link #onTransformationError(MediaItem, TransformationResult, - * TransformationException)}. + * @deprecated Use {@link #onTransformationError(Composition, TransformationResult, + * TransformationException)} instead. */ @Deprecated default void onTransformationError( @@ -480,22 +491,43 @@ public final class Transformer { } /** - * Called if an exception occurs during the transformation. - * - * @param inputMediaItem The {@link MediaItem} for which the exception occurs. - * @param result The {@link TransformationResult} of the transformation. - * @param exception The {@link TransformationException} describing the exception. + * @deprecated Use {@link #onTransformationError(Composition, TransformationResult, + * TransformationException)} instead. */ + @Deprecated default void onTransformationError( MediaItem inputMediaItem, TransformationResult result, TransformationException exception) { onTransformationError(inputMediaItem, exception); } + /** + * Called if an exception occurs during the transformation. + * + * @param composition The {@link Composition} for which the exception occurs. + * @param result The {@link TransformationResult} of the transformation. + * @param exception The {@link TransformationException} describing the exception. + */ + default void onTransformationError( + Composition composition, TransformationResult result, TransformationException exception) { + MediaItem mediaItem = composition.sequences.get(0).editedMediaItems.get(0).mediaItem; + onTransformationError(mediaItem, result, exception); + } + + /** + * @deprecated Use {@link #onFallbackApplied(Composition, TransformationRequest, + * TransformationRequest)} instead. + */ + @Deprecated + default void onFallbackApplied( + MediaItem inputMediaItem, + TransformationRequest originalTransformationRequest, + TransformationRequest fallbackTransformationRequest) {} + /** * Called when falling back to an alternative {@link TransformationRequest} or changing the * video frames' resolution is necessary to comply with muxer or device constraints. * - * @param inputMediaItem The {@link MediaItem} for which the transformation is requested. + * @param composition The {@link Composition} for which the transformation is requested. * @param originalTransformationRequest The unsupported {@link TransformationRequest} used when * building {@link Transformer}. * @param fallbackTransformationRequest The alternative {@link TransformationRequest}, with @@ -504,9 +536,12 @@ public final class Transformer { * {@link TransformationRequest#hdrMode} values set. */ default void onFallbackApplied( - MediaItem inputMediaItem, + Composition composition, TransformationRequest originalTransformationRequest, - TransformationRequest fallbackTransformationRequest) {} + TransformationRequest fallbackTransformationRequest) { + MediaItem mediaItem = composition.sequences.get(0).editedMediaItems.get(0).mediaItem; + onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + } } /** @@ -715,12 +750,14 @@ public final class Transformer { if (transformerInternal != null) { throw new IllegalStateException("There is already a transformation in progress."); } + EditedMediaItemSequence sequence = + new EditedMediaItemSequence(ImmutableList.of(editedMediaItem)); + Composition composition = new Composition(ImmutableList.of(sequence), Effects.EMPTY); TransformerInternalListener transformerInternalListener = - new TransformerInternalListener(editedMediaItem.mediaItem); + new TransformerInternalListener(composition); HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null); FallbackListener fallbackListener = - new FallbackListener( - editedMediaItem.mediaItem, listeners, applicationHandler, transformationRequest); + new FallbackListener(composition, listeners, applicationHandler, transformationRequest); transformerInternal = new TransformerInternal( context, @@ -751,7 +788,7 @@ public final class Transformer { * Returns the current {@link ProgressState} and updates {@code progressHolder} with the current * progress if it is {@link #PROGRESS_STATE_AVAILABLE available}. * - *

After a transformation {@linkplain Listener#onTransformationCompleted(MediaItem, + *

After a transformation {@linkplain Listener#onTransformationCompleted(Composition, * TransformationResult) completes}, this method returns {@link #PROGRESS_STATE_NOT_STARTED}. * * @param progressHolder A {@link ProgressHolder}, updated to hold the percentage progress if @@ -791,10 +828,10 @@ public final class Transformer { private final class TransformerInternalListener implements TransformerInternal.Listener { - private final MediaItem mediaItem; + private final Composition composition; - public TransformerInternalListener(MediaItem mediaItem) { - this.mediaItem = mediaItem; + public TransformerInternalListener(Composition composition) { + this.composition = composition; } @Override @@ -803,7 +840,7 @@ public final class Transformer { transformerInternal = null; listeners.queueEvent( /* eventFlag= */ C.INDEX_UNSET, - listener -> listener.onTransformationCompleted(mediaItem, transformationResult)); + listener -> listener.onTransformationCompleted(composition, transformationResult)); listeners.flushEvents(); } @@ -813,7 +850,7 @@ public final class Transformer { transformerInternal = null; listeners.queueEvent( /* eventFlag= */ C.INDEX_UNSET, - listener -> listener.onTransformationError(mediaItem, result, exception)); + listener -> listener.onTransformationError(composition, result, exception)); listeners.flushEvents(); } } diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/FallbackListenerTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/FallbackListenerTest.java index f622d09561..510dc9d1cd 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/FallbackListenerTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/FallbackListenerTest.java @@ -29,6 +29,7 @@ import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.ListenerSet; import com.google.android.exoplayer2.util.MimeTypes; +import com.google.common.collect.ImmutableList; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.shadows.ShadowLooper; @@ -37,14 +38,20 @@ import org.robolectric.shadows.ShadowLooper; @RunWith(AndroidJUnit4.class) public class FallbackListenerTest { - private static final MediaItem PLACEHOLDER_MEDIA_ITEM = MediaItem.fromUri(Uri.EMPTY); + private static final Composition PLACEHOLDER_COMPOSITION = + new Composition( + ImmutableList.of( + new EditedMediaItemSequence( + ImmutableList.of( + new EditedMediaItem.Builder(MediaItem.fromUri(Uri.EMPTY)).build()))), + Effects.EMPTY); @Test public void onTransformationRequestFinalized_withoutTrackCountSet_throwsException() { TransformationRequest transformationRequest = new TransformationRequest.Builder().build(); FallbackListener fallbackListener = new FallbackListener( - PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest); + PLACEHOLDER_COMPOSITION, createListenerSet(), createHandler(), transformationRequest); assertThrows( IllegalStateException.class, @@ -56,7 +63,7 @@ public class FallbackListenerTest { TransformationRequest transformationRequest = new TransformationRequest.Builder().build(); FallbackListener fallbackListener = new FallbackListener( - PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest); + PLACEHOLDER_COMPOSITION, createListenerSet(), createHandler(), transformationRequest); fallbackListener.setTrackCount(1); fallbackListener.onTransformationRequestFinalized(transformationRequest); @@ -71,7 +78,7 @@ public class FallbackListenerTest { Transformer.Listener mockListener = mock(Transformer.Listener.class); FallbackListener fallbackListener = new FallbackListener( - PLACEHOLDER_MEDIA_ITEM, + PLACEHOLDER_COMPOSITION, createListenerSet(mockListener), createHandler(), originalRequest); @@ -80,7 +87,7 @@ public class FallbackListenerTest { fallbackListener.onTransformationRequestFinalized(unchangedRequest); ShadowLooper.idleMainLooper(); - verify(mockListener, never()).onFallbackApplied(any(), any(), any()); + verify(mockListener, never()).onFallbackApplied(any(Composition.class), any(), any()); } @Test @@ -92,7 +99,7 @@ public class FallbackListenerTest { Transformer.Listener mockListener = mock(Transformer.Listener.class); FallbackListener fallbackListener = new FallbackListener( - PLACEHOLDER_MEDIA_ITEM, + PLACEHOLDER_COMPOSITION, createListenerSet(mockListener), createHandler(), originalRequest); @@ -102,7 +109,7 @@ public class FallbackListenerTest { ShadowLooper.idleMainLooper(); verify(mockListener) - .onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, audioFallbackRequest); + .onFallbackApplied(PLACEHOLDER_COMPOSITION, originalRequest, audioFallbackRequest); } @Test @@ -122,7 +129,7 @@ public class FallbackListenerTest { Transformer.Listener mockListener = mock(Transformer.Listener.class); FallbackListener fallbackListener = new FallbackListener( - PLACEHOLDER_MEDIA_ITEM, + PLACEHOLDER_COMPOSITION, createListenerSet(mockListener), createHandler(), originalRequest); @@ -133,7 +140,7 @@ public class FallbackListenerTest { ShadowLooper.idleMainLooper(); verify(mockListener) - .onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, mergedFallbackRequest); + .onFallbackApplied(PLACEHOLDER_COMPOSITION, originalRequest, mergedFallbackRequest); } private static ListenerSet createListenerSet( 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 59c33b065d..731d299e5d 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 @@ -83,6 +83,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.robolectric.shadows.MediaCodecInfoBuilder; import org.robolectric.shadows.ShadowMediaCodec; import org.robolectric.shadows.ShadowMediaCodecList; @@ -110,6 +111,7 @@ public final class TransformerEndToEndTest { private TestMuxer testMuxer; private FakeClock clock; private ProgressHolder progressHolder; + private ArgumentCaptor compositionArgumentCaptor; @Before public void setUp() throws Exception { @@ -117,6 +119,7 @@ public final class TransformerEndToEndTest { outputPath = Util.createTempFile(context, "TransformerTest").getPath(); clock = new FakeClock(/* isAutoAdvancing= */ true); progressHolder = new ProgressHolder(); + compositionArgumentCaptor = ArgumentCaptor.forClass(Composition.class); createEncodersAndDecoders(); } @@ -389,9 +392,10 @@ public final class TransformerEndToEndTest { transformer.startTransformation(mediaItem, outputPath); TransformerTestRunner.runLooper(transformer); - verify(mockListener1).onTransformationCompleted(eq(mediaItem), any()); - verify(mockListener2).onTransformationCompleted(eq(mediaItem), any()); - verify(mockListener3).onTransformationCompleted(eq(mediaItem), any()); + verify(mockListener1).onTransformationCompleted(compositionArgumentCaptor.capture(), any()); + Composition composition = compositionArgumentCaptor.getValue(); + verify(mockListener2).onTransformationCompleted(eq(composition), any()); + verify(mockListener3).onTransformationCompleted(eq(composition), any()); } @Test @@ -414,9 +418,11 @@ public final class TransformerEndToEndTest { assertThrows( TransformationException.class, () -> TransformerTestRunner.runLooper(transformer)); - verify(mockListener1).onTransformationError(eq(mediaItem), any(), eq(exception)); - verify(mockListener2).onTransformationError(eq(mediaItem), any(), eq(exception)); - verify(mockListener3).onTransformationError(eq(mediaItem), any(), eq(exception)); + verify(mockListener1) + .onTransformationError(compositionArgumentCaptor.capture(), any(), eq(exception)); + Composition composition = compositionArgumentCaptor.getValue(); + verify(mockListener2).onTransformationError(eq(composition), any(), eq(exception)); + verify(mockListener3).onTransformationError(eq(composition), any(), eq(exception)); } @Test @@ -440,11 +446,119 @@ public final class TransformerEndToEndTest { TransformerTestRunner.runLooper(transformer); verify(mockListener1) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + compositionArgumentCaptor.capture(), + eq(originalTransformationRequest), + eq(fallbackTransformationRequest)); + Composition composition = compositionArgumentCaptor.getValue(); verify(mockListener2) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + composition, originalTransformationRequest, fallbackTransformationRequest); verify(mockListener3) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + composition, originalTransformationRequest, fallbackTransformationRequest); + } + + @Test + public void startTransformation_success_callsDeprecatedCompletionCallbacks() throws Exception { + AtomicBoolean deprecatedFallbackCalled1 = new AtomicBoolean(); + AtomicBoolean deprecatedFallbackCalled2 = new AtomicBoolean(); + Transformer transformer = + createTransformerBuilder(/* enableFallback= */ false) + .addListener( + new Transformer.Listener() { + @Override + public void onTransformationCompleted(MediaItem inputMediaItem) { + deprecatedFallbackCalled1.set(true); + } + }) + .addListener( + new Transformer.Listener() { + @Override + public void onTransformationCompleted( + MediaItem inputMediaItem, TransformationResult result) { + deprecatedFallbackCalled2.set(true); + } + }) + .build(); + MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + + transformer.startTransformation(mediaItem, outputPath); + TransformerTestRunner.runLooper(transformer); + + assertThat(deprecatedFallbackCalled1.get()).isTrue(); + assertThat(deprecatedFallbackCalled2.get()).isTrue(); + } + + @Test + public void startTransformation_withError_callsDeprecatedErrorCallbacks() throws Exception { + AtomicBoolean deprecatedFallbackCalled1 = new AtomicBoolean(); + AtomicBoolean deprecatedFallbackCalled2 = new AtomicBoolean(); + AtomicBoolean deprecatedFallbackCalled3 = new AtomicBoolean(); + Transformer transformer = + createTransformerBuilder(/* enableFallback= */ false) + .addListener( + new Transformer.Listener() { + @Override + public void onTransformationError(MediaItem inputMediaItem, Exception exception) { + deprecatedFallbackCalled1.set(true); + } + }) + .addListener( + new Transformer.Listener() { + @Override + public void onTransformationError( + MediaItem inputMediaItem, TransformationException exception) { + deprecatedFallbackCalled2.set(true); + } + }) + .addListener( + new Transformer.Listener() { + @Override + public void onTransformationError( + MediaItem inputMediaItem, + TransformationResult result, + TransformationException exception) { + deprecatedFallbackCalled3.set(true); + } + }) + .build(); + MediaItem mediaItem = MediaItem.fromUri("invalid.uri"); + + transformer.startTransformation(mediaItem, outputPath); + try { + TransformerTestRunner.runLooper(transformer); + } catch (TransformationException transformationException) { + // Ignore exception thrown. + } + + assertThat(deprecatedFallbackCalled1.get()).isTrue(); + assertThat(deprecatedFallbackCalled2.get()).isTrue(); + assertThat(deprecatedFallbackCalled3.get()).isTrue(); + } + + @Test + public void startTransformation_withFallback_callsDeprecatedFallbackCallbacks() throws Exception { + AtomicBoolean deprecatedFallbackCalled = new AtomicBoolean(); + Transformer transformer = + createTransformerBuilder(/* enableFallback= */ true) + .addListener( + new Transformer.Listener() { + @Override + public void onFallbackApplied( + MediaItem inputMediaItem, + TransformationRequest originalTransformationRequest, + TransformationRequest fallbackTransformationRequest) { + deprecatedFallbackCalled.set(true); + } + }) + .build(); + MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER); + + transformer.startTransformation(mediaItem, outputPath); + TransformerTestRunner.runLooper(transformer); + + assertThat(deprecatedFallbackCalled.get()).isTrue(); } @Test @@ -465,9 +579,10 @@ public final class TransformerEndToEndTest { transformer2.startTransformation(mediaItem, outputPath); TransformerTestRunner.runLooper(transformer2); - verify(mockListener1).onTransformationCompleted(eq(mediaItem), any()); - verify(mockListener2, never()).onTransformationCompleted(eq(mediaItem), any()); - verify(mockListener3).onTransformationCompleted(eq(mediaItem), any()); + verify(mockListener1).onTransformationCompleted(compositionArgumentCaptor.capture(), any()); + verify(mockListener2, never()).onTransformationCompleted(any(Composition.class), any()); + verify(mockListener3) + .onTransformationCompleted(eq(compositionArgumentCaptor.getValue()), any()); } @Test @@ -569,7 +684,10 @@ public final class TransformerEndToEndTest { DumpFileAsserts.assertOutput( context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback")); verify(mockListener) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + any(Composition.class), + eq(originalTransformationRequest), + eq(fallbackTransformationRequest)); } @Test @@ -590,7 +708,10 @@ public final class TransformerEndToEndTest { DumpFileAsserts.assertOutput( context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback")); verify(mockListener) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + any(Composition.class), + eq(originalTransformationRequest), + eq(fallbackTransformationRequest)); } @Test @@ -750,7 +871,7 @@ public final class TransformerEndToEndTest { ImmutableList.of( Presentation.createForHeight(mediaItemHeightPixels), new ScaleToFitTransformation.Builder().build()); - Effects effects = new Effects(ImmutableList.of(), videoEffects); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).setEffects(effects).build(); diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/VideoEncoderWrapperTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/VideoEncoderWrapperTest.java index db17b5815f..063ae36e4e 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/VideoEncoderWrapperTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/VideoEncoderWrapperTest.java @@ -43,12 +43,20 @@ import org.robolectric.shadows.ShadowMediaCodecList; /** Unit tests for {@link VideoSamplePipeline.EncoderWrapper}. */ @RunWith(AndroidJUnit4.class) public final class VideoEncoderWrapperTest { + private static final Composition FAKE_COMPOSITION = + new Composition( + ImmutableList.of( + new EditedMediaItemSequence( + ImmutableList.of( + new EditedMediaItem.Builder(MediaItem.fromUri(Uri.EMPTY)).build()))), + Effects.EMPTY); + private final TransformationRequest emptyTransformationRequest = new TransformationRequest.Builder().build(); private final FakeVideoEncoderFactory fakeEncoderFactory = new FakeVideoEncoderFactory(); private final FallbackListener fallbackListener = new FallbackListener( - MediaItem.fromUri(Uri.EMPTY), + FAKE_COMPOSITION, new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {}), Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null), emptyTransformationRequest);