Pass a Composition to Transformer callbacks
PiperOrigin-RevId: 506304101
This commit is contained in:
parent
b2ab4393a4
commit
b8ec982ee3
@ -21,9 +21,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkState;
|
|||||||
import com.google.android.exoplayer2.MediaItem;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|
||||||
|
|
||||||
/** A {@link MediaItem} with the transformations to apply to it. */
|
/** A {@link MediaItem} with the transformations to apply to it. */
|
||||||
public final class EditedMediaItem {
|
public final class EditedMediaItem {
|
||||||
@ -36,7 +34,7 @@ public final class EditedMediaItem {
|
|||||||
private boolean removeAudio;
|
private boolean removeAudio;
|
||||||
private boolean removeVideo;
|
private boolean removeVideo;
|
||||||
private boolean flattenForSlowMotion;
|
private boolean flattenForSlowMotion;
|
||||||
private @MonotonicNonNull Effects effects;
|
private Effects effects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates an instance.
|
||||||
@ -45,6 +43,7 @@ public final class EditedMediaItem {
|
|||||||
*/
|
*/
|
||||||
public Builder(MediaItem mediaItem) {
|
public Builder(MediaItem mediaItem) {
|
||||||
this.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}.
|
* 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.
|
* @param effects The {@link Effects} to apply.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
@ -126,11 +125,6 @@ public final class EditedMediaItem {
|
|||||||
|
|
||||||
/** Builds an {@link EditedMediaItem} instance. */
|
/** Builds an {@link EditedMediaItem} instance. */
|
||||||
public EditedMediaItem build() {
|
public EditedMediaItem build() {
|
||||||
if (effects == null) {
|
|
||||||
effects =
|
|
||||||
new Effects(
|
|
||||||
/* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of());
|
|
||||||
}
|
|
||||||
return new EditedMediaItem(
|
return new EditedMediaItem(
|
||||||
mediaItem, removeAudio, removeVideo, flattenForSlowMotion, effects);
|
mediaItem, removeAudio, removeVideo, flattenForSlowMotion, effects);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,11 @@ import com.google.common.collect.ImmutableList;
|
|||||||
/** Effects to apply to a {@link MediaItem}. */
|
/** Effects to apply to a {@link MediaItem}. */
|
||||||
public final class Effects {
|
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
|
* 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
|
* applied in the order of the list, and buffers will only be modified by that {@link
|
||||||
|
@ -20,7 +20,6 @@ import static com.google.android.exoplayer2.util.Assertions.checkState;
|
|||||||
|
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import com.google.android.exoplayer2.C;
|
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.HandlerWrapper;
|
||||||
import com.google.android.exoplayer2.util.ListenerSet;
|
import com.google.android.exoplayer2.util.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
@ -31,7 +30,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
*/
|
*/
|
||||||
/* package */ final class FallbackListener {
|
/* package */ final class FallbackListener {
|
||||||
|
|
||||||
private final MediaItem mediaItem;
|
private final Composition composition;
|
||||||
private final TransformationRequest originalTransformationRequest;
|
private final TransformationRequest originalTransformationRequest;
|
||||||
private final ListenerSet<Transformer.Listener> transformerListeners;
|
private final ListenerSet<Transformer.Listener> transformerListeners;
|
||||||
private final HandlerWrapper transformerListenerHandler;
|
private final HandlerWrapper transformerListenerHandler;
|
||||||
@ -42,7 +41,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* 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
|
* @param transformerListeners The {@linkplain Transformer.Listener listeners} to call {@link
|
||||||
* Transformer.Listener#onFallbackApplied} on.
|
* Transformer.Listener#onFallbackApplied} on.
|
||||||
* @param transformerListenerHandler The {@link HandlerWrapper} to call {@link
|
* @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}.
|
* @param originalTransformationRequest The original {@link TransformationRequest}.
|
||||||
*/
|
*/
|
||||||
public FallbackListener(
|
public FallbackListener(
|
||||||
MediaItem mediaItem,
|
Composition composition,
|
||||||
ListenerSet<Transformer.Listener> transformerListeners,
|
ListenerSet<Transformer.Listener> transformerListeners,
|
||||||
HandlerWrapper transformerListenerHandler,
|
HandlerWrapper transformerListenerHandler,
|
||||||
TransformationRequest originalTransformationRequest) {
|
TransformationRequest originalTransformationRequest) {
|
||||||
this.mediaItem = mediaItem;
|
this.composition = composition;
|
||||||
this.transformerListeners = transformerListeners;
|
this.transformerListeners = transformerListeners;
|
||||||
this.transformerListenerHandler = transformerListenerHandler;
|
this.transformerListenerHandler = transformerListenerHandler;
|
||||||
this.originalTransformationRequest = originalTransformationRequest;
|
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
|
* <p>Fallback is applied if the finalized {@code TransformationRequest} is different from the
|
||||||
* original {@code TransformationRequest}. If fallback is applied, calls {@link
|
* 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.
|
* TransformationRequest)} once this method has been called for each track.
|
||||||
*
|
*
|
||||||
* @param transformationRequest The final {@link TransformationRequest} for a 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,
|
/* eventFlag= */ C.INDEX_UNSET,
|
||||||
listener ->
|
listener ->
|
||||||
listener.onFallbackApplied(
|
listener.onFallbackApplied(
|
||||||
mediaItem,
|
composition,
|
||||||
originalTransformationRequest,
|
originalTransformationRequest,
|
||||||
newFallbackTransformationRequest)));
|
newFallbackTransformationRequest)));
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
|
|||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
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.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
@ -245,10 +244,10 @@ public final class TransformationRequest {
|
|||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Always set to {@link C#LENGTH_UNSET} in the {@code originalTransformationRequest}
|
* <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)}.
|
* TransformationRequest, TransformationRequest)}.
|
||||||
* <li>Set to {@link C#LENGTH_UNSET} in the {@code fallbackTransformationRequest} parameter of
|
* <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.
|
* TransformationRequest)} to indicate that it is inferred from the input.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
|
@ -133,8 +133,8 @@ public final class Transformer {
|
|||||||
* Sets the {@link TransformationRequest} which configures the editing and transcoding options.
|
* Sets the {@link TransformationRequest} which configures the editing and transcoding options.
|
||||||
*
|
*
|
||||||
* <p>Actual applied values may differ, per device capabilities. {@link
|
* <p>Actual applied values may differ, per device capabilities. {@link
|
||||||
* Listener#onFallbackApplied(MediaItem, TransformationRequest, TransformationRequest)} will be
|
* Listener#onFallbackApplied(Composition, TransformationRequest, TransformationRequest)} will
|
||||||
* invoked with the actual applied values.
|
* be invoked with the actual applied values.
|
||||||
*
|
*
|
||||||
* @param transformationRequest The {@link TransformationRequest}.
|
* @param transformationRequest The {@link TransformationRequest}.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
@ -447,31 +447,42 @@ public final class Transformer {
|
|||||||
public interface Listener {
|
public interface Listener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #onTransformationCompleted(MediaItem, TransformationResult)} instead.
|
* @deprecated Use {@link #onTransformationCompleted(Composition, TransformationResult)}
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default void onTransformationCompleted(MediaItem inputMediaItem) {}
|
default void onTransformationCompleted(MediaItem inputMediaItem) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the transformation is completed successfully.
|
* @deprecated Use {@link #onTransformationCompleted(Composition, TransformationResult)}
|
||||||
*
|
* instead.
|
||||||
* @param inputMediaItem The {@link MediaItem} for which the transformation is completed.
|
|
||||||
* @param result The {@link TransformationResult} of the transformation.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
default void onTransformationCompleted(MediaItem inputMediaItem, TransformationResult result) {
|
default void onTransformationCompleted(MediaItem inputMediaItem, TransformationResult result) {
|
||||||
onTransformationCompleted(inputMediaItem);
|
onTransformationCompleted(inputMediaItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #onTransformationError(MediaItem, TransformationResult,
|
* Called when the transformation is completed successfully.
|
||||||
* TransformationException)}.
|
*
|
||||||
|
* @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
|
@Deprecated
|
||||||
default void onTransformationError(MediaItem inputMediaItem, Exception exception) {}
|
default void onTransformationError(MediaItem inputMediaItem, Exception exception) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #onTransformationError(MediaItem, TransformationResult,
|
* @deprecated Use {@link #onTransformationError(Composition, TransformationResult,
|
||||||
* TransformationException)}.
|
* TransformationException)} instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default void onTransformationError(
|
default void onTransformationError(
|
||||||
@ -480,22 +491,43 @@ public final class Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called if an exception occurs during the transformation.
|
* @deprecated Use {@link #onTransformationError(Composition, TransformationResult,
|
||||||
*
|
* TransformationException)} instead.
|
||||||
* @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
|
||||||
default void onTransformationError(
|
default void onTransformationError(
|
||||||
MediaItem inputMediaItem, TransformationResult result, TransformationException exception) {
|
MediaItem inputMediaItem, TransformationResult result, TransformationException exception) {
|
||||||
onTransformationError(inputMediaItem, 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
|
* Called when falling back to an alternative {@link TransformationRequest} or changing the
|
||||||
* video frames' resolution is necessary to comply with muxer or device constraints.
|
* 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
|
* @param originalTransformationRequest The unsupported {@link TransformationRequest} used when
|
||||||
* building {@link Transformer}.
|
* building {@link Transformer}.
|
||||||
* @param fallbackTransformationRequest The alternative {@link TransformationRequest}, with
|
* @param fallbackTransformationRequest The alternative {@link TransformationRequest}, with
|
||||||
@ -504,9 +536,12 @@ public final class Transformer {
|
|||||||
* {@link TransformationRequest#hdrMode} values set.
|
* {@link TransformationRequest#hdrMode} values set.
|
||||||
*/
|
*/
|
||||||
default void onFallbackApplied(
|
default void onFallbackApplied(
|
||||||
MediaItem inputMediaItem,
|
Composition composition,
|
||||||
TransformationRequest originalTransformationRequest,
|
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) {
|
if (transformerInternal != null) {
|
||||||
throw new IllegalStateException("There is already a transformation in progress.");
|
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 =
|
TransformerInternalListener transformerInternalListener =
|
||||||
new TransformerInternalListener(editedMediaItem.mediaItem);
|
new TransformerInternalListener(composition);
|
||||||
HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null);
|
HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(composition, listeners, applicationHandler, transformationRequest);
|
||||||
editedMediaItem.mediaItem, listeners, applicationHandler, transformationRequest);
|
|
||||||
transformerInternal =
|
transformerInternal =
|
||||||
new TransformerInternal(
|
new TransformerInternal(
|
||||||
context,
|
context,
|
||||||
@ -751,7 +788,7 @@ public final class Transformer {
|
|||||||
* Returns the current {@link ProgressState} and updates {@code progressHolder} with the current
|
* Returns the current {@link ProgressState} and updates {@code progressHolder} with the current
|
||||||
* progress if it is {@link #PROGRESS_STATE_AVAILABLE available}.
|
* 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}.
|
* TransformationResult) completes}, this method returns {@link #PROGRESS_STATE_NOT_STARTED}.
|
||||||
*
|
*
|
||||||
* @param progressHolder A {@link ProgressHolder}, updated to hold the percentage progress if
|
* @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 class TransformerInternalListener implements TransformerInternal.Listener {
|
||||||
|
|
||||||
private final MediaItem mediaItem;
|
private final Composition composition;
|
||||||
|
|
||||||
public TransformerInternalListener(MediaItem mediaItem) {
|
public TransformerInternalListener(Composition composition) {
|
||||||
this.mediaItem = mediaItem;
|
this.composition = composition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -803,7 +840,7 @@ public final class Transformer {
|
|||||||
transformerInternal = null;
|
transformerInternal = null;
|
||||||
listeners.queueEvent(
|
listeners.queueEvent(
|
||||||
/* eventFlag= */ C.INDEX_UNSET,
|
/* eventFlag= */ C.INDEX_UNSET,
|
||||||
listener -> listener.onTransformationCompleted(mediaItem, transformationResult));
|
listener -> listener.onTransformationCompleted(composition, transformationResult));
|
||||||
listeners.flushEvents();
|
listeners.flushEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -813,7 +850,7 @@ public final class Transformer {
|
|||||||
transformerInternal = null;
|
transformerInternal = null;
|
||||||
listeners.queueEvent(
|
listeners.queueEvent(
|
||||||
/* eventFlag= */ C.INDEX_UNSET,
|
/* eventFlag= */ C.INDEX_UNSET,
|
||||||
listener -> listener.onTransformationError(mediaItem, result, exception));
|
listener -> listener.onTransformationError(composition, result, exception));
|
||||||
listeners.flushEvents();
|
listeners.flushEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer2.util.Clock;
|
|||||||
import com.google.android.exoplayer2.util.HandlerWrapper;
|
import com.google.android.exoplayer2.util.HandlerWrapper;
|
||||||
import com.google.android.exoplayer2.util.ListenerSet;
|
import com.google.android.exoplayer2.util.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.shadows.ShadowLooper;
|
import org.robolectric.shadows.ShadowLooper;
|
||||||
@ -37,14 +38,20 @@ import org.robolectric.shadows.ShadowLooper;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class FallbackListenerTest {
|
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
|
@Test
|
||||||
public void onTransformationRequestFinalized_withoutTrackCountSet_throwsException() {
|
public void onTransformationRequestFinalized_withoutTrackCountSet_throwsException() {
|
||||||
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest);
|
PLACEHOLDER_COMPOSITION, createListenerSet(), createHandler(), transformationRequest);
|
||||||
|
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
@ -56,7 +63,7 @@ public class FallbackListenerTest {
|
|||||||
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest);
|
PLACEHOLDER_COMPOSITION, createListenerSet(), createHandler(), transformationRequest);
|
||||||
|
|
||||||
fallbackListener.setTrackCount(1);
|
fallbackListener.setTrackCount(1);
|
||||||
fallbackListener.onTransformationRequestFinalized(transformationRequest);
|
fallbackListener.onTransformationRequestFinalized(transformationRequest);
|
||||||
@ -71,7 +78,7 @@ public class FallbackListenerTest {
|
|||||||
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM,
|
PLACEHOLDER_COMPOSITION,
|
||||||
createListenerSet(mockListener),
|
createListenerSet(mockListener),
|
||||||
createHandler(),
|
createHandler(),
|
||||||
originalRequest);
|
originalRequest);
|
||||||
@ -80,7 +87,7 @@ public class FallbackListenerTest {
|
|||||||
fallbackListener.onTransformationRequestFinalized(unchangedRequest);
|
fallbackListener.onTransformationRequestFinalized(unchangedRequest);
|
||||||
ShadowLooper.idleMainLooper();
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
verify(mockListener, never()).onFallbackApplied(any(), any(), any());
|
verify(mockListener, never()).onFallbackApplied(any(Composition.class), any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -92,7 +99,7 @@ public class FallbackListenerTest {
|
|||||||
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM,
|
PLACEHOLDER_COMPOSITION,
|
||||||
createListenerSet(mockListener),
|
createListenerSet(mockListener),
|
||||||
createHandler(),
|
createHandler(),
|
||||||
originalRequest);
|
originalRequest);
|
||||||
@ -102,7 +109,7 @@ public class FallbackListenerTest {
|
|||||||
ShadowLooper.idleMainLooper();
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
verify(mockListener)
|
verify(mockListener)
|
||||||
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, audioFallbackRequest);
|
.onFallbackApplied(PLACEHOLDER_COMPOSITION, originalRequest, audioFallbackRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -122,7 +129,7 @@ public class FallbackListenerTest {
|
|||||||
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM,
|
PLACEHOLDER_COMPOSITION,
|
||||||
createListenerSet(mockListener),
|
createListenerSet(mockListener),
|
||||||
createHandler(),
|
createHandler(),
|
||||||
originalRequest);
|
originalRequest);
|
||||||
@ -133,7 +140,7 @@ public class FallbackListenerTest {
|
|||||||
ShadowLooper.idleMainLooper();
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
verify(mockListener)
|
verify(mockListener)
|
||||||
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, mergedFallbackRequest);
|
.onFallbackApplied(PLACEHOLDER_COMPOSITION, originalRequest, mergedFallbackRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ListenerSet<Transformer.Listener> createListenerSet(
|
private static ListenerSet<Transformer.Listener> createListenerSet(
|
||||||
|
@ -83,6 +83,7 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.robolectric.shadows.MediaCodecInfoBuilder;
|
import org.robolectric.shadows.MediaCodecInfoBuilder;
|
||||||
import org.robolectric.shadows.ShadowMediaCodec;
|
import org.robolectric.shadows.ShadowMediaCodec;
|
||||||
import org.robolectric.shadows.ShadowMediaCodecList;
|
import org.robolectric.shadows.ShadowMediaCodecList;
|
||||||
@ -110,6 +111,7 @@ public final class TransformerEndToEndTest {
|
|||||||
private TestMuxer testMuxer;
|
private TestMuxer testMuxer;
|
||||||
private FakeClock clock;
|
private FakeClock clock;
|
||||||
private ProgressHolder progressHolder;
|
private ProgressHolder progressHolder;
|
||||||
|
private ArgumentCaptor<Composition> compositionArgumentCaptor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@ -117,6 +119,7 @@ public final class TransformerEndToEndTest {
|
|||||||
outputPath = Util.createTempFile(context, "TransformerTest").getPath();
|
outputPath = Util.createTempFile(context, "TransformerTest").getPath();
|
||||||
clock = new FakeClock(/* isAutoAdvancing= */ true);
|
clock = new FakeClock(/* isAutoAdvancing= */ true);
|
||||||
progressHolder = new ProgressHolder();
|
progressHolder = new ProgressHolder();
|
||||||
|
compositionArgumentCaptor = ArgumentCaptor.forClass(Composition.class);
|
||||||
createEncodersAndDecoders();
|
createEncodersAndDecoders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,9 +392,10 @@ public final class TransformerEndToEndTest {
|
|||||||
transformer.startTransformation(mediaItem, outputPath);
|
transformer.startTransformation(mediaItem, outputPath);
|
||||||
TransformerTestRunner.runLooper(transformer);
|
TransformerTestRunner.runLooper(transformer);
|
||||||
|
|
||||||
verify(mockListener1).onTransformationCompleted(eq(mediaItem), any());
|
verify(mockListener1).onTransformationCompleted(compositionArgumentCaptor.capture(), any());
|
||||||
verify(mockListener2).onTransformationCompleted(eq(mediaItem), any());
|
Composition composition = compositionArgumentCaptor.getValue();
|
||||||
verify(mockListener3).onTransformationCompleted(eq(mediaItem), any());
|
verify(mockListener2).onTransformationCompleted(eq(composition), any());
|
||||||
|
verify(mockListener3).onTransformationCompleted(eq(composition), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -414,9 +418,11 @@ public final class TransformerEndToEndTest {
|
|||||||
assertThrows(
|
assertThrows(
|
||||||
TransformationException.class, () -> TransformerTestRunner.runLooper(transformer));
|
TransformationException.class, () -> TransformerTestRunner.runLooper(transformer));
|
||||||
|
|
||||||
verify(mockListener1).onTransformationError(eq(mediaItem), any(), eq(exception));
|
verify(mockListener1)
|
||||||
verify(mockListener2).onTransformationError(eq(mediaItem), any(), eq(exception));
|
.onTransformationError(compositionArgumentCaptor.capture(), any(), eq(exception));
|
||||||
verify(mockListener3).onTransformationError(eq(mediaItem), any(), eq(exception));
|
Composition composition = compositionArgumentCaptor.getValue();
|
||||||
|
verify(mockListener2).onTransformationError(eq(composition), any(), eq(exception));
|
||||||
|
verify(mockListener3).onTransformationError(eq(composition), any(), eq(exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -440,11 +446,119 @@ public final class TransformerEndToEndTest {
|
|||||||
TransformerTestRunner.runLooper(transformer);
|
TransformerTestRunner.runLooper(transformer);
|
||||||
|
|
||||||
verify(mockListener1)
|
verify(mockListener1)
|
||||||
.onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest);
|
.onFallbackApplied(
|
||||||
|
compositionArgumentCaptor.capture(),
|
||||||
|
eq(originalTransformationRequest),
|
||||||
|
eq(fallbackTransformationRequest));
|
||||||
|
Composition composition = compositionArgumentCaptor.getValue();
|
||||||
verify(mockListener2)
|
verify(mockListener2)
|
||||||
.onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest);
|
.onFallbackApplied(
|
||||||
|
composition, originalTransformationRequest, fallbackTransformationRequest);
|
||||||
verify(mockListener3)
|
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
|
@Test
|
||||||
@ -465,9 +579,10 @@ public final class TransformerEndToEndTest {
|
|||||||
transformer2.startTransformation(mediaItem, outputPath);
|
transformer2.startTransformation(mediaItem, outputPath);
|
||||||
TransformerTestRunner.runLooper(transformer2);
|
TransformerTestRunner.runLooper(transformer2);
|
||||||
|
|
||||||
verify(mockListener1).onTransformationCompleted(eq(mediaItem), any());
|
verify(mockListener1).onTransformationCompleted(compositionArgumentCaptor.capture(), any());
|
||||||
verify(mockListener2, never()).onTransformationCompleted(eq(mediaItem), any());
|
verify(mockListener2, never()).onTransformationCompleted(any(Composition.class), any());
|
||||||
verify(mockListener3).onTransformationCompleted(eq(mediaItem), any());
|
verify(mockListener3)
|
||||||
|
.onTransformationCompleted(eq(compositionArgumentCaptor.getValue()), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -569,7 +684,10 @@ public final class TransformerEndToEndTest {
|
|||||||
DumpFileAsserts.assertOutput(
|
DumpFileAsserts.assertOutput(
|
||||||
context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback"));
|
context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback"));
|
||||||
verify(mockListener)
|
verify(mockListener)
|
||||||
.onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest);
|
.onFallbackApplied(
|
||||||
|
any(Composition.class),
|
||||||
|
eq(originalTransformationRequest),
|
||||||
|
eq(fallbackTransformationRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -590,7 +708,10 @@ public final class TransformerEndToEndTest {
|
|||||||
DumpFileAsserts.assertOutput(
|
DumpFileAsserts.assertOutput(
|
||||||
context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback"));
|
context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback"));
|
||||||
verify(mockListener)
|
verify(mockListener)
|
||||||
.onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest);
|
.onFallbackApplied(
|
||||||
|
any(Composition.class),
|
||||||
|
eq(originalTransformationRequest),
|
||||||
|
eq(fallbackTransformationRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -750,7 +871,7 @@ public final class TransformerEndToEndTest {
|
|||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
Presentation.createForHeight(mediaItemHeightPixels),
|
Presentation.createForHeight(mediaItemHeightPixels),
|
||||||
new ScaleToFitTransformation.Builder().build());
|
new ScaleToFitTransformation.Builder().build());
|
||||||
Effects effects = new Effects(ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
|
|
||||||
|
@ -43,12 +43,20 @@ import org.robolectric.shadows.ShadowMediaCodecList;
|
|||||||
/** Unit tests for {@link VideoSamplePipeline.EncoderWrapper}. */
|
/** Unit tests for {@link VideoSamplePipeline.EncoderWrapper}. */
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public final class VideoEncoderWrapperTest {
|
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 =
|
private final TransformationRequest emptyTransformationRequest =
|
||||||
new TransformationRequest.Builder().build();
|
new TransformationRequest.Builder().build();
|
||||||
private final FakeVideoEncoderFactory fakeEncoderFactory = new FakeVideoEncoderFactory();
|
private final FakeVideoEncoderFactory fakeEncoderFactory = new FakeVideoEncoderFactory();
|
||||||
private final FallbackListener fallbackListener =
|
private final FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
MediaItem.fromUri(Uri.EMPTY),
|
FAKE_COMPOSITION,
|
||||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {}),
|
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {}),
|
||||||
Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null),
|
Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null),
|
||||||
emptyTransformationRequest);
|
emptyTransformationRequest);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user