diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Composition.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Composition.java index 7ec8110cb4..6eae3cd07f 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Composition.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Composition.java @@ -120,9 +120,10 @@ public final class Composition { * audio track will only be transcoded if necessary. * *
If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all - * the audio tracks are transmuxed if {@code transmuxAudio} is {@code true} and exporting the - * first {@link MediaItem} doesn't require audio transcoding. Otherwise, they are all - * transcoded. Transmuxed tracks must be compatible and must not overlap in time. + * the audio tracks are transcoded by default. They are all transmuxed if {@code transmuxAudio} + * is {@code true}. Transmuxed tracks must be compatible (typically, all the {@link MediaItem} + * instances containing the track to transmux are concatenated in a single {@link + * EditedMediaItemSequence} and have the same sample format for that track). * *
Requesting audio transmuxing and {@linkplain #experimentalSetForceAudioTrack(boolean) * forcing an audio track} are not allowed together because generating silence requires @@ -146,9 +147,10 @@ public final class Composition { * video track will only be transcoded if necessary. * *
If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all - * the video tracks are transmuxed if {@code transmuxVideo} is {@code true} and exporting the - * first {@link MediaItem} doesn't require video transcoding. Otherwise, they are all - * transcoded. Transmuxed tracks must be compatible and must not overlap in time. + * the video tracks are transcoded by default. They are all transmuxed if {@code transmuxVideo} + * is {@code true}. Transmuxed tracks must be compatible (typically, all the {@link MediaItem} + * instances containing the track to transmux are concatenated in a single {@link + * EditedMediaItemSequence} and have the same sample format for that track). * * @param transmuxVideo Whether to transmux the video tracks. * @return This builder. diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java index 3fbea97f5d..c02dc704cb 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java @@ -582,8 +582,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } private boolean shouldTranscodeAudio(Format inputFormat) { - if (editedMediaItems.size() > 1 && !composition.transmuxAudio) { - return true; + if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) { + return !composition.transmuxAudio; } if (encoderFactory.audioNeedsEncoding()) { return true; @@ -603,14 +603,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) { return true; } - return false; } private boolean shouldTranscodeVideo( Format inputFormat, long streamStartPositionUs, long streamOffsetUs) { - if (editedMediaItems.size() > 1 && !composition.transmuxVideo) { - return true; + if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) { + return !composition.transmuxVideo; } EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0); if ((streamStartPositionUs - streamOffsetUs) != 0 diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java index ab57df45e4..30a87e27d1 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java @@ -49,6 +49,7 @@ import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.SonicAudioProcessor; import com.google.android.exoplayer2.effect.Presentation; +import com.google.android.exoplayer2.effect.RgbFilter; import com.google.android.exoplayer2.effect.ScaleAndRotateTransformation; import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; import com.google.android.exoplayer2.extractor.Extractor; @@ -516,15 +517,16 @@ public final class TransformerEndToEndTest { } @Test - public void start_multipleMediaItemsWithEffectsAndTransmux_ignoresTransmux() throws Exception { + public void start_multipleMediaItemsAndTransmux_transmux() throws Exception { Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build(); MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO); SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor(); sonicAudioProcessor.setPitch(2f); + Effect videoEffect = RgbFilter.createGrayscaleFilter(); Effects effects = - new Effects(ImmutableList.of(sonicAudioProcessor), /* videoEffects= */ ImmutableList.of()); + new Effects(ImmutableList.of(sonicAudioProcessor), ImmutableList.of(videoEffect)); EditedMediaItem editedMediaItem = - new EditedMediaItem.Builder(mediaItem).setEffects(effects).setRemoveVideo(true).build(); + new EditedMediaItem.Builder(mediaItem).setEffects(effects).build(); EditedMediaItemSequence editedMediaItemSequence = new EditedMediaItemSequence(ImmutableList.of(editedMediaItem, editedMediaItem)); Composition composition = @@ -536,13 +538,8 @@ public final class TransformerEndToEndTest { transformer.start(composition, outputPath); TransformerTestRunner.runLooper(transformer); - // The inputs should be transcoded even though transmuxing has been requested. This is because - // audio effects have been added to the first MediaItem in the sequence, so the transcoding - // audio sample pipeline should be picked to apply these effects. DumpFileAsserts.assertOutput( - context, - testMuxer, - getDumpFileName(FILE_AUDIO_VIDEO + ".concatenated_with_high_pitch_and_no_video")); + context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO + ".concatenated")); } @Test