Make sure that tracks are transcoded/transmuxed consistently
All audio tracks should either all be transcoded or all be transmuxed. Same for video tracks. To achieve this, simplify the behaviour of transmuxAudio/Video. PiperOrigin-RevId: 513809287
This commit is contained in:
parent
07ba24ab1a
commit
71fb4f9a5c
@ -122,9 +122,10 @@ public final class Composition {
|
|||||||
* audio track will only be transcoded if necessary.
|
* audio track will only be transcoded if necessary.
|
||||||
*
|
*
|
||||||
* <p>If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all
|
* <p>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
|
* the audio tracks are transcoded by default. They are all transmuxed if {@code transmuxAudio}
|
||||||
* first {@link MediaItem} doesn't require audio transcoding. Otherwise, they are all
|
* is {@code true}. Transmuxed tracks must be compatible (typically, all the {@link MediaItem}
|
||||||
* transcoded. Transmuxed tracks must be compatible and must not overlap in time.
|
* instances containing the track to transmux are concatenated in a single {@link
|
||||||
|
* EditedMediaItemSequence} and have the same sample format for that track).
|
||||||
*
|
*
|
||||||
* <p>Requesting audio transmuxing and {@linkplain #experimentalSetForceAudioTrack(boolean)
|
* <p>Requesting audio transmuxing and {@linkplain #experimentalSetForceAudioTrack(boolean)
|
||||||
* forcing an audio track} are not allowed together because generating silence requires
|
* forcing an audio track} are not allowed together because generating silence requires
|
||||||
@ -148,9 +149,10 @@ public final class Composition {
|
|||||||
* video track will only be transcoded if necessary.
|
* video track will only be transcoded if necessary.
|
||||||
*
|
*
|
||||||
* <p>If the input {@link Composition} contains multiple {@linkplain MediaItem media items}, all
|
* <p>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
|
* the video tracks are transcoded by default. They are all transmuxed if {@code transmuxVideo}
|
||||||
* first {@link MediaItem} doesn't require video transcoding. Otherwise, they are all
|
* is {@code true}. Transmuxed tracks must be compatible (typically, all the {@link MediaItem}
|
||||||
* transcoded. Transmuxed tracks must be compatible and must not overlap in time.
|
* 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.
|
* @param transmuxVideo Whether to transmux the video tracks.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
|
@ -582,8 +582,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldTranscodeAudio(Format inputFormat) {
|
private boolean shouldTranscodeAudio(Format inputFormat) {
|
||||||
if (editedMediaItems.size() > 1 && !composition.transmuxAudio) {
|
if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) {
|
||||||
return true;
|
return !composition.transmuxAudio;
|
||||||
}
|
}
|
||||||
if (encoderFactory.audioNeedsEncoding()) {
|
if (encoderFactory.audioNeedsEncoding()) {
|
||||||
return true;
|
return true;
|
||||||
@ -603,14 +603,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) {
|
if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldTranscodeVideo(
|
private boolean shouldTranscodeVideo(
|
||||||
Format inputFormat, long streamStartPositionUs, long streamOffsetUs) {
|
Format inputFormat, long streamStartPositionUs, long streamOffsetUs) {
|
||||||
if (editedMediaItems.size() > 1 && !composition.transmuxVideo) {
|
if (composition.sequences.size() > 1 || editedMediaItems.size() > 1) {
|
||||||
return true;
|
return !composition.transmuxVideo;
|
||||||
}
|
}
|
||||||
EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0);
|
EditedMediaItem firstEditedMediaItem = editedMediaItems.get(0);
|
||||||
if ((streamStartPositionUs - streamOffsetUs) != 0
|
if ((streamStartPositionUs - streamOffsetUs) != 0
|
||||||
|
@ -50,6 +50,7 @@ import androidx.media3.common.audio.AudioProcessor;
|
|||||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.effect.Presentation;
|
import androidx.media3.effect.Presentation;
|
||||||
|
import androidx.media3.effect.RgbFilter;
|
||||||
import androidx.media3.effect.ScaleAndRotateTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
import androidx.media3.exoplayer.source.MediaSource;
|
||||||
@ -516,15 +517,16 @@ public final class TransformerEndToEndTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void start_multipleMediaItemsWithEffectsAndTransmux_ignoresTransmux() throws Exception {
|
public void start_multipleMediaItemsAndTransmux_transmux() throws Exception {
|
||||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
|
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
|
||||||
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
|
SonicAudioProcessor sonicAudioProcessor = new SonicAudioProcessor();
|
||||||
sonicAudioProcessor.setPitch(2f);
|
sonicAudioProcessor.setPitch(2f);
|
||||||
|
Effect videoEffect = RgbFilter.createGrayscaleFilter();
|
||||||
Effects effects =
|
Effects effects =
|
||||||
new Effects(ImmutableList.of(sonicAudioProcessor), /* videoEffects= */ ImmutableList.of());
|
new Effects(ImmutableList.of(sonicAudioProcessor), ImmutableList.of(videoEffect));
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).setRemoveVideo(true).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
EditedMediaItemSequence editedMediaItemSequence =
|
EditedMediaItemSequence editedMediaItemSequence =
|
||||||
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem, editedMediaItem));
|
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem, editedMediaItem));
|
||||||
Composition composition =
|
Composition composition =
|
||||||
@ -536,13 +538,8 @@ public final class TransformerEndToEndTest {
|
|||||||
transformer.start(composition, outputPath);
|
transformer.start(composition, outputPath);
|
||||||
TransformerTestRunner.runLooper(transformer);
|
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(
|
DumpFileAsserts.assertOutput(
|
||||||
context,
|
context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO + ".concatenated"));
|
||||||
testMuxer,
|
|
||||||
getDumpFileName(FILE_AUDIO_VIDEO + ".concatenated_with_high_pitch_and_no_video"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user