Pass a Composition to Transformer callbacks

PiperOrigin-RevId: 506304101
This commit is contained in:
kimvde 2023-02-01 14:55:33 +00:00 committed by christosts
parent b2ab4393a4
commit b8ec982ee3
8 changed files with 242 additions and 72 deletions

View File

@ -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}.
*
* <p>The default value is an empty {@link Effects} instance.
* <p>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);
}

View File

@ -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

View File

@ -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<Transformer.Listener> 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<Transformer.Listener> 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;
*
* <p>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)));
}

View File

@ -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 {
*
* <ul>
* <li>Always set to {@link C#LENGTH_UNSET} in the {@code originalTransformationRequest}
* parameter of {@link Transformer.Listener#onFallbackApplied(MediaItem,
* parameter of {@link Transformer.Listener#onFallbackApplied(Composition,
* TransformationRequest, TransformationRequest)}.
* <li>Set to {@link C#LENGTH_UNSET} in the {@code fallbackTransformationRequest} parameter of
* {@link Transformer.Listener#onFallbackApplied(MediaItem, TransformationRequest,
* {@link Transformer.Listener#onFallbackApplied(Composition, TransformationRequest,
* TransformationRequest)} to indicate that it is inferred from the input.
* </ul>
*/

View File

@ -133,8 +133,8 @@ public final class Transformer {
* Sets the {@link TransformationRequest} which configures the editing and transcoding options.
*
* <p>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}.
*
* <p>After a transformation {@linkplain Listener#onTransformationCompleted(MediaItem,
* <p>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();
}
}

View File

@ -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<Transformer.Listener> createListenerSet(

View File

@ -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<Composition> 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();

View File

@ -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);