Commit e8ffc7b6 by kimvde Committed by christosts

Move removeAudio/Video to EditedMediaItem

Also add a Builder to EditedMediaItem to avoid having a constructor with
many optional parameters, or a chain of constructors.

PiperOrigin-RevId: 504588544
parent 50beec56
Showing with 300 additions and 134 deletions
...@@ -286,8 +286,6 @@ public final class TransformerActivity extends AppCompatActivity { ...@@ -286,8 +286,6 @@ public final class TransformerActivity extends AppCompatActivity {
transformerBuilder.setTransformationRequest(requestBuilder.build()); transformerBuilder.setTransformationRequest(requestBuilder.build());
transformerBuilder transformerBuilder
.setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO))
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO))
.experimentalSetGenerateSilentAudio( .experimentalSetGenerateSilentAudio(
bundle.getBoolean(ConfigurationActivity.GENERATE_SILENT_AUDIO)) bundle.getBoolean(ConfigurationActivity.GENERATE_SILENT_AUDIO))
.setEncoderFactory( .setEncoderFactory(
...@@ -345,14 +343,17 @@ public final class TransformerActivity extends AppCompatActivity { ...@@ -345,14 +343,17 @@ public final class TransformerActivity extends AppCompatActivity {
}) })
private EditedMediaItem createEditedMediaItem(MediaItem mediaItem, @Nullable Bundle bundle) private EditedMediaItem createEditedMediaItem(MediaItem mediaItem, @Nullable Bundle bundle)
throws PackageManager.NameNotFoundException { throws PackageManager.NameNotFoundException {
EditedMediaItem.Builder editedMediaItemBuilder = new EditedMediaItem.Builder(mediaItem);
if (bundle == null) { if (bundle == null) {
return new EditedMediaItem(mediaItem); return editedMediaItemBuilder.build();
} }
ImmutableList<AudioProcessor> audioProcessors = createAudioProcessorsFromBundle(bundle); ImmutableList<AudioProcessor> audioProcessors = createAudioProcessorsFromBundle(bundle);
ImmutableList<Effect> videoEffects = createVideoEffectsFromBundle(bundle); ImmutableList<Effect> videoEffects = createVideoEffectsFromBundle(bundle);
Effects effects = new Effects(audioProcessors, videoEffects); return editedMediaItemBuilder
return new EditedMediaItem(mediaItem, effects); .setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO))
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO))
.setEffects(new Effects(audioProcessors, videoEffects))
.build();
} }
private ImmutableList<AudioProcessor> createAudioProcessorsFromBundle(Bundle bundle) { private ImmutableList<AudioProcessor> createAudioProcessorsFromBundle(Bundle bundle) {
......
...@@ -174,19 +174,6 @@ public class TransformerAndroidTestRunner { ...@@ -174,19 +174,6 @@ public class TransformerAndroidTestRunner {
} }
/** /**
* Transforms the {@link MediaItem}, saving a summary of the transformation to the application
* cache.
*
* @param testId A unique identifier for the transformer test run.
* @param mediaItem The {@link MediaItem} to transform.
* @return The {@link TransformationTestResult}.
* @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 * Transforms the {@link EditedMediaItem}, saving a summary of the transformation to the
* application cache. * application cache.
* *
......
...@@ -51,7 +51,8 @@ public class TransformerEndToEndTest { ...@@ -51,7 +51,8 @@ public class TransformerEndToEndTest {
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING));
ImmutableList<Effect> videoEffects = ImmutableList.of(Presentation.createForHeight(480)); ImmutableList<Effect> videoEffects = ImmutableList.of(Presentation.createForHeight(480));
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
// Result of the following command: // Result of the following command:
// ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames sample.mp4 // ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames sample.mp4
int expectedFrameCount = 30; int expectedFrameCount = 30;
...@@ -68,14 +69,14 @@ public class TransformerEndToEndTest { ...@@ -68,14 +69,14 @@ public class TransformerEndToEndTest {
public void videoOnly_completesWithConsistentDuration() throws Exception { public void videoOnly_completesWithConsistentDuration() throws Exception {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveAudio(true)
.setEncoderFactory( .setEncoderFactory(
new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build()) new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build())
.build(); .build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)); MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING));
ImmutableList<Effect> videoEffects = ImmutableList.of(Presentation.createForHeight(480)); ImmutableList<Effect> videoEffects = ImmutableList.of(Presentation.createForHeight(480));
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).setEffects(effects).build();
long expectedDurationMs = 967; long expectedDurationMs = 967;
TransformationTestResult result = TransformationTestResult result =
...@@ -100,11 +101,12 @@ public class TransformerEndToEndTest { ...@@ -100,11 +101,12 @@ public class TransformerEndToEndTest {
.setEndPositionMs(clippingEndMs) .setEndPositionMs(clippingEndMs)
.build()) .build())
.build(); .build();
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
TransformationTestResult result = TransformationTestResult result =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(/* testId= */ "clippedMedia_completesWithClippedDuration", mediaItem); .run(/* testId= */ "clippedMedia_completesWithClippedDuration", editedMediaItem);
assertThat(result.transformationResult.durationMs).isAtMost(clippingEndMs - clippingStartMs); assertThat(result.transformationResult.durationMs).isAtMost(clippingEndMs - clippingStartMs);
} }
...@@ -114,6 +116,9 @@ public class TransformerEndToEndTest { ...@@ -114,6 +116,9 @@ public class TransformerEndToEndTest {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setEncoderFactory(new VideoUnsupportedEncoderFactory(context)) .setEncoderFactory(new VideoUnsupportedEncoderFactory(context))
.build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)))
.setRemoveAudio(true) .setRemoveAudio(true)
.build(); .build();
...@@ -125,7 +130,7 @@ public class TransformerEndToEndTest { ...@@ -125,7 +130,7 @@ public class TransformerEndToEndTest {
.build() .build()
.run( .run(
/* testId= */ "videoEncoderFormatUnsupported_completesWithError", /* testId= */ "videoEncoderFormatUnsupported_completesWithError",
MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)))); editedMediaItem));
assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class); assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
assertThat(exception.errorCode) assertThat(exception.errorCode)
......
...@@ -27,6 +27,7 @@ import androidx.media3.common.C; ...@@ -27,6 +27,7 @@ import androidx.media3.common.C;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.TransformationException; import androidx.media3.transformer.TransformationException;
import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult; import androidx.media3.transformer.TransformationTestResult;
...@@ -67,11 +68,14 @@ public class ForceInterpretHdrVideoAsSdrTest { ...@@ -67,11 +68,14 @@ public class ForceInterpretHdrVideoAsSdrTest {
TransformationRequest.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR) TransformationRequest.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR)
.build()) .build())
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); .run(testId, editedMediaItem);
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR);
Log.i(TAG, "Transformed."); Log.i(TAG, "Transformed.");
} catch (TransformationException exception) { } catch (TransformationException exception) {
...@@ -103,11 +107,14 @@ public class ForceInterpretHdrVideoAsSdrTest { ...@@ -103,11 +107,14 @@ public class ForceInterpretHdrVideoAsSdrTest {
TransformationRequest.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR) TransformationRequest.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR)
.build()) .build())
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); .run(testId, editedMediaItem);
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR);
Log.i(TAG, "Transformed."); Log.i(TAG, "Transformed.");
} catch (TransformationException exception) { } catch (TransformationException exception) {
......
...@@ -74,12 +74,15 @@ public class HdrEditingTest { ...@@ -74,12 +74,15 @@ public class HdrEditingTest {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).build(); Transformer transformer = new Transformer.Builder(context).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); .run(testId, editedMediaItem);
Log.i(TAG, "Transformed."); Log.i(TAG, "Transformed.");
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_ST2084); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_ST2084);
} catch (TransformationException exception) { } catch (TransformationException exception) {
...@@ -96,12 +99,15 @@ public class HdrEditingTest { ...@@ -96,12 +99,15 @@ public class HdrEditingTest {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).build(); Transformer transformer = new Transformer.Builder(context).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); .run(testId, editedMediaItem);
Log.i(TAG, "Transformed."); Log.i(TAG, "Transformed.");
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_HLG); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_HLG);
} catch (TransformationException exception) { } catch (TransformationException exception) {
...@@ -127,7 +133,8 @@ public class HdrEditingTest { ...@@ -127,7 +133,8 @@ public class HdrEditingTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
...@@ -151,7 +158,8 @@ public class HdrEditingTest { ...@@ -151,7 +158,8 @@ public class HdrEditingTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
...@@ -194,7 +202,8 @@ public class HdrEditingTest { ...@@ -194,7 +202,8 @@ public class HdrEditingTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
...@@ -249,7 +258,8 @@ public class HdrEditingTest { ...@@ -249,7 +258,8 @@ public class HdrEditingTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
...@@ -283,11 +293,12 @@ public class HdrEditingTest { ...@@ -283,11 +293,12 @@ public class HdrEditingTest {
} }
Transformer transformer = new Transformer.Builder(context).build(); Transformer transformer = new Transformer.Builder(context).build();
MediaItem mediaItem =
MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_1_SECOND_HDR10_VIDEO_SDR_CONTAINER));
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run( .run(testId, editedMediaItem);
testId,
MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_1_SECOND_HDR10_VIDEO_SDR_CONTAINER)));
} }
private static boolean deviceSupportsHdrEditing(String mimeType, ColorInfo colorInfo) { private static boolean deviceSupportsHdrEditing(String mimeType, ColorInfo colorInfo) {
......
...@@ -59,7 +59,8 @@ public final class RepeatedTranscodeTest { ...@@ -59,7 +59,8 @@ public final class RepeatedTranscodeTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
Set<Long> differentOutputSizesBytes = new HashSet<>(); Set<Long> differentOutputSizesBytes = new HashSet<>();
for (int i = 0; i < TRANSCODE_COUNT; i++) { for (int i = 0; i < TRANSCODE_COUNT; i++) {
...@@ -83,7 +84,6 @@ public final class RepeatedTranscodeTest { ...@@ -83,7 +84,6 @@ public final class RepeatedTranscodeTest {
new TransformerAndroidTestRunner.Builder( new TransformerAndroidTestRunner.Builder(
context, context,
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveAudio(true)
.setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context)) .setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context))
.build()) .build())
.build(); .build();
...@@ -92,7 +92,8 @@ public final class RepeatedTranscodeTest { ...@@ -92,7 +92,8 @@ public final class RepeatedTranscodeTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).setEffects(effects).build();
Set<Long> differentOutputSizesBytes = new HashSet<>(); Set<Long> differentOutputSizesBytes = new HashSet<>();
for (int i = 0; i < TRANSCODE_COUNT; i++) { for (int i = 0; i < TRANSCODE_COUNT; i++) {
...@@ -117,11 +118,14 @@ public final class RepeatedTranscodeTest { ...@@ -117,11 +118,14 @@ public final class RepeatedTranscodeTest {
new TransformerAndroidTestRunner.Builder( new TransformerAndroidTestRunner.Builder(
context, context,
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveVideo(true)
.setTransformationRequest(new TransformationRequest.Builder().build()) .setTransformationRequest(new TransformationRequest.Builder().build())
.setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context)) .setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context))
.build()) .build())
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveVideo(true).build();
Set<Long> differentOutputSizesBytes = new HashSet<>(); Set<Long> differentOutputSizesBytes = new HashSet<>();
for (int i = 0; i < TRANSCODE_COUNT; i++) { for (int i = 0; i < TRANSCODE_COUNT; i++) {
...@@ -129,7 +133,7 @@ public final class RepeatedTranscodeTest { ...@@ -129,7 +133,7 @@ public final class RepeatedTranscodeTest {
TransformationTestResult testResult = TransformationTestResult testResult =
transformerRunner.run( transformerRunner.run(
/* testId= */ "repeatedTranscodeNoVideo_givesConsistentLengthOutput_" + i, /* testId= */ "repeatedTranscodeNoVideo_givesConsistentLengthOutput_" + i,
MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING))); editedMediaItem);
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes)); differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
} }
......
...@@ -75,12 +75,15 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { ...@@ -75,12 +75,15 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
} }
}) })
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); .run(testId, editedMediaItem);
Log.i(TAG, "Tone mapped."); Log.i(TAG, "Tone mapped.");
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR);
} catch (TransformationException exception) { } catch (TransformationException exception) {
...@@ -118,12 +121,15 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { ...@@ -118,12 +121,15 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
} }
}) })
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); .run(testId, editedMediaItem);
Log.i(TAG, "Tone mapped."); Log.i(TAG, "Tone mapped.");
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR);
} catch (TransformationException exception) { } catch (TransformationException exception) {
...@@ -165,7 +171,8 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { ...@@ -165,7 +171,8 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
...@@ -213,7 +220,8 @@ public class ToneMapHdrToSdrUsingMediaCodecTest { ...@@ -213,7 +220,8 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
......
...@@ -32,6 +32,7 @@ import androidx.media3.common.util.GlUtil; ...@@ -32,6 +32,7 @@ import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.TransformationException; import androidx.media3.transformer.TransformationException;
import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult; import androidx.media3.transformer.TransformationTestResult;
...@@ -85,11 +86,14 @@ public class ToneMapHdrToSdrUsingOpenGlTest { ...@@ -85,11 +86,14 @@ public class ToneMapHdrToSdrUsingOpenGlTest {
.setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL) .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL)
.build()) .build())
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10))); .run(testId, editedMediaItem);
Log.i(TAG, "Tone mapped."); Log.i(TAG, "Tone mapped.");
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR);
} catch (TransformationException exception) { } catch (TransformationException exception) {
...@@ -135,11 +139,14 @@ public class ToneMapHdrToSdrUsingOpenGlTest { ...@@ -135,11 +139,14 @@ public class ToneMapHdrToSdrUsingOpenGlTest {
.setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL) .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL)
.build()) .build())
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10)))
.build();
try { try {
TransformationTestResult transformationTestResult = TransformationTestResult transformationTestResult =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10))); .run(testId, editedMediaItem);
Log.i(TAG, "Tone mapped."); Log.i(TAG, "Tone mapped.");
assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR); assertFileHasColorTransfer(transformationTestResult.filePath, C.COLOR_TRANSFER_SDR);
} catch (TransformationException exception) { } catch (TransformationException exception) {
......
...@@ -24,6 +24,7 @@ import androidx.media3.common.MediaItem; ...@@ -24,6 +24,7 @@ import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes; import androidx.media3.common.MimeTypes;
import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.DefaultEncoderFactory; import androidx.media3.transformer.DefaultEncoderFactory;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult; import androidx.media3.transformer.TransformationTestResult;
import androidx.media3.transformer.Transformer; import androidx.media3.transformer.Transformer;
...@@ -62,17 +63,18 @@ public final class TranscodeQualityTest { ...@@ -62,17 +63,18 @@ public final class TranscodeQualityTest {
.experimentalSetEnableHighQualityTargeting(true) .experimentalSetEnableHighQualityTargeting(true)
.build()) .build())
.build()) .build())
.setRemoveAudio(true)
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(
Uri.parse(AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
TransformationTestResult result = TransformationTestResult result =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run( .run(testId, editedMediaItem);
testId,
MediaItem.fromUri(
Uri.parse(AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING)));
if (result.ssim != TransformationTestResult.SSIM_UNSET) { if (result.ssim != TransformationTestResult.SSIM_UNSET) {
assertThat(result.ssim).isGreaterThan(0.90); assertThat(result.ssim).isGreaterThan(0.90);
...@@ -99,17 +101,18 @@ public final class TranscodeQualityTest { ...@@ -99,17 +101,18 @@ public final class TranscodeQualityTest {
new Transformer.Builder(context) new Transformer.Builder(context)
.setTransformationRequest( .setTransformationRequest(
new TransformationRequest.Builder().setVideoMimeType(MimeTypes.VIDEO_H265).build()) new TransformationRequest.Builder().setVideoMimeType(MimeTypes.VIDEO_H265).build())
.setRemoveAudio(true)
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(
Uri.parse(AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
TransformationTestResult result = TransformationTestResult result =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run( .run(testId, editedMediaItem);
testId,
MediaItem.fromUri(
Uri.parse(AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING)));
if (result.ssim != TransformationTestResult.SSIM_UNSET) { if (result.ssim != TransformationTestResult.SSIM_UNSET) {
assertThat(result.ssim).isGreaterThan(0.90); assertThat(result.ssim).isGreaterThan(0.90);
...@@ -129,19 +132,19 @@ public final class TranscodeQualityTest { ...@@ -129,19 +132,19 @@ public final class TranscodeQualityTest {
.setTransformationRequest( .setTransformationRequest(
new TransformationRequest.Builder().setVideoMimeType(MimeTypes.VIDEO_H264).build()) new TransformationRequest.Builder().setVideoMimeType(MimeTypes.VIDEO_H264).build())
.setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context)) .setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context))
.setRemoveAudio(true)
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(
Uri.parse(
AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_320W_240H_15S_URI_STRING));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
TransformationTestResult result = TransformationTestResult result =
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run( .run(testId, editedMediaItem);
testId,
MediaItem.fromUri(
Uri.parse(
AndroidTestUtil
.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_320W_240H_15S_URI_STRING)));
if (result.ssim != TransformationTestResult.SSIM_UNSET) { if (result.ssim != TransformationTestResult.SSIM_UNSET) {
assertThat(result.ssim).isGreaterThan(0.90); assertThat(result.ssim).isGreaterThan(0.90);
......
...@@ -59,10 +59,13 @@ public class TransformationTest { ...@@ -59,10 +59,13 @@ public class TransformationTest {
new Transformer.Builder(context) new Transformer.Builder(context)
.setEncoderFactory(new ForceEncodeEncoderFactory(context)) .setEncoderFactory(new ForceEncodeEncoderFactory(context))
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -70,10 +73,13 @@ public class TransformationTest { ...@@ -70,10 +73,13 @@ public class TransformationTest {
String testId = TAG + "_transformWithoutDecodeEncode"; String testId = TAG + "_transformWithoutDecodeEncode";
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).build(); Transformer transformer = new Transformer.Builder(context).build();
MediaItem mediaItem =
MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
// No need to calculate SSIM because no decode/encoding, so input frames match output frames. // No need to calculate SSIM because no decode/encoding, so input frames match output frames.
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -82,7 +88,6 @@ public class TransformationTest { ...@@ -82,7 +88,6 @@ public class TransformationTest {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveAudio(true)
.setEncoderFactory( .setEncoderFactory(
new ForceEncodeEncoderFactory( new ForceEncodeEncoderFactory(
/* wrappedEncoderFactory= */ new DefaultEncoderFactory.Builder(context) /* wrappedEncoderFactory= */ new DefaultEncoderFactory.Builder(context)
...@@ -90,10 +95,14 @@ public class TransformationTest { ...@@ -90,10 +95,14 @@ public class TransformationTest {
new VideoEncoderSettings.Builder().setBitrate(5_000_000).build()) new VideoEncoderSettings.Builder().setBitrate(5_000_000).build())
.build())) .build()))
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -113,11 +122,13 @@ public class TransformationTest { ...@@ -113,11 +122,13 @@ public class TransformationTest {
new Transformer.Builder(context) new Transformer.Builder(context)
.setEncoderFactory(new ForceEncodeEncoderFactory(context)) .setEncoderFactory(new ForceEncodeEncoderFactory(context))
.build(); .build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_REMOTE_4K60_PORTRAIT_URI_STRING));
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.setTimeoutSeconds(180) .setTimeoutSeconds(180)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_REMOTE_4K60_PORTRAIT_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -136,11 +147,14 @@ public class TransformationTest { ...@@ -136,11 +147,14 @@ public class TransformationTest {
new Transformer.Builder(context) new Transformer.Builder(context)
.setEncoderFactory(new ForceEncodeEncoderFactory(context)) .setEncoderFactory(new ForceEncodeEncoderFactory(context))
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_REMOTE_8K24_URI_STRING)))
.build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.setTimeoutSeconds(180) .setTimeoutSeconds(180)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_REMOTE_8K24_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -150,12 +164,15 @@ public class TransformationTest { ...@@ -150,12 +164,15 @@ public class TransformationTest {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setEncoderFactory(new ForceEncodeEncoderFactory(context)) .setEncoderFactory(new ForceEncodeEncoderFactory(context))
.setRemoveAudio(true)
.build(); .build();
MediaItem mediaItem =
MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -165,11 +182,14 @@ public class TransformationTest { ...@@ -165,11 +182,14 @@ public class TransformationTest {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setEncoderFactory(new ForceEncodeEncoderFactory(context)) .setEncoderFactory(new ForceEncodeEncoderFactory(context))
.build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING)))
.setRemoveVideo(true) .setRemoveVideo(true)
.build(); .build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -188,9 +208,11 @@ public class TransformationTest { ...@@ -188,9 +208,11 @@ public class TransformationTest {
.setTransformationRequest( .setTransformationRequest(
new TransformationRequest.Builder().setFlattenForSlowMotion(true).build()) new TransformationRequest.Builder().setFlattenForSlowMotion(true).build())
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(MP4_ASSET_SEF_URI_STRING))).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(MP4_ASSET_SEF_URI_STRING))); .run(testId, editedMediaItem);
} }
@Test @Test
...@@ -204,7 +226,8 @@ public class TransformationTest { ...@@ -204,7 +226,8 @@ public class TransformationTest {
ImmutableList<Effect> videoEffects = ImmutableList<Effect> videoEffects =
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()); ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build());
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects); Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
EditedMediaItem editedMediaItem = new EditedMediaItem(mediaItem, effects); EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.build() .build()
......
...@@ -42,6 +42,7 @@ import androidx.media3.common.MediaItem; ...@@ -42,6 +42,7 @@ import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.DefaultEncoderFactory; import androidx.media3.transformer.DefaultEncoderFactory;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.Transformer; import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner; import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.media3.transformer.VideoEncoderSettings; import androidx.media3.transformer.VideoEncoderSettings;
...@@ -142,7 +143,6 @@ public class BitrateAnalysisTest { ...@@ -142,7 +143,6 @@ public class BitrateAnalysisTest {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveAudio(true)
.setEncoderFactory( .setEncoderFactory(
new AndroidTestUtil.ForceEncodeEncoderFactory( new AndroidTestUtil.ForceEncodeEncoderFactory(
/* wrappedEncoderFactory= */ new DefaultEncoderFactory.Builder(context) /* wrappedEncoderFactory= */ new DefaultEncoderFactory.Builder(context)
...@@ -154,11 +154,15 @@ public class BitrateAnalysisTest { ...@@ -154,11 +154,15 @@ public class BitrateAnalysisTest {
.setEnableFallback(false) .setEnableFallback(false)
.build())) .build()))
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(fileUri)))
.setRemoveAudio(true)
.build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setInputValues(inputValues) .setInputValues(inputValues)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(fileUri))); .run(testId, editedMediaItem);
} }
} }
...@@ -27,6 +27,7 @@ import androidx.media3.common.MediaItem; ...@@ -27,6 +27,7 @@ import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.DefaultEncoderFactory; import androidx.media3.transformer.DefaultEncoderFactory;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.Transformer; import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner; import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.media3.transformer.VideoEncoderSettings; import androidx.media3.transformer.VideoEncoderSettings;
...@@ -118,7 +119,6 @@ public class EncoderPerformanceAnalysisTest { ...@@ -118,7 +119,6 @@ public class EncoderPerformanceAnalysisTest {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveAudio(true)
.setEncoderFactory( .setEncoderFactory(
new AndroidTestUtil.ForceEncodeEncoderFactory( new AndroidTestUtil.ForceEncodeEncoderFactory(
/* wrappedEncoderFactory= */ new DefaultEncoderFactory.Builder(context) /* wrappedEncoderFactory= */ new DefaultEncoderFactory.Builder(context)
...@@ -129,10 +129,14 @@ public class EncoderPerformanceAnalysisTest { ...@@ -129,10 +129,14 @@ public class EncoderPerformanceAnalysisTest {
.setEnableFallback(false) .setEnableFallback(false)
.build())) .build()))
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(fileUri)))
.setRemoveAudio(true)
.build();
new TransformerAndroidTestRunner.Builder(context, transformer) new TransformerAndroidTestRunner.Builder(context, transformer)
.setInputValues(inputValues) .setInputValues(inputValues)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(fileUri))); .run(testId, editedMediaItem);
} }
} }
...@@ -55,6 +55,7 @@ import androidx.media3.common.MimeTypes; ...@@ -55,6 +55,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.transformer.AndroidTestUtil; import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.DefaultEncoderFactory; import androidx.media3.transformer.DefaultEncoderFactory;
import androidx.media3.transformer.EditedMediaItem;
import androidx.media3.transformer.TransformationRequest; import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.Transformer; import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner; import androidx.media3.transformer.TransformerAndroidTestRunner;
...@@ -287,7 +288,6 @@ public class SsimMapperTest { ...@@ -287,7 +288,6 @@ public class SsimMapperTest {
Transformer transformer = Transformer transformer =
new Transformer.Builder(context) new Transformer.Builder(context)
.setRemoveAudio(true)
.setTransformationRequest( .setTransformationRequest(
new TransformationRequest.Builder().setVideoMimeType(outputMimeType).build()) new TransformationRequest.Builder().setVideoMimeType(outputMimeType).build())
.setEncoderFactory( .setEncoderFactory(
...@@ -300,6 +300,10 @@ public class SsimMapperTest { ...@@ -300,6 +300,10 @@ public class SsimMapperTest {
.setEnableFallback(false) .setEnableFallback(false)
.build()) .build())
.build(); .build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.parse(videoUri)))
.setRemoveAudio(true)
.build();
transformationsLeft--; transformationsLeft--;
...@@ -308,7 +312,7 @@ public class SsimMapperTest { ...@@ -308,7 +312,7 @@ public class SsimMapperTest {
.setInputValues(inputValues) .setInputValues(inputValues)
.setRequestCalculateSsim(true) .setRequestCalculateSsim(true)
.build() .build()
.run(testId, MediaItem.fromUri(Uri.parse(videoUri))) .run(testId, editedMediaItem)
.ssim; .ssim;
checkState(ssim != SSIM_UNSET, "SSIM has not been calculated."); checkState(ssim != SSIM_UNSET, "SSIM has not been calculated.");
......
...@@ -15,34 +15,106 @@ ...@@ -15,34 +15,106 @@
*/ */
package androidx.media3.transformer; package androidx.media3.transformer;
import static androidx.media3.common.util.Assertions.checkState;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** A {@link MediaItem} with the transformations to apply to it. */ /** A {@link MediaItem} with the transformations to apply to it. */
@UnstableApi @UnstableApi
public class EditedMediaItem { public class EditedMediaItem {
/* package */ final MediaItem mediaItem; /** A builder for {@link EditedMediaItem} instances. */
/* package */ final Effects effects; public static final class Builder {
private final MediaItem mediaItem;
private boolean removeAudio;
private boolean removeVideo;
private @MonotonicNonNull Effects effects;
/**
* Creates an instance.
*
* @param mediaItem The {@link MediaItem} on which transformations are applied.
*/
public Builder(MediaItem mediaItem) {
this.mediaItem = mediaItem;
}
/** /**
* Creates an instance with no {@link Effects}. * Sets whether to remove the audio from the {@link MediaItem}.
* *
* @param mediaItem The {@link MediaItem} to edit. * <p>The default value is {@code false}.
*/ *
public EditedMediaItem(MediaItem mediaItem) { * <p>The audio and video cannot both be removed because the output would not contain any
this(mediaItem, new Effects(ImmutableList.of(), ImmutableList.of())); * samples.
*
* @param removeAudio Whether to remove the audio.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setRemoveAudio(boolean removeAudio) {
this.removeAudio = removeAudio;
return this;
}
/**
* Sets whether to remove the video from the {@link MediaItem}.
*
* <p>The default value is {@code false}.
*
* <p>The audio and video cannot both be removed because the output would not contain any
* samples.
*
* @param removeVideo Whether to remove the video.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setRemoveVideo(boolean removeVideo) {
this.removeVideo = removeVideo;
return this;
}
/**
* Sets the {@link Effects} to apply to the {@link MediaItem}.
*
* <p>The default value is an empty {@link Effects} instance.
*
* @param effects The {@link Effects} to apply.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setEffects(Effects effects) {
this.effects = effects;
return this;
}
/** Builds an {@link EditedMediaItem} instance. */
public EditedMediaItem build() {
if (effects == null) {
effects =
new Effects(
/* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of());
}
return new EditedMediaItem(mediaItem, removeAudio, removeVideo, effects);
}
} }
/** /* package */ final MediaItem mediaItem;
* Creates an instance. /* package */ final boolean removeAudio;
* /* package */ final boolean removeVideo;
* @param mediaItem The {@link MediaItem} to edit. /* package */ final Effects effects;
* @param effects The {@link Effects} to apply to the {@code mediaItem}.
*/ private EditedMediaItem(
public EditedMediaItem(MediaItem mediaItem, Effects effects) { MediaItem mediaItem, boolean removeAudio, boolean removeVideo, Effects effects) {
checkState(!removeAudio || !removeVideo, "Audio and video cannot both be removed");
this.mediaItem = mediaItem; this.mediaItem = mediaItem;
this.removeAudio = removeAudio;
this.removeVideo = removeVideo;
this.effects = effects; this.effects = effects;
} }
} }
...@@ -175,34 +175,24 @@ public final class Transformer { ...@@ -175,34 +175,24 @@ public final class Transformer {
} }
/** /**
* Sets whether to remove the audio from the output. * @deprecated Use {@link EditedMediaItem.Builder#setRemoveAudio(boolean)} to remove the audio
* * from the {@link EditedMediaItem} passed to {@link #startTransformation(EditedMediaItem,
* <p>The default value is {@code false}. * String)} or {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
*
* <p>The audio and video cannot both be removed because the output would not contain any
* samples.
*
* @param removeAudio Whether to remove the audio.
* @return This builder.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
@Deprecated
public Builder setRemoveAudio(boolean removeAudio) { public Builder setRemoveAudio(boolean removeAudio) {
this.removeAudio = removeAudio; this.removeAudio = removeAudio;
return this; return this;
} }
/** /**
* Sets whether to remove the video from the output. * @deprecated Use {@link EditedMediaItem.Builder#setRemoveVideo(boolean)} to remove the video
* * from the {@link EditedMediaItem} passed to {@link #startTransformation(EditedMediaItem,
* <p>The default value is {@code false}. * String)} or {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
*
* <p>The audio and video cannot both be removed because the output would not contain any
* samples.
*
* @param removeVideo Whether to remove the video.
* @return This builder.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
@Deprecated
public Builder setRemoveVideo(boolean removeVideo) { public Builder setRemoveVideo(boolean removeVideo) {
this.removeVideo = removeVideo; this.removeVideo = removeVideo;
return this; return this;
...@@ -384,7 +374,9 @@ public final class Transformer { ...@@ -384,7 +374,9 @@ public final class Transformer {
* *
* <p>This method is experimental and may be removed or changed without warning. * <p>This method is experimental and may be removed or changed without warning.
* *
* <p>To replace existing audio with silence, call {@link #setRemoveAudio(boolean)} as well. * <p>To replace existing audio with silence, {@linkplain
* EditedMediaItem.Builder#setRemoveAudio(boolean) remove the audio} from the {@link
* EditedMediaItem} to transform.
* *
* <p>Audio properties/format: * <p>Audio properties/format:
* *
...@@ -721,8 +713,11 @@ public final class Transformer { ...@@ -721,8 +713,11 @@ public final class Transformer {
@Deprecated @Deprecated
public void startTransformation(MediaItem mediaItem, String path) { public void startTransformation(MediaItem mediaItem, String path) {
EditedMediaItem editedMediaItem = EditedMediaItem editedMediaItem =
new EditedMediaItem( new EditedMediaItem.Builder(mediaItem)
mediaItem, new Effects(audioProcessors, videoEffects, frameProcessorFactory)); .setRemoveAudio(removeAudio)
.setRemoveVideo(removeVideo)
.setEffects(new Effects(audioProcessors, videoEffects, frameProcessorFactory))
.build();
startTransformationInternal(editedMediaItem, path, /* parcelFileDescriptor= */ null); startTransformationInternal(editedMediaItem, path, /* parcelFileDescriptor= */ null);
} }
...@@ -733,8 +728,11 @@ public final class Transformer { ...@@ -733,8 +728,11 @@ public final class Transformer {
@RequiresApi(26) @RequiresApi(26)
public void startTransformation(MediaItem mediaItem, ParcelFileDescriptor parcelFileDescriptor) { public void startTransformation(MediaItem mediaItem, ParcelFileDescriptor parcelFileDescriptor) {
EditedMediaItem editedMediaItem = EditedMediaItem editedMediaItem =
new EditedMediaItem( new EditedMediaItem.Builder(mediaItem)
mediaItem, new Effects(audioProcessors, videoEffects, frameProcessorFactory)); .setRemoveAudio(removeAudio)
.setRemoveVideo(removeVideo)
.setEffects(new Effects(audioProcessors, videoEffects, frameProcessorFactory))
.build();
startTransformationInternal(editedMediaItem, /* path= */ null, parcelFileDescriptor); startTransformationInternal(editedMediaItem, /* path= */ null, parcelFileDescriptor);
} }
...@@ -765,8 +763,6 @@ public final class Transformer { ...@@ -765,8 +763,6 @@ public final class Transformer {
path, path,
parcelFileDescriptor, parcelFileDescriptor,
transformationRequest, transformationRequest,
removeAudio,
removeVideo,
generateSilentAudio, generateSilentAudio,
assetLoaderFactory, assetLoaderFactory,
encoderFactory, encoderFactory,
......
...@@ -118,8 +118,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -118,8 +118,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Nullable String outputPath, @Nullable String outputPath,
@Nullable ParcelFileDescriptor outputParcelFileDescriptor, @Nullable ParcelFileDescriptor outputParcelFileDescriptor,
TransformationRequest transformationRequest, TransformationRequest transformationRequest,
boolean removeAudio,
boolean removeVideo,
boolean generateSilentAudio, boolean generateSilentAudio,
AssetLoader.Factory assetLoaderFactory, AssetLoader.Factory assetLoaderFactory,
Codec.EncoderFactory encoderFactory, Codec.EncoderFactory encoderFactory,
...@@ -144,8 +142,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -144,8 +142,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
ComponentListener componentListener = new ComponentListener(mediaItem, fallbackListener); ComponentListener componentListener = new ComponentListener(mediaItem, fallbackListener);
assetLoader = assetLoader =
assetLoaderFactory assetLoaderFactory
.setRemoveAudio(removeAudio) .setRemoveAudio(editedMediaItem.removeAudio)
.setRemoveVideo(removeVideo) .setRemoveVideo(editedMediaItem.removeVideo)
.setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion) .setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion)
.createAssetLoader(mediaItem, internalLooper, componentListener); .createAssetLoader(mediaItem, internalLooper, componentListener);
effects = editedMediaItem.effects; effects = editedMediaItem.effects;
......
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.transformer;
import static org.junit.Assert.assertThrows;
import androidx.media3.common.MediaItem;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link EditedMediaItem.Builder}. */
@RunWith(AndroidJUnit4.class)
public final class EditedMediaItemBuilderTest {
@Test
public void build_removeAudioAndVideo_throws() {
MediaItem mediaItem = MediaItem.fromUri("uri");
assertThrows(
IllegalStateException.class,
() ->
new EditedMediaItem.Builder(mediaItem)
.setRemoveAudio(true)
.setRemoveVideo(true)
.build());
}
}
...@@ -30,15 +30,6 @@ import org.junit.runner.RunWith; ...@@ -30,15 +30,6 @@ import org.junit.runner.RunWith;
public class TransformerBuilderTest { public class TransformerBuilderTest {
@Test @Test
public void build_removeAudioAndVideo_throws() {
Context context = ApplicationProvider.getApplicationContext();
assertThrows(
IllegalStateException.class,
() -> new Transformer.Builder(context).setRemoveAudio(true).setRemoveVideo(true).build());
}
@Test
public void build_withUnsupportedAudioMimeType_throws() { public void build_withUnsupportedAudioMimeType_throws() {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
TransformationRequest transformationRequest = TransformationRequest transformationRequest =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment