Add a TestTransformerBuilder

This is inspired from TestExoPlayerBuilder.

Adding this class has a few advantages:
- It makes testing easier for apps by configuring Transformer for unit
  tests (for example, by setting the clock).
- It removes the Transformer setters that apps should not use for unit
  testing (for example, the video MIME type should not be set because
  it would cause Transformer to transcode.
- It allows us to add additional setters in the future, for example to
  build a Transformer that always fails.

PiperOrigin-RevId: 704181927
This commit is contained in:
kimvde 2024-12-09 01:03:47 -08:00 committed by Copybara-Service
parent 0a75447785
commit 1a7da45dd9
9 changed files with 352 additions and 184 deletions

View File

@ -26,7 +26,6 @@ import static androidx.media3.transformer.TestUtil.FILE_VIDEO_ONLY;
import static androidx.media3.transformer.TestUtil.addAudioDecoders;
import static androidx.media3.transformer.TestUtil.addAudioEncoders;
import static androidx.media3.transformer.TestUtil.createAudioEffects;
import static androidx.media3.transformer.TestUtil.createTransformerBuilder;
import static androidx.media3.transformer.TestUtil.createVolumeScalingAudioProcessor;
import static androidx.media3.transformer.TestUtil.getCompositionDumpFilePath;
import static androidx.media3.transformer.TestUtil.getDumpFileName;
@ -73,7 +72,7 @@ public class CompositionExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
EditedMediaItem audioEditedMediaItem =
@ -97,9 +96,8 @@ public class CompositionExportTest {
@Test
public void start_loopingTransmuxedAudio_producesExpectedResult() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_ONLY)).build();
EditedMediaItemSequence loopingAudioSequence =
@ -134,7 +132,7 @@ public class CompositionExportTest {
public void start_loopingTransmuxedVideo_producesExpectedResult() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_ONLY)).build();
EditedMediaItemSequence audioSequence =
@ -169,7 +167,7 @@ public class CompositionExportTest {
public void start_longVideoCompositionWithLoopingAudio_producesExpectedResult() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItemSequence loopingAudioSequence =
new EditedMediaItemSequence.Builder(
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW))
@ -200,7 +198,7 @@ public class CompositionExportTest {
public void start_compositionOfConcurrentAudio_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem rawAudioEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
Composition composition =
@ -224,7 +222,7 @@ public class CompositionExportTest {
public void start_audioVideoCompositionWithExtraAudio_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioVideoEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -257,7 +255,7 @@ public class CompositionExportTest {
public void start_audioVideoCompositionWithMutedAudio_matchesSingleSequence() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioVideoEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -293,7 +291,7 @@ public class CompositionExportTest {
public void start_audioVideoCompositionWithLoopingAudio_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioVideoEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -333,7 +331,7 @@ public class CompositionExportTest {
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setOutputSampleRateHz(48000);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
Composition composition =
@ -356,7 +354,7 @@ public class CompositionExportTest {
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setOutputSampleRateHz(48000);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem rawAudioEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
Composition composition =
@ -385,7 +383,7 @@ public class CompositionExportTest {
public void start_firstSequenceFinishesEarly_works() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioItem300ms =
new EditedMediaItem.Builder(
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)
@ -418,7 +416,7 @@ public class CompositionExportTest {
public void start_secondSequenceFinishesEarly_works() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioItem1000ms =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItem audioItem300ms =
@ -451,7 +449,7 @@ public class CompositionExportTest {
public void start_audioCompositionWithFirstSequenceAsGap_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioItem1000ms =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
Composition composition =
@ -475,7 +473,7 @@ public class CompositionExportTest {
public void start_audioCompositionWithFirstSequenceOffsetGap_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioEditedMediaItem =
new EditedMediaItem.Builder(
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_STEREO_48000KHZ))
@ -510,7 +508,7 @@ public class CompositionExportTest {
public void start_audioCompositionWithFirstSequencePaddingGap_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioItem300ms =
new EditedMediaItem.Builder(
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)
@ -551,7 +549,7 @@ public class CompositionExportTest {
public void start_audioVideoCompositionWithSecondSequenceOffsetGap_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioVideoEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -589,7 +587,7 @@ public class CompositionExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioVideoEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -647,7 +645,7 @@ public class CompositionExportTest {
public void start_audioVideoCompositionWithSecondSequencePaddingGap_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioVideoEditedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -685,7 +683,7 @@ public class CompositionExportTest {
public void start_audioCompositionWithSecondSequenceAsGap_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioItem1000ms =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
Composition composition =
@ -705,7 +703,7 @@ public class CompositionExportTest {
public void start_audioCompositionWithBothSequencesAsGaps_isCorrect() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
Composition composition =
new Composition.Builder(
new EditedMediaItemSequence.Builder().addGap(500_000).build(),

View File

@ -40,7 +40,6 @@ import static androidx.media3.transformer.TestUtil.addAudioDecoders;
import static androidx.media3.transformer.TestUtil.addAudioEncoders;
import static androidx.media3.transformer.TestUtil.createAudioEffects;
import static androidx.media3.transformer.TestUtil.createPitchChangingAudioProcessor;
import static androidx.media3.transformer.TestUtil.createTransformerBuilder;
import static androidx.media3.transformer.TestUtil.getDumpFileName;
import static androidx.media3.transformer.TestUtil.removeEncodersAndDecoders;
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_AVAILABLE;
@ -145,7 +144,7 @@ public final class MediaItemExportTest {
public void start_gapOnlyExport_outputsSilence() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItemSequence gapSequence =
new EditedMediaItemSequence.Builder().addGap(500_000).build();
@ -166,7 +165,7 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO_INCREASING_TIMESTAMPS_15S)
@ -193,7 +192,7 @@ public final class MediaItemExportTest {
public void start_withClippingStartAndEndEqual_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO_INCREASING_TIMESTAMPS_15S)
@ -220,7 +219,8 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem mediaItem =
@ -240,7 +240,8 @@ public final class MediaItemExportTest {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem mediaItem =
@ -272,7 +273,8 @@ public final class MediaItemExportTest {
public void start_trimOptimizationEnabled_fileNotMp4_fallbackToNormalExport() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem mediaItem =
@ -301,9 +303,7 @@ public final class MediaItemExportTest {
public void start_withSubtitlesVideoOnly_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
.setAudioMimeType(MimeTypes.AUDIO_AAC)
.build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_WITH_SUBTITLES))
.setRemoveAudio(true)
@ -323,7 +323,7 @@ public final class MediaItemExportTest {
public void start_successiveExports_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
// Transform first media item.
@ -342,7 +342,7 @@ public final class MediaItemExportTest {
public void start_concurrentExports_throwsError() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
transformer.start(mediaItem, outputDir.newFile("first").getPath());
@ -356,7 +356,7 @@ public final class MediaItemExportTest {
public void start_removeAudio_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO))
.setRemoveAudio(true)
@ -376,7 +376,7 @@ public final class MediaItemExportTest {
public void start_removeVideo_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO))
.setRemoveVideo(true)
@ -396,7 +396,7 @@ public final class MediaItemExportTest {
public void start_forceAudioTrackOnAudioOnly_isIgnored() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_AMR_NB);
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
Composition composition =
@ -415,7 +415,7 @@ public final class MediaItemExportTest {
public void start_forceAudioTrackOnAudioVideo_isIgnored() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
Composition composition =
@ -435,7 +435,7 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setOutputSampleRateHz(48000);
EditedMediaItem editedMediaItem =
@ -464,7 +464,7 @@ public final class MediaItemExportTest {
public void start_forceAudioTrackAndRemoveVideo_isIgnored() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO))
.setRemoveVideo(true)
@ -487,7 +487,7 @@ public final class MediaItemExportTest {
public void start_forceAudioTrackOnVideoOnly_generatesSilentAudio() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
Composition composition =
@ -510,7 +510,7 @@ public final class MediaItemExportTest {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
AtomicInteger bytesSeenByEffect = new AtomicInteger();
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem)
@ -530,7 +530,7 @@ public final class MediaItemExportTest {
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setOutputSampleRateHz(48000);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
AtomicInteger bytesRead = new AtomicInteger();
@ -559,7 +559,7 @@ public final class MediaItemExportTest {
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setSpeed(2f);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
AtomicInteger bytesRead = new AtomicInteger();
@ -588,7 +588,7 @@ public final class MediaItemExportTest {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
ToInt16PcmAudioProcessor toInt16PcmAudioProcessor = new ToInt16PcmAudioProcessor();
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + "mp4/sample_twos_pcm.mp4");
EditedMediaItem editedMediaItem =
@ -612,7 +612,7 @@ public final class MediaItemExportTest {
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
sonicAudioProcessor.setOutputSampleRateHz(48000);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem)
@ -640,7 +640,8 @@ public final class MediaItemExportTest {
Transformer.Listener mockListener2 = mock(Transformer.Listener.class);
Transformer.Listener mockListener3 = mock(Transformer.Listener.class);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.addListener(mockListener1)
.addListener(mockListener2)
.addListener(mockListener3)
@ -665,7 +666,8 @@ public final class MediaItemExportTest {
Transformer.Listener mockListener2 = mock(Transformer.Listener.class);
Transformer.Listener mockListener3 = mock(Transformer.Listener.class);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.addListener(mockListener1)
.addListener(mockListener2)
.addListener(mockListener3)
@ -697,7 +699,9 @@ public final class MediaItemExportTest {
TransformationRequest fallbackTransformationRequest =
new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build();
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ true)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setFallbackEnabled(true)
.addListener(mockListener1)
.addListener(mockListener2)
.addListener(mockListener3)
@ -732,7 +736,8 @@ public final class MediaItemExportTest {
Transformer.Listener mockListener2 = mock(Transformer.Listener.class);
Transformer.Listener mockListener3 = mock(Transformer.Listener.class);
Transformer transformer1 =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.addListener(mockListener1)
.addListener(mockListener2)
.addListener(mockListener3)
@ -752,7 +757,7 @@ public final class MediaItemExportTest {
public void start_flattenForSlowMotionVideoOnly_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_WITH_SEF_SLOW_MOTION))
.setFlattenForSlowMotion(true)
@ -773,7 +778,7 @@ public final class MediaItemExportTest {
public void start_completesWithValidBitrate() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
transformer.start(mediaItem, outputDir.newFile().getPath());
@ -809,7 +814,9 @@ public final class MediaItemExportTest {
addAudioEncoders(throwOnConfigureCodecConfig, MimeTypes.AUDIO_AMR_NB);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ true)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setFallbackEnabled(true)
.setAudioMimeType(MimeTypes.AUDIO_AMR_NB)
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
@ -827,7 +834,8 @@ public final class MediaItemExportTest {
public void start_withAudioFormatUnsupportedByDecoder_completesWithError() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setAudioMimeType(MimeTypes.AUDIO_AAC) // supported by encoder and muxer
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_AMR_WB);
@ -858,7 +866,8 @@ public final class MediaItemExportTest {
new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build();
// MIME type fallback is mandatory.
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.addListener(mockListener)
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
@ -891,7 +900,9 @@ public final class MediaItemExportTest {
TransformationRequest fallbackTransformationRequest =
new TransformationRequest.Builder().setAudioMimeType(MimeTypes.AUDIO_AAC).build();
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ true)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setFallbackEnabled(true)
.addListener(mockListener)
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
@ -912,7 +923,7 @@ public final class MediaItemExportTest {
public void start_withIoError_completesWithError() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri("asset:///non-existing-path.mp4");
transformer.start(mediaItem, outputDir.newFile().getPath());
@ -936,7 +947,8 @@ public final class MediaItemExportTest {
new FakeClock(/* isAutoAdvancing= */ true),
mediaSourceFactory);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setMaxDelayBetweenMuxerSamplesMs(1)
.setAssetLoaderFactory(assetLoaderFactory)
.build();
@ -953,7 +965,8 @@ public final class MediaItemExportTest {
public void start_withUnsetMaxDelayBetweenSamples_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setMaxDelayBetweenMuxerSamplesMs(C.TIME_UNSET)
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
@ -969,7 +982,7 @@ public final class MediaItemExportTest {
public void start_afterCancellation_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
transformer.start(mediaItem, outputDir.newFile("first").getPath());
@ -990,9 +1003,7 @@ public final class MediaItemExportTest {
anotherThread.start();
Looper looper = anotherThread.getLooper();
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
.setLooper(looper)
.build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).setLooper(looper).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
AtomicReference<Exception> exception = new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
@ -1022,7 +1033,7 @@ public final class MediaItemExportTest {
public void start_fromWrongThread_throwsError() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
HandlerThread anotherThread = new HandlerThread("AnotherThread");
AtomicReference<IllegalStateException> illegalStateException = new AtomicReference<>();
@ -1054,7 +1065,8 @@ public final class MediaItemExportTest {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
AtomicReference<SampleConsumer> sampleConsumerRef = new AtomicReference<>();
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setAssetLoaderFactory(
new FakeAssetLoader.Factory(SUPPORTED_OUTPUT_TYPE_DECODED, sampleConsumerRef))
.build();
@ -1072,7 +1084,8 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.setAssetLoaderFactory(
new FakeAssetLoader.Factory(
SUPPORTED_OUTPUT_TYPE_ENCODED, /* sampleConsumerRef= */ null))
@ -1094,7 +1107,7 @@ public final class MediaItemExportTest {
public void start_withNoOpEffects_transmuxes() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
int mediaItemHeightPixels = 720;
ImmutableList<Effect> videoEffects =
@ -1119,7 +1132,7 @@ public final class MediaItemExportTest {
public void start_withOnlyRegularRotationEffect_transmuxesAndRotates() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
ImmutableList<Effect> videoEffects =
ImmutableList.of(
@ -1145,7 +1158,7 @@ public final class MediaItemExportTest {
public void start_regularRotationsAndNoOps_transmuxes() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
// Total rotation is 270.
ImmutableList<Effect> videoEffects =
ImmutableList.of(
@ -1176,10 +1189,7 @@ public final class MediaItemExportTest {
addThrowingAudioEncoder(MimeTypes.AUDIO_AAC);
Transformer transformer =
ExperimentalAnalyzerModeFactory.buildAnalyzer(
getApplicationContext(),
new Transformer.Builder(getApplicationContext())
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.build());
getApplicationContext(), new TestTransformerBuilder(getApplicationContext()).build());
AtomicInteger bytesSeen = new AtomicInteger(0);
EditedMediaItem item =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW))
@ -1201,10 +1211,7 @@ public final class MediaItemExportTest {
addThrowingAudioEncoder(MimeTypes.AUDIO_AAC);
Transformer transformer =
ExperimentalAnalyzerModeFactory.buildAnalyzer(
getApplicationContext(),
new Transformer.Builder(getApplicationContext())
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.build());
getApplicationContext(), new TestTransformerBuilder(getApplicationContext()).build());
AtomicInteger bytesSeen = new AtomicInteger(0);
Composition composition =
new Composition.Builder(
@ -1231,10 +1238,7 @@ public final class MediaItemExportTest {
addThrowingAudioEncoder(MimeTypes.AUDIO_AAC);
Transformer transformer =
ExperimentalAnalyzerModeFactory.buildAnalyzer(
getApplicationContext(),
new Transformer.Builder(getApplicationContext())
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.build());
getApplicationContext(), new TestTransformerBuilder(getApplicationContext()).build());
AtomicInteger itemEffectBytesSeen = new AtomicInteger(0);
AtomicInteger compositionEffectBytesSeen = new AtomicInteger(0);
Composition composition =
@ -1262,7 +1266,7 @@ public final class MediaItemExportTest {
public void getProgress_unknownDuration_returnsConsistentStates() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_UNKNOWN_DURATION);
transformer.start(mediaItem, outputDir.newFile().getPath());
@ -1284,7 +1288,7 @@ public final class MediaItemExportTest {
public void getProgress_knownDuration_returnsConsistentStates() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem =
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO_INCREASING_TIMESTAMPS_15S);
@ -1306,7 +1310,7 @@ public final class MediaItemExportTest {
public void getProgress_knownDuration_givesIncreasingPercentages() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem =
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO_INCREASING_TIMESTAMPS_15S);
@ -1325,7 +1329,7 @@ public final class MediaItemExportTest {
public void getProgress_noCurrentExport_returnsNotStarted() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
ProgressHolder progressHolder = new ProgressHolder();
@Transformer.ProgressState int stateBeforeTransform = transformer.getProgress(progressHolder);
@ -1341,7 +1345,7 @@ public final class MediaItemExportTest {
public void getProgress_fromWrongThread_throwsError() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
HandlerThread anotherThread = new HandlerThread("AnotherThread");
AtomicReference<IllegalStateException> illegalStateException = new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
@ -1371,7 +1375,8 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem mediaItem =
@ -1394,7 +1399,8 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem mediaItem =
@ -1420,7 +1426,8 @@ public final class MediaItemExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
@ -1438,7 +1445,7 @@ public final class MediaItemExportTest {
public void cancel_afterCompletion_doesNotThrow() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
transformer.start(mediaItem, outputDir.newFile().getPath());
@ -1450,7 +1457,7 @@ public final class MediaItemExportTest {
public void cancel_fromWrongThread_throwsError() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
HandlerThread anotherThread = new HandlerThread("AnotherThread");
AtomicReference<IllegalStateException> illegalStateException = new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
@ -1480,7 +1487,7 @@ public final class MediaItemExportTest {
public void transmux_audioWithEditList_api30_correctDuration() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_ELST_SKIP_500MS);
transformer.start(mediaItem, outputDir.newFile().getPath());
@ -1507,7 +1514,7 @@ public final class MediaItemExportTest {
// Do not use CapturingMuxer.Factory(), as this test checks for a workaround in
// FrameworkMuxer.
Transformer transformer =
createTransformerBuilder(new FrameworkMuxer.Factory(), /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(new FrameworkMuxer.Factory()).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_ELST_SKIP_500MS);
transformer.start(mediaItem, outputDir.newFile().getPath());
@ -1527,7 +1534,7 @@ public final class MediaItemExportTest {
public void transmux_trimsFirstIDRDuration() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ELST_TRIM_IDR_DURATION);
transformer.start(mediaItem, outputDir.newFile().getPath());

View File

@ -23,12 +23,12 @@ import static androidx.media3.transformer.TestUtil.addAudioDecoders;
import static androidx.media3.transformer.TestUtil.addAudioEncoders;
import static androidx.media3.transformer.TestUtil.createAudioEffects;
import static androidx.media3.transformer.TestUtil.createPitchChangingAudioProcessor;
import static androidx.media3.transformer.TestUtil.createTransformerBuilder;
import static androidx.media3.transformer.TestUtil.getSequenceDumpFilePath;
import static androidx.media3.transformer.TestUtil.removeEncodersAndDecoders;
import static com.google.common.truth.Truth.assertThat;
import static java.util.stream.Collectors.toList;
import android.content.Context;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Util;
@ -127,6 +127,8 @@ public final class ParameterizedAudioExportTest {
@Parameter public SequenceConfig sequence;
private final Context context = ApplicationProvider.getApplicationContext();
private final CapturingMuxer.Factory muxerFactory =
new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
@ -144,7 +146,7 @@ public final class ParameterizedAudioExportTest {
@Test
public void export() throws Exception {
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
transformer.start(sequence.asComposition(), outputDir.newFile().getPath());

View File

@ -26,12 +26,12 @@ import static androidx.media3.transformer.TestUtil.FILE_VIDEO_ONLY;
import static androidx.media3.transformer.TestUtil.addAudioDecoders;
import static androidx.media3.transformer.TestUtil.addAudioEncoders;
import static androidx.media3.transformer.TestUtil.createAudioEffects;
import static androidx.media3.transformer.TestUtil.createTransformerBuilder;
import static androidx.media3.transformer.TestUtil.createVolumeScalingAudioProcessor;
import static androidx.media3.transformer.TestUtil.getDumpFileName;
import static androidx.media3.transformer.TestUtil.removeEncodersAndDecoders;
import static org.junit.Assume.assumeFalse;
import android.content.Context;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.test.utils.DumpFileAsserts;
@ -90,6 +90,8 @@ public final class ParameterizedItemExportTest {
@Parameter public String assetFile;
private final Context context = ApplicationProvider.getApplicationContext();
@Before
public void setUp() {
// Only add RAW decoder, so non-RAW audio has no options for decoding.
@ -108,7 +110,7 @@ public final class ParameterizedItemExportTest {
boolean handleAudioAsPcm = !ENCODED_AUDIO_ASSETS.contains(assetFile);
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(handleAudioAsPcm);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
transformer.start(
MediaItem.fromUri(ASSET_URI_PREFIX + assetFile), outputDir.newFile().getPath());
@ -125,7 +127,7 @@ public final class ParameterizedItemExportTest {
assumeFalse(AUDIO_ONLY_ASSETS.contains(assetFile));
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem item =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + assetFile))
@ -153,7 +155,7 @@ public final class ParameterizedItemExportTest {
ENCODED_AUDIO_ASSETS.contains(assetFile));
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem item =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + assetFile))
@ -179,7 +181,7 @@ public final class ParameterizedItemExportTest {
ENCODED_AUDIO_ASSETS.contains(assetFile));
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem item =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + assetFile)).build();

View File

@ -27,7 +27,6 @@ import static androidx.media3.transformer.TestUtil.addAudioEncoders;
import static androidx.media3.transformer.TestUtil.createAudioEffects;
import static androidx.media3.transformer.TestUtil.createChannelCountChangingAudioProcessor;
import static androidx.media3.transformer.TestUtil.createPitchChangingAudioProcessor;
import static androidx.media3.transformer.TestUtil.createTransformerBuilder;
import static androidx.media3.transformer.TestUtil.getDumpFileName;
import static androidx.media3.transformer.TestUtil.getSequenceDumpFilePath;
import static androidx.media3.transformer.TestUtil.removeEncodersAndDecoders;
@ -84,7 +83,7 @@ public final class SequenceExportTest {
public void start_concatenateSameMediaItemWithTransmux_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
Composition composition =
@ -112,7 +111,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(mediaItem)
@ -146,7 +145,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem.ClippingConfiguration clippingConfiguration1 =
new MediaItem.ClippingConfiguration.Builder()
.setStartPositionMs(0) // Corresponds to key frame.
@ -195,7 +194,8 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ false);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false)
new TestTransformerBuilder(context)
.setMuxerFactory(muxerFactory)
.experimentalSetTrimOptimizationEnabled(true)
.build();
MediaItem.ClippingConfiguration clippingConfiguration1 =
@ -246,7 +246,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem audioVideoMediaItem = new EditedMediaItem.Builder(mediaItem).build();
EditedMediaItem videoOnlyMediaItem =
@ -276,7 +276,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem videoOnlyMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
@ -306,7 +306,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem audioEditedMediaItem =
new EditedMediaItem.Builder(mediaItem)
@ -342,7 +342,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem silenceEditedMediaItem =
new EditedMediaItem.Builder(mediaItem)
@ -378,7 +378,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem videoOnlyMediaItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
@ -406,7 +406,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem silenceWithEffectsItem =
new EditedMediaItem.Builder(mediaItem)
@ -439,7 +439,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem silenceItem =
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).build();
@ -472,7 +472,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO);
EditedMediaItem firstItem =
new EditedMediaItem.Builder(mediaItem)
@ -504,8 +504,7 @@ public final class SequenceExportTest {
@Test
public void transmuxAudio_itemGap_throws() throws Exception {
Transformer transformer =
createTransformerBuilder(new DefaultMuxer.Factory(), /* enableFallback= */ false).build();
Transformer transformer = new TestTransformerBuilder(context).build();
EditedMediaItem audioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItemSequence sequence =
@ -523,8 +522,7 @@ public final class SequenceExportTest {
@Ignore
@Test
public void transmuxAudio_gapItem_throws() throws Exception {
Transformer transformer =
createTransformerBuilder(new DefaultMuxer.Factory(), /* enableFallback= */ false).build();
Transformer transformer = new TestTransformerBuilder(context).build();
EditedMediaItem audioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW))
.setRemoveVideo(true)
@ -542,8 +540,7 @@ public final class SequenceExportTest {
@Test
public void start_videoGap_throws() throws Exception {
Transformer transformer =
createTransformerBuilder(new DefaultMuxer.Factory(), /* enableFallback= */ false).build();
Transformer transformer = new TestTransformerBuilder(context).build();
EditedMediaItem audioVideoItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -561,8 +558,7 @@ public final class SequenceExportTest {
@Test
public void start_gapVideo_throws() throws Exception {
Transformer transformer =
createTransformerBuilder(new DefaultMuxer.Factory(), /* enableFallback= */ false).build();
Transformer transformer = new TestTransformerBuilder(context).build();
EditedMediaItem audioVideoItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_VIDEO))
.build();
@ -581,7 +577,7 @@ public final class SequenceExportTest {
public void start_gapGap_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItemSequence sequence =
new EditedMediaItemSequence.Builder().addGap(300_000).addGap(200_000).build();
Composition composition = new Composition.Builder(sequence).build();
@ -597,7 +593,7 @@ public final class SequenceExportTest {
public void start_itemGapGap_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem firstAudioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItemSequence sequence =
@ -622,7 +618,7 @@ public final class SequenceExportTest {
public void start_gapGapItem_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem audioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItemSequence sequence =
@ -647,7 +643,7 @@ public final class SequenceExportTest {
public void start_itemGapGapItem_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem firstAudioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItem secondAudioItem =
@ -680,7 +676,7 @@ public final class SequenceExportTest {
public void start_itemGapItemGap_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem firstAudioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItem secondAudioItem =
@ -713,7 +709,7 @@ public final class SequenceExportTest {
public void start_gapItemGapItem_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem firstAudioItem =
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW)).build();
EditedMediaItem secondAudioItem =
@ -746,7 +742,7 @@ public final class SequenceExportTest {
public void concatenateTwoAudioItems_withSameFormat_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem audioOnlyMediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(audioOnlyMediaItem).build();
Composition composition =
@ -771,7 +767,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem audioOnlyMediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(audioOnlyMediaItem)
@ -799,7 +795,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem audioOnlyMediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem highPitchMediaItem =
new EditedMediaItem.Builder(audioOnlyMediaItem)
@ -832,7 +828,7 @@ public final class SequenceExportTest {
public void concatenateTwoAudioItems_withDiffFormat_completesSuccessfully() throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem stereo48000Audio =
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_STEREO_48000KHZ);
MediaItem mono44100Audio = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
@ -861,7 +857,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem stereo48000Audio =
new EditedMediaItem.Builder(
@ -894,7 +890,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
EditedMediaItem stereo48000AudioHighPitch =
new EditedMediaItem.Builder(
@ -929,7 +925,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem stereo48000Audio =
MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW_STEREO_48000KHZ);
MediaItem mono44100Audio = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
@ -962,7 +958,7 @@ public final class SequenceExportTest {
throws Exception {
CapturingMuxer.Factory muxerFactory = new CapturingMuxer.Factory(/* handleAudioAsPcm= */ true);
Transformer transformer =
createTransformerBuilder(muxerFactory, /* enableFallback= */ false).build();
new TestTransformerBuilder(context).setMuxerFactory(muxerFactory).build();
MediaItem audioOnlyMediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_RAW);
EditedMediaItem twoChannelMediaItem =
new EditedMediaItem.Builder(audioOnlyMediaItem)

View File

@ -0,0 +1,203 @@
/*
* Copyright 2024 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
*
* https://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 android.content.Context;
import android.os.Looper;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Clock;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.FakeClock;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/**
* A builder of {@link Transformer} instances for testing with Robolectric.
*
* <p>To transcode audio, add the required codecs using {@link TestUtil#addAudioDecoders} and {@link
* TestUtil#addAudioEncoders}.
*
* <p>Transcoding video is unsupported in Robolectric tests. In order for a {@link Transformer} test
* instance to succeed with video input, make sure to configure the export in such a way that video
* samples are transmuxed (for example by not adding any video effects).
*
* <p>Images are unsupported in Robolectric tests.
*/
@UnstableApi
public final class TestTransformerBuilder {
private final Context context;
private final List<Transformer.Listener> listeners;
private final Clock clock;
private @MonotonicNonNull String audioMimeType;
private boolean trimOptimizationEnabled;
private long maxDelayBetweenMuxerSamplesMs;
private AssetLoader.Factory assetLoaderFactory;
private Muxer.Factory muxerFactory;
private boolean fallbackEnabled;
private Looper looper;
/** Creates a new instance. */
public TestTransformerBuilder(Context context) {
this.context = context;
listeners = new ArrayList<>();
clock = new FakeClock(/* isAutoAdvancing= */ true);
maxDelayBetweenMuxerSamplesMs = Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS;
assetLoaderFactory =
new DefaultAssetLoaderFactory(
context, new DefaultDecoderFactory.Builder(context).build(), clock);
muxerFactory = new DefaultMuxer.Factory();
looper = Util.getCurrentOrMainLooper();
}
/**
* Sets the audio {@linkplain MimeTypes MIME type} of the output.
*
* @param audioMimeType The audio MIME type of the output.
* @return This builder.
* @see Transformer.Builder#setAudioMimeType(String)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder setAudioMimeType(String audioMimeType) {
this.audioMimeType = audioMimeType;
return this;
}
/**
* Sets whether to enable the trim optimization.
*
* @param trimOptimizationEnabled Whether to enable the trim optimization.
* @return This builder.
* @see Transformer.Builder#experimentalSetTrimOptimizationEnabled(boolean)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder experimentalSetTrimOptimizationEnabled(
boolean trimOptimizationEnabled) {
this.trimOptimizationEnabled = trimOptimizationEnabled;
return this;
}
/**
* Sets the maximum delay allowed between output samples.
*
* @param maxDelayBetweenMuxerSamplesMs The maximum delay allowed between output samples, in
* milliseconds.
* @return This builder.
* @see Transformer.Builder#setMaxDelayBetweenMuxerSamplesMs(long)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder setMaxDelayBetweenMuxerSamplesMs(
long maxDelayBetweenMuxerSamplesMs) {
this.maxDelayBetweenMuxerSamplesMs = maxDelayBetweenMuxerSamplesMs;
return this;
}
/**
* Adds a {@link Transformer.Listener}.
*
* @param listener A @link Transformer.Listener}.
* @return This builder.
* @see Transformer.Builder#addListener(Transformer.Listener)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder addListener(Transformer.Listener listener) {
listeners.add(listener);
return this;
}
/**
* Sets the {@link AssetLoader.Factory} to use.
*
* @param assetLoaderFactory The {@link AssetLoader.Factory} to use.
* @return This builder.
* @see Transformer.Builder#setAssetLoaderFactory(AssetLoader.Factory)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder setAssetLoaderFactory(AssetLoader.Factory assetLoaderFactory) {
this.assetLoaderFactory = assetLoaderFactory;
return this;
}
/**
* Sets the {@link Muxer.Factory} to use.
*
* @param muxerFactory The {@link Muxer.Factory} to use.
* @return This builder.
* @see Transformer.Builder#setMuxerFactory(Muxer.Factory)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder setMuxerFactory(Muxer.Factory muxerFactory) {
this.muxerFactory = muxerFactory;
return this;
}
/**
* Sets whether to enable {@linkplain DefaultEncoderFactory.Builder#setEnableFallback(boolean)
* fallback}.
*
* <p>The default value is {@code false}.
*
* @param fallbackEnabled Whether to enable fallback.
* @return This builder.
* @see DefaultEncoderFactory.Builder#setEnableFallback(boolean)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder setFallbackEnabled(boolean fallbackEnabled) {
this.fallbackEnabled = fallbackEnabled;
return this;
}
/**
* Sets the {@link Looper} that must be used for all calls to the transformer and that is used to
* call listeners on.
*
* @param looper The {@link Looper} to use.
* @return This builder.
* @see Transformer.Builder#setLooper(Looper)
*/
@CanIgnoreReturnValue
public TestTransformerBuilder setLooper(Looper looper) {
this.looper = looper;
return this;
}
/** Builds a {@link Transformer} instance for testing with Robolectric. */
public Transformer build() {
Codec.EncoderFactory encoderFactory =
new DefaultEncoderFactory.Builder(context).setEnableFallback(fallbackEnabled).build();
Transformer.Builder transformerBuilder =
new Transformer.Builder(context)
.experimentalSetTrimOptimizationEnabled(trimOptimizationEnabled)
.setMaxDelayBetweenMuxerSamplesMs(maxDelayBetweenMuxerSamplesMs)
.setAssetLoaderFactory(assetLoaderFactory)
.setMuxerFactory(muxerFactory)
.setEncoderFactory(encoderFactory)
.setLooper(looper)
.setClock(clock);
if (audioMimeType != null) {
transformerBuilder.setAudioMimeType(audioMimeType);
}
for (Transformer.Listener listener : listeners) {
transformerBuilder.addListener(listener);
}
return transformerBuilder.build();
}
}

View File

@ -15,7 +15,6 @@
*/
package androidx.media3.transformer;
import android.content.Context;
import android.media.MediaFormat;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.audio.AudioProcessor;
@ -24,9 +23,6 @@ import androidx.media3.common.audio.ChannelMixingMatrix;
import androidx.media3.common.audio.SonicAudioProcessor;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.FakeClock;
import androidx.test.core.app.ApplicationProvider;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import java.util.List;
@ -65,16 +61,6 @@ public final class TestUtil {
private TestUtil() {}
public static Transformer.Builder createTransformerBuilder(
Muxer.Factory muxerFactory, boolean enableFallback) {
Context context = ApplicationProvider.getApplicationContext();
return new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(muxerFactory)
.setEncoderFactory(
new DefaultEncoderFactory.Builder(context).setEnableFallback(enableFallback).build());
}
public static Effects createAudioEffects(AudioProcessor... audioProcessors) {
return new Effects(
ImmutableList.copyOf(audioProcessors), /* videoEffects= */ ImmutableList.of());

View File

@ -36,7 +36,6 @@ import androidx.media3.extractor.mp4.Mp4Extractor;
import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.DumpFileAsserts;
import androidx.media3.test.utils.FakeClock;
import androidx.media3.test.utils.FakeExtractorOutput;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@ -79,10 +78,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(Uri.parse(tsFilePath))
@ -117,10 +113,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
})
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_FILE_PATH));
transformer.start(mediaItem, outputPath);
@ -141,10 +134,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
.setMetadataProvider(metadataEntries -> metadataEntries.add(new XmpData(xmpData)))
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_FILE_PATH));
transformer.start(mediaItem, outputPath);
@ -167,10 +157,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
.setMetadataProvider(metadataEntries -> metadataEntries.add(expectedCaptureFps))
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_FILE_PATH));
transformer.start(mediaItem, outputPath);
@ -199,10 +186,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_FILE_PATH));
transformer.start(mediaItem, outputPath);
@ -236,10 +220,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
})
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_FILE_PATH));
transformer.start(mediaItem, outputPath);
@ -271,10 +252,7 @@ public class TransformerWithInAppMuxerEndToEndNonParameterizedTest {
long expectedDurationUs = 2_000_000L;
inAppMuxerFactory.setVideoDurationUs(expectedDurationUs);
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_FILE_PATH));
transformer.start(mediaItem, outputPath);

View File

@ -26,7 +26,6 @@ import androidx.media3.extractor.mp4.Mp4Extractor;
import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.DumpFileAsserts;
import androidx.media3.test.utils.FakeClock;
import androidx.media3.test.utils.FakeExtractorOutput;
import androidx.test.core.app.ApplicationProvider;
import com.google.common.collect.ImmutableList;
@ -96,10 +95,7 @@ public class TransformerWithInAppMuxerEndToEndParameterizedTest {
.build();
Transformer transformer =
new Transformer.Builder(context)
.setClock(new FakeClock(/* isAutoAdvancing= */ true))
.setMuxerFactory(inAppMuxerFactory)
.build();
new TestTransformerBuilder(context).setMuxerFactory(inAppMuxerFactory).build();
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + checkNotNull(inputFile));
transformer.start(mediaItem, outputPath);