diff --git a/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java b/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java index 0dcfbe0d4d..ceeb0e8f12 100644 --- a/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java +++ b/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java @@ -74,6 +74,8 @@ import androidx.media3.exoplayer.audio.SilenceSkippingAudioProcessor; import androidx.media3.exoplayer.util.DebugTextViewHelper; import androidx.media3.transformer.DefaultEncoderFactory; import androidx.media3.transformer.DefaultMuxer; +import androidx.media3.transformer.EditedMediaItem; +import androidx.media3.transformer.Effects; import androidx.media3.transformer.ProgressHolder; import androidx.media3.transformer.TransformationException; import androidx.media3.transformer.TransformationRequest; @@ -207,8 +209,9 @@ public final class TransformerActivity extends AppCompatActivity { MediaItem mediaItem = createMediaItem(bundle, uri); try { Transformer transformer = createTransformer(bundle, filePath); + EditedMediaItem editedMediaItem = createEditedMediaItem(mediaItem, bundle); transformationStopwatch.start(); - transformer.startTransformation(mediaItem, filePath); + transformer.startTransformation(editedMediaItem, filePath); this.transformer = transformer; } catch (PackageManager.NameNotFoundException e) { throw new IllegalStateException(e); @@ -265,8 +268,7 @@ public final class TransformerActivity extends AppCompatActivity { "progressViewGroup", "debugFrame", }) - private Transformer createTransformer(@Nullable Bundle bundle, String filePath) - throws PackageManager.NameNotFoundException { + private Transformer createTransformer(@Nullable Bundle bundle, String filePath) { Transformer.Builder transformerBuilder = new Transformer.Builder(/* context= */ this); if (bundle != null) { TransformationRequest.Builder requestBuilder = new TransformationRequest.Builder(); @@ -283,29 +285,6 @@ public final class TransformerActivity extends AppCompatActivity { requestBuilder.setHdrMode(bundle.getInt(ConfigurationActivity.HDR_MODE)); transformerBuilder.setTransformationRequest(requestBuilder.build()); - transformerBuilder.setAudioProcessors(createAudioProcessorsFromBundle(bundle)); - - ImmutableList.Builder effectsListBuilder = - new ImmutableList.Builder().addAll(createVideoEffectsFromBundle(bundle)); - float scaleX = bundle.getFloat(ConfigurationActivity.SCALE_X, /* defaultValue= */ 1); - float scaleY = bundle.getFloat(ConfigurationActivity.SCALE_Y, /* defaultValue= */ 1); - float rotateDegrees = - bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0); - if (scaleX != 1f || scaleY != 1f || rotateDegrees != 0f) { - effectsListBuilder.add( - new ScaleToFitTransformation.Builder() - .setScale(scaleX, scaleY) - .setRotationDegrees(rotateDegrees) - .build()); - } - int resolutionHeight = - bundle.getInt( - ConfigurationActivity.RESOLUTION_HEIGHT, /* defaultValue= */ C.LENGTH_UNSET); - if (resolutionHeight != C.LENGTH_UNSET) { - effectsListBuilder.add(Presentation.createForHeight(resolutionHeight)); - } - transformerBuilder.setVideoEffects(effectsListBuilder.build()); - transformerBuilder .setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO)) .setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO)) @@ -358,6 +337,24 @@ public final class TransformerActivity extends AppCompatActivity { return file; } + @RequiresNonNull({ + "inputCardView", + "outputPlayerView", + "transformationStopwatch", + "progressViewGroup", + }) + private EditedMediaItem createEditedMediaItem(MediaItem mediaItem, @Nullable Bundle bundle) + throws PackageManager.NameNotFoundException { + if (bundle == null) { + return new EditedMediaItem(mediaItem); + } + + ImmutableList audioProcessors = createAudioProcessorsFromBundle(bundle); + ImmutableList videoEffects = createVideoEffectsFromBundle(bundle); + Effects effects = new Effects(audioProcessors, videoEffects); + return new EditedMediaItem(mediaItem, effects); + } + private ImmutableList createAudioProcessorsFromBundle(Bundle bundle) { @Nullable boolean[] selectedAudioEffects = @@ -518,6 +515,24 @@ public final class TransformerActivity extends AppCompatActivity { effects.add(overlayEffect); } + float scaleX = bundle.getFloat(ConfigurationActivity.SCALE_X, /* defaultValue= */ 1); + float scaleY = bundle.getFloat(ConfigurationActivity.SCALE_Y, /* defaultValue= */ 1); + float rotateDegrees = + bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0); + if (scaleX != 1f || scaleY != 1f || rotateDegrees != 0f) { + effects.add( + new ScaleToFitTransformation.Builder() + .setScale(scaleX, scaleY) + .setRotationDegrees(rotateDegrees) + .build()); + } + + int resolutionHeight = + bundle.getInt(ConfigurationActivity.RESOLUTION_HEIGHT, /* defaultValue= */ C.LENGTH_UNSET); + if (resolutionHeight != C.LENGTH_UNSET) { + effects.add(Presentation.createForHeight(resolutionHeight)); + } + return effects.build(); } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java index fc030523fc..1a7a2fda34 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java @@ -183,12 +183,26 @@ public class TransformerAndroidTestRunner { * @throws Exception The cause of the transformation not completing. */ public TransformationTestResult run(String testId, MediaItem mediaItem) throws Exception { + return run(testId, new EditedMediaItem(mediaItem)); + } + + /** + * Transforms the {@link EditedMediaItem}, saving a summary of the transformation to the + * application cache. + * + * @param testId A unique identifier for the transformer test run. + * @param editedMediaItem The {@link EditedMediaItem} to transform. + * @return The {@link TransformationTestResult}. + * @throws Exception The cause of the transformation not completing. + */ + public TransformationTestResult run(String testId, EditedMediaItem editedMediaItem) + throws Exception { JSONObject resultJson = new JSONObject(); if (inputValues != null) { resultJson.put("inputValues", JSONObject.wrap(inputValues)); } try { - TransformationTestResult transformationTestResult = runInternal(testId, mediaItem); + TransformationTestResult transformationTestResult = runInternal(testId, editedMediaItem); resultJson.put("transformationResult", transformationTestResult.asJsonObject()); if (transformationTestResult.testException != null) { throw transformationTestResult.testException; @@ -208,17 +222,18 @@ public class TransformerAndroidTestRunner { } /** - * Transforms the {@link MediaItem}. + * Transforms the {@link EditedMediaItem}. * * @param testId An identifier for the test. - * @param mediaItem The {@link MediaItem} to transform. + * @param editedMediaItem The {@link EditedMediaItem} to transform. * @return The {@link TransformationTestResult}. * @throws InterruptedException If the thread is interrupted whilst waiting for transformer to * complete. * @throws IOException If an error occurs opening the output file for writing. */ - private TransformationTestResult runInternal(String testId, MediaItem mediaItem) + private TransformationTestResult runInternal(String testId, EditedMediaItem editedMediaItem) throws InterruptedException, IOException { + MediaItem mediaItem = editedMediaItem.mediaItem; if (!mediaItem.clippingConfiguration.equals(MediaItem.ClippingConfiguration.UNSET) && requestCalculateSsim) { throw new UnsupportedOperationException( @@ -293,7 +308,8 @@ public class TransformerAndroidTestRunner { .runOnMainSync( () -> { try { - testTransformer.startTransformation(mediaItem, outputVideoFile.getAbsolutePath()); + testTransformer.startTransformation( + editedMediaItem, outputVideoFile.getAbsolutePath()); // Catch all exceptions to report. Exceptions thrown here and not caught will NOT // propagate. } catch (Exception e) { diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerEndToEndTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerEndToEndTest.java index 7803dec92d..f44e1e35ce 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerEndToEndTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerEndToEndTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertThrows; import android.content.Context; import android.net.Uri; +import androidx.media3.common.Effect; import androidx.media3.common.Format; import androidx.media3.common.MediaItem; import androidx.media3.effect.Presentation; @@ -44,10 +45,13 @@ public class TransformerEndToEndTest { public void videoEditing_completesWithConsistentFrameCount() throws Exception { Transformer transformer = new Transformer.Builder(context) - .setVideoEffects(ImmutableList.of(Presentation.createForHeight(480))) .setEncoderFactory( new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build()) .build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)); + ImmutableList videoEffects = ImmutableList.of(Presentation.createForHeight(480)); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); // Result of the following command: // ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames sample.mp4 int expectedFrameCount = 30; @@ -55,9 +59,7 @@ public class TransformerEndToEndTest { TransformationTestResult result = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run( - /* testId= */ "videoEditing_completesWithConsistentFrameCount", - MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING))); + .run(/* testId= */ "videoEditing_completesWithConsistentFrameCount", editedMediaItem); assertThat(result.transformationResult.videoFrameCount).isEqualTo(expectedFrameCount); } @@ -67,18 +69,19 @@ public class TransformerEndToEndTest { Transformer transformer = new Transformer.Builder(context) .setRemoveAudio(true) - .setVideoEffects(ImmutableList.of(Presentation.createForHeight(480))) .setEncoderFactory( new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build()) .build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)); + ImmutableList videoEffects = ImmutableList.of(Presentation.createForHeight(480)); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); long expectedDurationMs = 967; TransformationTestResult result = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run( - /* testId= */ "videoOnly_completesWithConsistentDuration", - MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING))); + .run(/* testId= */ "videoOnly_completesWithConsistentDuration", editedMediaItem); assertThat(result.transformationResult.durationMs).isEqualTo(expectedDurationMs); } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java index 791eb518af..912e36755a 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/HdrEditingTest.java @@ -28,10 +28,13 @@ import android.content.Context; import android.net.Uri; import androidx.media3.common.C; import androidx.media3.common.ColorInfo; +import androidx.media3.common.Effect; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Log; import androidx.media3.common.util.Util; import androidx.media3.effect.ScaleToFitTransformation; +import androidx.media3.transformer.EditedMediaItem; +import androidx.media3.transformer.Effects; import androidx.media3.transformer.EncoderUtil; import androidx.media3.transformer.TransformationException; import androidx.media3.transformer.TransformationRequest; @@ -79,7 +82,6 @@ public class HdrEditingTest { .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); Log.i(TAG, "Transformed."); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_ST2084); - return; } catch (TransformationException exception) { Log.i(TAG, checkNotNull(exception.getCause()).toString()); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); @@ -102,7 +104,6 @@ public class HdrEditingTest { .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); Log.i(TAG, "Transformed."); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_HLG); - return; } catch (TransformationException exception) { Log.i(TAG, checkNotNull(exception.getCause()).toString()); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); @@ -121,17 +122,17 @@ public class HdrEditingTest { return; } - Transformer transformer = - new Transformer.Builder(context) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(180).build())) - .build(); + Transformer transformer = new Transformer.Builder(context).build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); TransformationTestResult transformationTestResult = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); + .run(testId, editedMediaItem); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_ST2084); } @@ -145,17 +146,17 @@ public class HdrEditingTest { return; } - Transformer transformer = - new Transformer.Builder(context) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(180).build())) - .build(); + Transformer transformer = new Transformer.Builder(context).build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); TransformationTestResult transformationTestResult = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); + .run(testId, editedMediaItem); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_HLG); } @@ -173,9 +174,6 @@ public class HdrEditingTest { AtomicBoolean isToneMappingFallbackApplied = new AtomicBoolean(); Transformer transformer = new Transformer.Builder(context) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(180).build())) .addListener( new Transformer.Listener() { @Override @@ -192,12 +190,17 @@ public class HdrEditingTest { } }) .build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); try { TransformationTestResult transformationTestResult = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); + .run(testId, editedMediaItem); Log.i(TAG, "Tone mapped."); assertThat(isToneMappingFallbackApplied.get()).isTrue(); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); @@ -209,7 +212,6 @@ public class HdrEditingTest { TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED, TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); assertThat(isFallbackListenerInvoked.get()).isFalse(); - return; } } @@ -227,9 +229,6 @@ public class HdrEditingTest { AtomicBoolean isToneMappingFallbackApplied = new AtomicBoolean(); Transformer transformer = new Transformer.Builder(context) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(180).build())) .addListener( new Transformer.Listener() { @Override @@ -246,12 +245,17 @@ public class HdrEditingTest { } }) .build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); try { TransformationTestResult transformationTestResult = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); + .run(testId, editedMediaItem); Log.i(TAG, "Tone mapped."); assertThat(isToneMappingFallbackApplied.get()).isTrue(); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/RepeatedTranscodeTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/RepeatedTranscodeTest.java index dfc2955b68..3ebb9aa1e6 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/RepeatedTranscodeTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/RepeatedTranscodeTest.java @@ -20,9 +20,12 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.content.Context; import android.net.Uri; +import androidx.media3.common.Effect; import androidx.media3.common.MediaItem; import androidx.media3.effect.ScaleToFitTransformation; import androidx.media3.transformer.AndroidTestUtil; +import androidx.media3.transformer.EditedMediaItem; +import androidx.media3.transformer.Effects; import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.TransformationTestResult; import androidx.media3.transformer.Transformer; @@ -48,20 +51,22 @@ public final class RepeatedTranscodeTest { new TransformerAndroidTestRunner.Builder( context, new Transformer.Builder(context) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(45).build())) .setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context)) .build()) .build(); + MediaItem mediaItem = + MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); Set differentOutputSizesBytes = new HashSet<>(); for (int i = 0; i < TRANSCODE_COUNT; i++) { // Use a long video in case an error occurs a while after the start of the video. TransformationTestResult testResult = transformerRunner.run( - /* testId= */ "repeatedTranscode_givesConsistentLengthOutput_" + i, - MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING))); + /* testId= */ "repeatedTranscode_givesConsistentLengthOutput_" + i, editedMediaItem); differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes)); } @@ -79,12 +84,15 @@ public final class RepeatedTranscodeTest { context, new Transformer.Builder(context) .setRemoveAudio(true) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(45).build())) .setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context)) .build()) .build(); + MediaItem mediaItem = + MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); Set differentOutputSizesBytes = new HashSet<>(); for (int i = 0; i < TRANSCODE_COUNT; i++) { @@ -92,7 +100,7 @@ public final class RepeatedTranscodeTest { TransformationTestResult testResult = transformerRunner.run( /* testId= */ "repeatedTranscodeNoAudio_givesConsistentLengthOutput_" + i, - MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING))); + editedMediaItem); differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes)); } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java index cfdfb2aafa..838970c0bf 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/ToneMapHdrToSdrUsingMediaCodecTest.java @@ -24,9 +24,12 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.net.Uri; import androidx.media3.common.C; +import androidx.media3.common.Effect; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Log; import androidx.media3.effect.ScaleToFitTransformation; +import androidx.media3.transformer.EditedMediaItem; +import androidx.media3.transformer.Effects; import androidx.media3.transformer.TransformationException; import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.TransformationTestResult; @@ -80,7 +83,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); Log.i(TAG, "Tone mapped."); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); - return; } catch (TransformationException exception) { Log.i(TAG, checkNotNull(exception.getCause()).toString()); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); @@ -88,7 +90,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { .isAnyOf( TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED, TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - return; } } @@ -125,7 +126,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); Log.i(TAG, "Tone mapped."); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); - return; } catch (TransformationException exception) { Log.i(TAG, checkNotNull(exception.getCause()).toString()); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); @@ -133,7 +133,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { .isAnyOf( TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED, TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - return; } } @@ -148,9 +147,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { new TransformationRequest.Builder() .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC) .build()) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(180).build())) .addListener( new Transformer.Listener() { @Override @@ -165,15 +161,19 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { } }) .build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); try { TransformationTestResult transformationTestResult = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); + .run(testId, editedMediaItem); Log.i(TAG, "Tone mapped."); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); - return; } catch (TransformationException exception) { Log.i(TAG, checkNotNull(exception.getCause()).toString()); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); @@ -181,7 +181,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { .isAnyOf( TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED, TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - return; } } @@ -196,9 +195,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { new TransformationRequest.Builder() .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC) .build()) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(180).build())) .addListener( new Transformer.Listener() { @Override @@ -213,15 +209,19 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { } }) .build(); + MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); try { TransformationTestResult transformationTestResult = new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); + .run(testId, editedMediaItem); Log.i(TAG, "Tone mapped."); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); - return; } catch (TransformationException exception) { Log.i(TAG, checkNotNull(exception.getCause()).toString()); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); @@ -229,7 +229,6 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { .isAnyOf( TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED, TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED); - return; } } } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/TransformationTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/TransformationTest.java index 02702c8cc4..e687c3d9d1 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/TransformationTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/TransformationTest.java @@ -26,12 +26,15 @@ import static androidx.media3.transformer.AndroidTestUtil.recordTestSkipped; import android.content.Context; import android.net.Uri; +import androidx.media3.common.Effect; import androidx.media3.common.MediaItem; import androidx.media3.common.util.Util; import androidx.media3.effect.ScaleToFitTransformation; import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil.ForceEncodeEncoderFactory; import androidx.media3.transformer.DefaultEncoderFactory; +import androidx.media3.transformer.EditedMediaItem; +import androidx.media3.transformer.Effects; import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.Transformer; import androidx.media3.transformer.TransformerAndroidTestRunner; @@ -195,17 +198,16 @@ public class TransformationTest { String testId = TAG + "_transformFrameRotation"; Context context = ApplicationProvider.getApplicationContext(); - Transformer transformer = - new Transformer.Builder(context) - .setVideoEffects( - ImmutableList.of( - new ScaleToFitTransformation.Builder().setRotationDegrees(45).build())) - .build(); + Transformer transformer = new Transformer.Builder(context).build(); + MediaItem mediaItem = + MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING)); + ImmutableList videoEffects = + ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()); + Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); new TransformerAndroidTestRunner.Builder(context, transformer) .build() - .run( - /* testId= */ testId, - MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING))); + .run(/* testId= */ testId, editedMediaItem); } } diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java index 3f88e8d4a0..9826241a2c 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java @@ -47,6 +47,7 @@ import androidx.media3.common.Effect; import androidx.media3.common.Format; import androidx.media3.common.MediaItem; import androidx.media3.common.MimeTypes; +import androidx.media3.common.audio.AudioProcessor; import androidx.media3.common.audio.SonicAudioProcessor; import androidx.media3.common.util.Util; import androidx.media3.effect.Presentation; @@ -129,9 +130,10 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_videoOnlyPassthrough_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_VIDEO_ONLY)); @@ -140,10 +142,11 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_audioOnlyPassthrough_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); + EditedMediaItem editedMediaItem = + new EditedMediaItem( + MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER)); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER); - - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -159,9 +162,11 @@ public final class TransformerEndToEndTest { .setAudioMimeType(MimeTypes.AUDIO_AAC) // supported by encoder and muxer .build()) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER); + EditedMediaItem editedMediaItem = + new EditedMediaItem( + MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -171,9 +176,10 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_audioAndVideo_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO)); @@ -193,8 +199,9 @@ public final class TransformerEndToEndTest { .setStartsAtKeyFrame(true) .build()) .build(); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -210,9 +217,10 @@ public final class TransformerEndToEndTest { .setTransformationRequest( new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build()) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_WITH_SUBTITLES); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_WITH_SUBTITLES)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_WITH_SUBTITLES)); @@ -222,15 +230,16 @@ public final class TransformerEndToEndTest { public void startTransformation_successiveTransformations_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); // Transform first media item. - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); Files.delete(Paths.get(outputPath)); // Transform second media item. - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO)); @@ -239,21 +248,24 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_concurrentTransformations_throwsError() { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); assertThrows( - IllegalStateException.class, () -> transformer.startTransformation(mediaItem, outputPath)); + IllegalStateException.class, + () -> transformer.startTransformation(editedMediaItem, outputPath)); } @Test public void startTransformation_removeAudio_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).setRemoveAudio(true).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -264,9 +276,10 @@ public final class TransformerEndToEndTest { public void startTransformation_removeVideo_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).setRemoveVideo(true).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -279,9 +292,11 @@ public final class TransformerEndToEndTest { createTransformerBuilder(/* enableFallback= */ false) .experimentalSetGenerateSilentAudio(true) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER); + EditedMediaItem editedMediaItem = + new EditedMediaItem( + MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -294,9 +309,10 @@ public final class TransformerEndToEndTest { createTransformerBuilder(/* enableFallback= */ false) .experimentalSetGenerateSilentAudio(true) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO)); @@ -309,9 +325,10 @@ public final class TransformerEndToEndTest { .experimentalSetGenerateSilentAudio(true) .setRemoveAudio(true) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -325,9 +342,10 @@ public final class TransformerEndToEndTest { .experimentalSetGenerateSilentAudio(true) .setRemoveVideo(true) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO + ".novideo")); @@ -339,9 +357,10 @@ public final class TransformerEndToEndTest { createTransformerBuilder(/* enableFallback= */ false) .experimentalSetGenerateSilentAudio(true) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -352,13 +371,13 @@ public final class TransformerEndToEndTest { public void startTransformation_adjustSampleRate_completesSuccessfully() throws Exception { SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor.setOutputSampleRateHz(48000); - Transformer transformer = - createTransformerBuilder(/* enableFallback= */ false) - .setAudioProcessors(ImmutableList.of(sonicAudioProcessor)) - .build(); + Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + ImmutableList audioProcessors = ImmutableList.of(sonicAudioProcessor); + Effects effects = new Effects(audioProcessors, /* videoEffects= */ ImmutableList.of()); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( @@ -376,14 +395,15 @@ public final class TransformerEndToEndTest { .addListener(mockListener2) .addListener(mockListener3) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, 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(eq(editedMediaItem.mediaItem), any()); + verify(mockListener2).onTransformationCompleted(eq(editedMediaItem.mediaItem), any()); + verify(mockListener3).onTransformationCompleted(eq(editedMediaItem.mediaItem), any()); } @Test @@ -399,16 +419,21 @@ public final class TransformerEndToEndTest { .setTransformationRequest( // Request transcoding so that decoder is used. new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build()) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_DECODER); + EditedMediaItem editedMediaItem = + new EditedMediaItem( + MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_DECODER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationException exception = 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(eq(editedMediaItem.mediaItem), any(), eq(exception)); + verify(mockListener2) + .onTransformationError(eq(editedMediaItem.mediaItem), any(), eq(exception)); + verify(mockListener3) + .onTransformationError(eq(editedMediaItem.mediaItem), any(), eq(exception)); } @Test @@ -426,17 +451,27 @@ public final class TransformerEndToEndTest { .addListener(mockListener2) .addListener(mockListener3) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); verify(mockListener1) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + editedMediaItem.mediaItem, + originalTransformationRequest, + fallbackTransformationRequest); verify(mockListener2) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + editedMediaItem.mediaItem, + originalTransformationRequest, + fallbackTransformationRequest); verify(mockListener3) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + editedMediaItem.mediaItem, + originalTransformationRequest, + fallbackTransformationRequest); } @Test @@ -452,14 +487,15 @@ public final class TransformerEndToEndTest { .addListener(mockListener3) .build(); Transformer transformer2 = transformer1.buildUpon().removeListener(mockListener2).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer2.startTransformation(mediaItem, outputPath); + transformer2.startTransformation(editedMediaItem, 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(eq(editedMediaItem.mediaItem), any()); + verify(mockListener2, never()).onTransformationCompleted(eq(editedMediaItem.mediaItem), any()); + verify(mockListener3).onTransformationCompleted(eq(editedMediaItem.mediaItem), any()); } @Test @@ -469,9 +505,10 @@ public final class TransformerEndToEndTest { .setTransformationRequest( new TransformationRequest.Builder().setFlattenForSlowMotion(true).build()) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_WITH_SEF_SLOW_MOTION); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_WITH_SEF_SLOW_MOTION)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_WITH_SEF_SLOW_MOTION)); @@ -480,9 +517,10 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_completesWithValidBitrate() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationResult result = TransformerTestRunner.runLooper(transformer); assertThat(result.averageAudioBitrate).isGreaterThan(0); @@ -499,9 +537,10 @@ public final class TransformerEndToEndTest { MimeTypes.AUDIO_AMR_NB) // unsupported by encoder, supported by muxer .build()) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationException exception = assertThrows( TransformationException.class, () -> TransformerTestRunner.runLooper(transformer)); @@ -519,9 +558,11 @@ public final class TransformerEndToEndTest { .setAudioMimeType(MimeTypes.AUDIO_AAC) // supported by encoder and muxer .build()) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_DECODER); + EditedMediaItem editedMediaItem = + new EditedMediaItem( + MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_DECODER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationException exception = assertThrows( TransformationException.class, () -> TransformerTestRunner.runLooper(transformer)); @@ -533,9 +574,10 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_withIoError_completesWithError() { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri("asset:///non-existing-path.mp4"); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri("asset:///non-existing-path.mp4")); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationException exception = assertThrows( TransformationException.class, () -> TransformerTestRunner.runLooper(transformer)); @@ -554,15 +596,19 @@ public final class TransformerEndToEndTest { new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build(); Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).addListener(mockListener).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback")); verify(mockListener) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + editedMediaItem.mediaItem, + originalTransformationRequest, + fallbackTransformationRequest); } @Test @@ -575,15 +621,19 @@ public final class TransformerEndToEndTest { new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build(); Transformer transformer = createTransformerBuilder(/* enableFallback= */ true).addListener(mockListener).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_MUXER)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput( context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_MUXER + ".fallback")); verify(mockListener) - .onFallbackApplied(mediaItem, originalTransformationRequest, fallbackTransformationRequest); + .onFallbackApplied( + editedMediaItem.mediaItem, + originalTransformationRequest, + fallbackTransformationRequest); } @Test @@ -600,9 +650,10 @@ public final class TransformerEndToEndTest { .setAssetLoaderFactory(assetLoaderFactory) .setMuxerFactory(muxerFactory) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationException exception = assertThrows( TransformationException.class, () -> TransformerTestRunner.runLooper(transformer)); @@ -616,9 +667,10 @@ public final class TransformerEndToEndTest { Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ C.TIME_UNSET); Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).setMuxerFactory(muxerFactory).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO)); @@ -627,14 +679,15 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_afterCancellation_completesSuccessfully() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); transformer.cancel(); Files.delete(Paths.get(outputPath)); // This would throw if the previous transformation had not been cancelled. - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationResult transformationResult = TransformerTestRunner.runLooper(transformer); // TODO(b/264974805): Make transformation output deterministic and check it against dump file. @@ -648,7 +701,8 @@ public final class TransformerEndToEndTest { Looper looper = anotherThread.getLooper(); Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).setLooper(looper).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); AtomicReference exception = new AtomicReference<>(); CountDownLatch countDownLatch = new CountDownLatch(1); @@ -656,7 +710,7 @@ public final class TransformerEndToEndTest { .post( () -> { try { - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); } catch (Exception e) { exception.set(e); @@ -673,7 +727,8 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_fromWrongThread_throwsError() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); HandlerThread anotherThread = new HandlerThread("AnotherThread"); AtomicReference illegalStateException = new AtomicReference<>(); CountDownLatch countDownLatch = new CountDownLatch(1); @@ -683,7 +738,7 @@ public final class TransformerEndToEndTest { .post( () -> { try { - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); } catch (IllegalStateException e) { illegalStateException.set(e); } finally { @@ -704,9 +759,10 @@ public final class TransformerEndToEndTest { .setAssetLoaderFactory( new FakeAssetLoader.Factory(SUPPORTED_OUTPUT_TYPE_DECODED, sampleConsumerRef)) .build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); runLooperUntil(transformer.getApplicationLooper(), () -> sampleConsumerRef.get() != null); assertThat(sampleConsumerRef.get().expectsDecodedData()).isTrue(); @@ -716,14 +772,16 @@ public final class TransformerEndToEndTest { public void startTransformation_withAssetLoaderNotDecodingAndDecodingNeeded_completesWithError() { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false) - .setAudioProcessors(ImmutableList.of(new SonicAudioProcessor())) .setAssetLoaderFactory( new FakeAssetLoader.Factory( SUPPORTED_OUTPUT_TYPE_ENCODED, /* sampleConsumerRef= */ null)) .build(); MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); + ImmutableList audioProcessors = ImmutableList.of(new SonicAudioProcessor()); + Effects effects = new Effects(audioProcessors, /* videoEffects= */ ImmutableList.of()); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformationException transformationException = assertThrows( TransformationException.class, () -> TransformerTestRunner.runLooper(transformer)); @@ -733,15 +791,17 @@ public final class TransformerEndToEndTest { @Test public void startTransformation_withNoOpEffects_transmuxes() throws Exception { + Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); int mediaItemHeightPixels = 720; - List videoEffects = new ArrayList<>(); - videoEffects.add(Presentation.createForHeight(mediaItemHeightPixels)); - videoEffects.add(new ScaleToFitTransformation.Builder().build()); - Transformer transformer = - createTransformerBuilder(/* enableFallback= */ false).setVideoEffects(videoEffects).build(); + ImmutableList videoEffects = + ImmutableList.of( + Presentation.createForHeight(mediaItemHeightPixels), + new ScaleToFitTransformation.Builder().build()); + Effects effects = new Effects(ImmutableList.of(), videoEffects); + EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); // Video transcoding in unit tests is not supported. @@ -751,7 +811,8 @@ public final class TransformerEndToEndTest { @Test public void getProgress_knownDuration_returnsConsistentStates() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); AtomicInteger previousProgressState = new AtomicInteger(PROGRESS_STATE_WAITING_FOR_AVAILABILITY); AtomicBoolean foundInconsistentState = new AtomicBoolean(); @@ -787,7 +848,7 @@ public final class TransformerEndToEndTest { } }; - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); progressHandler.sendEmptyMessage(0); TransformerTestRunner.runLooper(transformer); @@ -797,7 +858,8 @@ public final class TransformerEndToEndTest { @Test public void getProgress_knownDuration_givesIncreasingPercentages() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); List progresses = new ArrayList<>(); Handler progressHandler = new Handler(Looper.myLooper()) { @@ -816,7 +878,7 @@ public final class TransformerEndToEndTest { } }; - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); progressHandler.sendEmptyMessage(0); TransformerTestRunner.runLooper(transformer); @@ -832,10 +894,11 @@ public final class TransformerEndToEndTest { @Test public void getProgress_noCurrentTransformation_returnsNoTransformation() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); @Transformer.ProgressState int stateBeforeTransform = transformer.getProgress(progressHolder); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); @Transformer.ProgressState int stateAfterTransform = transformer.getProgress(progressHolder); @@ -846,7 +909,8 @@ public final class TransformerEndToEndTest { @Test public void getProgress_unknownDuration_returnsConsistentStates() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_UNKNOWN_DURATION); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_UNKNOWN_DURATION)); AtomicInteger previousProgressState = new AtomicInteger(PROGRESS_STATE_WAITING_FOR_AVAILABILITY); AtomicBoolean foundInconsistentState = new AtomicBoolean(); @@ -879,7 +943,7 @@ public final class TransformerEndToEndTest { } }; - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); progressHandler.sendEmptyMessage(0); TransformerTestRunner.runLooper(transformer); @@ -913,9 +977,10 @@ public final class TransformerEndToEndTest { @Test public void cancel_afterCompletion_doesNotThrow() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); - MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY); + EditedMediaItem editedMediaItem = + new EditedMediaItem(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY)); - transformer.startTransformation(mediaItem, outputPath); + transformer.startTransformation(editedMediaItem, outputPath); TransformerTestRunner.runLooper(transformer); transformer.cancel(); }