Move generateSilentAudio to Composition
Also rename to forceAudioTrack PiperOrigin-RevId: 510394620
This commit is contained in:
parent
0c17605ff0
commit
5806414fba
@ -62,7 +62,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
public static final String SHOULD_REMOVE_AUDIO = "should_remove_audio";
|
||||
public static final String SHOULD_REMOVE_VIDEO = "should_remove_video";
|
||||
public static final String SHOULD_FLATTEN_FOR_SLOW_MOTION = "should_flatten_for_slow_motion";
|
||||
public static final String GENERATE_SILENT_AUDIO = "generate_silent_audio";
|
||||
public static final String FORCE_AUDIO_TRACK = "force_audio_track";
|
||||
public static final String AUDIO_MIME_TYPE = "audio_mime_type";
|
||||
public static final String VIDEO_MIME_TYPE = "video_mime_type";
|
||||
public static final String RESOLUTION_HEIGHT = "resolution_height";
|
||||
@ -213,7 +213,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
private @MonotonicNonNull CheckBox removeAudioCheckbox;
|
||||
private @MonotonicNonNull CheckBox removeVideoCheckbox;
|
||||
private @MonotonicNonNull CheckBox flattenForSlowMotionCheckbox;
|
||||
private @MonotonicNonNull CheckBox generateSilentAudioCheckbox;
|
||||
private @MonotonicNonNull CheckBox forceAudioTrackCheckbox;
|
||||
private @MonotonicNonNull Spinner audioMimeSpinner;
|
||||
private @MonotonicNonNull Spinner videoMimeSpinner;
|
||||
private @MonotonicNonNull Spinner resolutionHeightSpinner;
|
||||
@ -274,7 +274,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
|
||||
flattenForSlowMotionCheckbox = findViewById(R.id.flatten_for_slow_motion_checkbox);
|
||||
|
||||
generateSilentAudioCheckbox = findViewById(R.id.generate_silent_audio_checkbox);
|
||||
forceAudioTrackCheckbox = findViewById(R.id.force_audio_track_checkbox);
|
||||
|
||||
ArrayAdapter<String> audioMimeAdapter =
|
||||
new ArrayAdapter<>(/* context= */ this, R.layout.spinner_item);
|
||||
@ -385,7 +385,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
"removeAudioCheckbox",
|
||||
"removeVideoCheckbox",
|
||||
"flattenForSlowMotionCheckbox",
|
||||
"generateSilentAudioCheckbox",
|
||||
"forceAudioTrackCheckbox",
|
||||
"audioMimeSpinner",
|
||||
"videoMimeSpinner",
|
||||
"resolutionHeightSpinner",
|
||||
@ -405,7 +405,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
bundle.putBoolean(SHOULD_REMOVE_AUDIO, removeAudioCheckbox.isChecked());
|
||||
bundle.putBoolean(SHOULD_REMOVE_VIDEO, removeVideoCheckbox.isChecked());
|
||||
bundle.putBoolean(SHOULD_FLATTEN_FOR_SLOW_MOTION, flattenForSlowMotionCheckbox.isChecked());
|
||||
bundle.putBoolean(GENERATE_SILENT_AUDIO, generateSilentAudioCheckbox.isChecked());
|
||||
bundle.putBoolean(FORCE_AUDIO_TRACK, forceAudioTrackCheckbox.isChecked());
|
||||
String selectedAudioMimeType = String.valueOf(audioMimeSpinner.getSelectedItem());
|
||||
if (!SAME_AS_INPUT_OPTION.equals(selectedAudioMimeType)) {
|
||||
bundle.putString(AUDIO_MIME_TYPE, selectedAudioMimeType);
|
||||
@ -739,7 +739,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
|
||||
@RequiresNonNull({
|
||||
"removeVideoCheckbox",
|
||||
"generateSilentAudioCheckbox",
|
||||
"forceAudioTrackCheckbox",
|
||||
"audioMimeSpinner",
|
||||
"videoMimeSpinner",
|
||||
"resolutionHeightSpinner",
|
||||
@ -761,7 +761,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
|
||||
@RequiresNonNull({
|
||||
"removeAudioCheckbox",
|
||||
"generateSilentAudioCheckbox",
|
||||
"forceAudioTrackCheckbox",
|
||||
"audioMimeSpinner",
|
||||
"videoMimeSpinner",
|
||||
"resolutionHeightSpinner",
|
||||
@ -782,7 +782,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
@RequiresNonNull({
|
||||
"generateSilentAudioCheckbox",
|
||||
"forceAudioTrackCheckbox",
|
||||
"audioMimeSpinner",
|
||||
"videoMimeSpinner",
|
||||
"resolutionHeightSpinner",
|
||||
@ -794,7 +794,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
||||
"selectVideoEffectsButton"
|
||||
})
|
||||
private void enableTrackSpecificOptions(boolean isAudioEnabled, boolean isVideoEnabled) {
|
||||
generateSilentAudioCheckbox.setEnabled(isVideoEnabled);
|
||||
forceAudioTrackCheckbox.setEnabled(isVideoEnabled);
|
||||
audioMimeSpinner.setEnabled(isAudioEnabled);
|
||||
videoMimeSpinner.setEnabled(isVideoEnabled);
|
||||
resolutionHeightSpinner.setEnabled(isVideoEnabled);
|
||||
|
@ -82,6 +82,7 @@ import androidx.media3.transformer.Composition;
|
||||
import androidx.media3.transformer.DefaultEncoderFactory;
|
||||
import androidx.media3.transformer.DefaultMuxer;
|
||||
import androidx.media3.transformer.EditedMediaItem;
|
||||
import androidx.media3.transformer.EditedMediaItemSequence;
|
||||
import androidx.media3.transformer.Effects;
|
||||
import androidx.media3.transformer.ExportException;
|
||||
import androidx.media3.transformer.ExportResult;
|
||||
@ -99,6 +100,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -226,9 +229,9 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||
MediaItem mediaItem = createMediaItem(bundle, uri);
|
||||
try {
|
||||
Transformer transformer = createTransformer(bundle, filePath);
|
||||
EditedMediaItem editedMediaItem = createEditedMediaItem(mediaItem, bundle);
|
||||
Composition composition = createComposition(mediaItem, bundle);
|
||||
exportStopwatch.start();
|
||||
transformer.start(editedMediaItem, filePath);
|
||||
transformer.start(composition, filePath);
|
||||
this.transformer = transformer;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
@ -300,13 +303,10 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||
requestBuilder.setHdrMode(bundle.getInt(ConfigurationActivity.HDR_MODE));
|
||||
transformerBuilder.setTransformationRequest(requestBuilder.build());
|
||||
|
||||
transformerBuilder
|
||||
.experimentalSetGenerateSilentAudio(
|
||||
bundle.getBoolean(ConfigurationActivity.GENERATE_SILENT_AUDIO))
|
||||
.setEncoderFactory(
|
||||
new DefaultEncoderFactory.Builder(this.getApplicationContext())
|
||||
.setEnableFallback(bundle.getBoolean(ConfigurationActivity.ENABLE_FALLBACK))
|
||||
.build());
|
||||
transformerBuilder.setEncoderFactory(
|
||||
new DefaultEncoderFactory.Builder(this.getApplicationContext())
|
||||
.setEnableFallback(bundle.getBoolean(ConfigurationActivity.ENABLE_FALLBACK))
|
||||
.build());
|
||||
|
||||
if (!bundle.getBoolean(ConfigurationActivity.ABORT_SLOW_EXPORT)) {
|
||||
transformerBuilder.setMuxerFactory(
|
||||
@ -357,23 +357,28 @@ public final class TransformerActivity extends AppCompatActivity {
|
||||
"exportStopwatch",
|
||||
"progressViewGroup",
|
||||
})
|
||||
private EditedMediaItem createEditedMediaItem(MediaItem mediaItem, @Nullable Bundle bundle)
|
||||
private Composition createComposition(MediaItem mediaItem, @Nullable Bundle bundle)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
EditedMediaItem.Builder editedMediaItemBuilder = new EditedMediaItem.Builder(mediaItem);
|
||||
if (bundle == null) {
|
||||
return editedMediaItemBuilder.build();
|
||||
}
|
||||
// For image inputs. Automatically ignored if input is audio/video.
|
||||
editedMediaItemBuilder.setDurationUs(5_000_000).setFrameRate(30);
|
||||
ImmutableList<AudioProcessor> audioProcessors = createAudioProcessorsFromBundle(bundle);
|
||||
ImmutableList<Effect> videoEffects = createVideoEffectsFromBundle(bundle);
|
||||
return editedMediaItemBuilder
|
||||
.setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO))
|
||||
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO))
|
||||
.setFlattenForSlowMotion(
|
||||
bundle.getBoolean(ConfigurationActivity.SHOULD_FLATTEN_FOR_SLOW_MOTION))
|
||||
.setEffects(new Effects(audioProcessors, videoEffects))
|
||||
.build();
|
||||
boolean forceAudioTrack = false;
|
||||
if (bundle != null) {
|
||||
ImmutableList<AudioProcessor> audioProcessors = createAudioProcessorsFromBundle(bundle);
|
||||
ImmutableList<Effect> videoEffects = createVideoEffectsFromBundle(bundle);
|
||||
editedMediaItemBuilder
|
||||
.setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO))
|
||||
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO))
|
||||
.setFlattenForSlowMotion(
|
||||
bundle.getBoolean(ConfigurationActivity.SHOULD_FLATTEN_FOR_SLOW_MOTION))
|
||||
.setEffects(new Effects(audioProcessors, videoEffects));
|
||||
forceAudioTrack = bundle.getBoolean(ConfigurationActivity.FORCE_AUDIO_TRACK);
|
||||
}
|
||||
List<EditedMediaItem> editedMediaItems = new ArrayList<>();
|
||||
editedMediaItems.add(editedMediaItemBuilder.build());
|
||||
List<EditedMediaItemSequence> sequences = new ArrayList<>();
|
||||
sequences.add(new EditedMediaItemSequence(editedMediaItems));
|
||||
return new Composition(sequences, Effects.EMPTY, forceAudioTrack);
|
||||
}
|
||||
|
||||
private ImmutableList<AudioProcessor> createAudioProcessorsFromBundle(Bundle bundle) {
|
||||
|
@ -116,9 +116,9 @@
|
||||
android:layout_weight="1">
|
||||
<TextView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/generate_silent_audio" />
|
||||
android:text="@string/force_audio_track" />
|
||||
<CheckBox
|
||||
android:id="@+id/generate_silent_audio_checkbox"
|
||||
android:id="@+id/force_audio_track_checkbox"
|
||||
android:layout_gravity="end" />
|
||||
</TableRow>
|
||||
<TableRow
|
||||
|
@ -67,7 +67,7 @@
|
||||
<string name="permission_denied">Permission Denied</string>
|
||||
<string name="hide_input_video">Hide input video</string>
|
||||
<string name="show_input_video">Show input video</string>
|
||||
<string name="generate_silent_audio">Generate silent audio</string>
|
||||
<string name="force_audio_track">Force audio track</string>
|
||||
<string name="overlay_alpha">Alpha</string>
|
||||
<string name="overlay_uri">Uri</string>
|
||||
<string name="bitmap_overlay_settings">Specify bitmap overlay settings</string>
|
||||
|
@ -66,16 +66,15 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
TransformationRequest transformationRequest,
|
||||
boolean flattenForSlowMotion,
|
||||
ImmutableList<AudioProcessor> audioProcessors,
|
||||
long generateSilentAudioDurationUs,
|
||||
long forceAudioTrackDurationUs,
|
||||
Codec.EncoderFactory encoderFactory,
|
||||
MuxerWrapper muxerWrapper,
|
||||
FallbackListener fallbackListener)
|
||||
throws ExportException {
|
||||
super(firstInputFormat, streamStartPositionUs, muxerWrapper);
|
||||
|
||||
if (generateSilentAudioDurationUs != C.TIME_UNSET) {
|
||||
silentAudioGenerator =
|
||||
new SilentAudioGenerator(firstInputFormat, generateSilentAudioDurationUs);
|
||||
if (forceAudioTrackDurationUs != C.TIME_UNSET) {
|
||||
silentAudioGenerator = new SilentAudioGenerator(firstInputFormat, forceAudioTrackDurationUs);
|
||||
} else {
|
||||
silentAudioGenerator = null;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package androidx.media3.transformer;
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
@ -40,16 +41,57 @@ public final class Composition {
|
||||
public final ImmutableList<EditedMediaItemSequence> sequences;
|
||||
/** The {@link Effects} to apply to the composition. */
|
||||
public final Effects effects;
|
||||
/**
|
||||
* Whether the output file should always contain an audio track.
|
||||
*
|
||||
* <ul>
|
||||
* <li>If {@code false}:
|
||||
* <ul>
|
||||
* <li>If the {@link Composition} export doesn't produce any audio at timestamp 0, the
|
||||
* output won't contain any audio, and audio tracks from the {@link MediaItem}
|
||||
* instances in the {@link Composition} will be ignored.
|
||||
* <li>If the {@link Composition} export produces audio at timestamp 0, the output will
|
||||
* contain an audio track.
|
||||
* </ul>
|
||||
* <li>If {@code true}, the output will always contain an audio track.
|
||||
* </ul>
|
||||
*
|
||||
* If the output contains an audio track, silent audio will be generated for the segments where
|
||||
* the {@link Composition} export doesn't produce any audio.
|
||||
*
|
||||
* <p>The MIME type of the output's audio track can be set using {@link
|
||||
* TransformationRequest.Builder#setAudioMimeType(String)}. The sample rate and channel count can
|
||||
* be set by passing relevant {@link AudioProcessor} instances to the {@link Composition}.
|
||||
*
|
||||
* <p>This parameter is experimental and may be removed or changed without warning.
|
||||
*/
|
||||
public final boolean experimentalForceAudioTrack;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* <p>This is equivalent to calling {@link Composition#Composition(List, Effects, boolean)} with
|
||||
* {@link #experimentalForceAudioTrack} set to {@code false}.
|
||||
*/
|
||||
public Composition(List<EditedMediaItemSequence> sequences, Effects effects) {
|
||||
this(sequences, effects, /* experimentalForceAudioTrack= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param sequences The {@link #sequences}.
|
||||
* @param effects The {@link #effects}.
|
||||
* @param experimentalForceAudioTrack Whether to {@linkplain #experimentalForceAudioTrack always
|
||||
* add an audio track in the output}.
|
||||
*/
|
||||
public Composition(List<EditedMediaItemSequence> sequences, Effects effects) {
|
||||
public Composition(
|
||||
List<EditedMediaItemSequence> sequences,
|
||||
Effects effects,
|
||||
boolean experimentalForceAudioTrack) {
|
||||
checkArgument(!sequences.isEmpty());
|
||||
this.sequences = ImmutableList.copyOf(sequences);
|
||||
this.effects = effects;
|
||||
this.experimentalForceAudioTrack = experimentalForceAudioTrack;
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ import androidx.media3.common.MediaLibraryInfo;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.VideoFrameProcessor;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||
import androidx.media3.common.util.Clock;
|
||||
import androidx.media3.common.util.HandlerWrapper;
|
||||
import androidx.media3.common.util.ListenerSet;
|
||||
@ -86,7 +85,6 @@ public final class Transformer {
|
||||
private boolean removeVideo;
|
||||
private boolean flattenForSlowMotion;
|
||||
private boolean transmux;
|
||||
private boolean generateSilentAudio;
|
||||
private ListenerSet<Transformer.Listener> listeners;
|
||||
private AssetLoader.@MonotonicNonNull Factory assetLoaderFactory;
|
||||
private VideoFrameProcessor.Factory videoFrameProcessorFactory;
|
||||
@ -123,7 +121,6 @@ public final class Transformer {
|
||||
this.videoEffects = transformer.videoEffects;
|
||||
this.removeAudio = transformer.removeAudio;
|
||||
this.removeVideo = transformer.removeVideo;
|
||||
this.generateSilentAudio = transformer.generateSilentAudio;
|
||||
this.listeners = transformer.listeners;
|
||||
this.assetLoaderFactory = transformer.assetLoaderFactory;
|
||||
this.videoFrameProcessorFactory = transformer.videoFrameProcessorFactory;
|
||||
@ -395,39 +392,6 @@ public final class Transformer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to generate silent audio for the output file, if there is no audio available.
|
||||
*
|
||||
* <p>This method is experimental and may be removed or changed without warning.
|
||||
*
|
||||
* <p>To replace existing audio with silence, {@linkplain
|
||||
* EditedMediaItem.Builder#setRemoveAudio(boolean) remove the audio} from the {@link
|
||||
* EditedMediaItem} to export.
|
||||
*
|
||||
* <p>Audio properties/format:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Duration will match duration of the input media.
|
||||
* <li>Sample mime type will match {@link TransformationRequest#audioMimeType}, or {@link
|
||||
* MimeTypes#AUDIO_AAC} if {@code null}.
|
||||
* <li>Sample rate will be {@code 44100} Hz. This can be modified by creating a {@link
|
||||
* SonicAudioProcessor}, setting its {@linkplain
|
||||
* SonicAudioProcessor#setOutputSampleRateHz(int) sample rate}, and passing it to the
|
||||
* {@link EditedMediaItem} used to start the export.
|
||||
* <li>Channel count will be {@code 2}. This can be modified by implementing a custom {@link
|
||||
* AudioProcessor} and passing it to the {@link EditedMediaItem} used to start the export.
|
||||
* </ul>
|
||||
*
|
||||
* @param generateSilentAudio Whether to generate silent audio for the output file if there is
|
||||
* no audio track.
|
||||
* @return This builder.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder experimentalSetGenerateSilentAudio(boolean generateSilentAudio) {
|
||||
this.generateSilentAudio = generateSilentAudio;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link Transformer} instance.
|
||||
*
|
||||
@ -461,7 +425,6 @@ public final class Transformer {
|
||||
removeVideo,
|
||||
flattenForSlowMotion,
|
||||
transmux,
|
||||
generateSilentAudio,
|
||||
listeners,
|
||||
assetLoaderFactory,
|
||||
videoFrameProcessorFactory,
|
||||
@ -620,7 +583,6 @@ public final class Transformer {
|
||||
private final boolean removeVideo;
|
||||
private final boolean flattenForSlowMotion;
|
||||
private final boolean transmux;
|
||||
private final boolean generateSilentAudio;
|
||||
private final ListenerSet<Transformer.Listener> listeners;
|
||||
private final AssetLoader.Factory assetLoaderFactory;
|
||||
private final VideoFrameProcessor.Factory videoFrameProcessorFactory;
|
||||
@ -641,7 +603,6 @@ public final class Transformer {
|
||||
boolean removeVideo,
|
||||
boolean flattenForSlowMotion,
|
||||
boolean transmux,
|
||||
boolean generateSilentAudio,
|
||||
ListenerSet<Listener> listeners,
|
||||
AssetLoader.Factory assetLoaderFactory,
|
||||
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
||||
@ -659,7 +620,6 @@ public final class Transformer {
|
||||
this.removeVideo = removeVideo;
|
||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||
this.transmux = transmux;
|
||||
this.generateSilentAudio = generateSilentAudio;
|
||||
this.listeners = listeners;
|
||||
this.assetLoaderFactory = assetLoaderFactory;
|
||||
this.videoFrameProcessorFactory = videoFrameProcessorFactory;
|
||||
@ -779,7 +739,6 @@ public final class Transformer {
|
||||
path,
|
||||
transformationRequest,
|
||||
transmux,
|
||||
generateSilentAudio,
|
||||
assetLoaderFactory,
|
||||
encoderFactory,
|
||||
muxerFactory,
|
||||
|
@ -100,7 +100,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
private final ConditionVariable transformerConditionVariable;
|
||||
private final ExportResult.Builder exportResultBuilder;
|
||||
|
||||
private boolean generateSilentAudio;
|
||||
private boolean forceAudioTrack;
|
||||
private boolean isDrainingPipelines;
|
||||
private @Transformer.ProgressState int progressState;
|
||||
private @MonotonicNonNull RuntimeException cancelException;
|
||||
@ -113,7 +113,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
String outputPath,
|
||||
TransformationRequest transformationRequest,
|
||||
boolean transmux,
|
||||
boolean generateSilentAudio,
|
||||
AssetLoader.Factory assetLoaderFactory,
|
||||
Codec.EncoderFactory encoderFactory,
|
||||
Muxer.Factory muxerFactory,
|
||||
@ -124,7 +123,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
Clock clock) {
|
||||
this.context = context;
|
||||
this.transformationRequest = transformationRequest;
|
||||
this.generateSilentAudio = generateSilentAudio;
|
||||
this.forceAudioTrack = composition.experimentalForceAudioTrack;
|
||||
this.encoderFactory = new CapturingEncoderFactory(encoderFactory);
|
||||
this.listener = listener;
|
||||
this.applicationHandler = applicationHandler;
|
||||
@ -366,11 +365,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
throws ExportException {
|
||||
int trackType = MimeTypes.getTrackType(firstInputFormat.sampleMimeType);
|
||||
if (!trackAdded) {
|
||||
if (generateSilentAudio) {
|
||||
if (forceAudioTrack) {
|
||||
if (trackCount.get() == 1 && trackType == C.TRACK_TYPE_VIDEO) {
|
||||
trackCount.incrementAndGet();
|
||||
} else {
|
||||
generateSilentAudio = false;
|
||||
forceAudioTrack = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +386,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
compositeAssetLoader.addOnMediaItemChangedListener(samplePipeline, trackType);
|
||||
internalHandler.obtainMessage(MSG_REGISTER_SAMPLE_PIPELINE, samplePipeline).sendToTarget();
|
||||
|
||||
if (generateSilentAudio) {
|
||||
if (forceAudioTrack) {
|
||||
Format silentAudioFormat =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(MimeTypes.AUDIO_AAC)
|
||||
@ -479,7 +478,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
transformationRequest,
|
||||
firstEditedMediaItem.flattenForSlowMotion,
|
||||
firstEditedMediaItem.effects.audioProcessors,
|
||||
generateSilentAudio ? durationUs : C.TIME_UNSET,
|
||||
forceAudioTrack ? durationUs : C.TIME_UNSET,
|
||||
encoderFactory,
|
||||
muxerWrapper,
|
||||
fallbackListener);
|
||||
@ -525,7 +524,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
if (!firstEditedMediaItem.effects.audioProcessors.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (generateSilentAudio) {
|
||||
if (forceAudioTrack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -279,14 +279,17 @@ public final class TransformerEndToEndTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void start_silentAudioOnAudioOnly_isIgnored() throws Exception {
|
||||
Transformer transformer =
|
||||
createTransformerBuilder(/* enableFallback= */ false)
|
||||
.experimentalSetGenerateSilentAudio(true)
|
||||
.build();
|
||||
public void start_forceAudioTrackOnAudioOnly_isIgnored() throws Exception {
|
||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER);
|
||||
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
|
||||
EditedMediaItemSequence sequence =
|
||||
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem));
|
||||
Composition composition =
|
||||
new Composition(
|
||||
ImmutableList.of(sequence), Effects.EMPTY, /* experimentalForceAudioTrack= */ true);
|
||||
|
||||
transformer.start(mediaItem, outputPath);
|
||||
transformer.start(composition, outputPath);
|
||||
TransformerTestRunner.runLooper(transformer);
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
@ -294,31 +297,36 @@ public final class TransformerEndToEndTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void start_silentAudioOnAudioVideo_isIgnored() throws Exception {
|
||||
Transformer transformer =
|
||||
createTransformerBuilder(/* enableFallback= */ false)
|
||||
.experimentalSetGenerateSilentAudio(true)
|
||||
.build();
|
||||
public void start_forceAudioTrackOnAudioVideo_isIgnored() throws Exception {
|
||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO);
|
||||
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
|
||||
EditedMediaItemSequence sequence =
|
||||
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem));
|
||||
Composition composition =
|
||||
new Composition(
|
||||
ImmutableList.of(sequence), Effects.EMPTY, /* experimentalForceAudioTrack= */ true);
|
||||
|
||||
transformer.start(mediaItem, outputPath);
|
||||
transformer.start(composition, outputPath);
|
||||
TransformerTestRunner.runLooper(transformer);
|
||||
|
||||
DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void start_silentAudioRemoveAudio_completesSuccessfully() throws Exception {
|
||||
Transformer transformer =
|
||||
createTransformerBuilder(/* enableFallback= */ false)
|
||||
.experimentalSetGenerateSilentAudio(true)
|
||||
.build();
|
||||
public void start_forceAudioTrackAndRemoveAudio_generatesSilentAudio() throws Exception {
|
||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||
EditedMediaItem editedMediaItem =
|
||||
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO))
|
||||
.setRemoveAudio(true)
|
||||
.build();
|
||||
EditedMediaItemSequence sequence =
|
||||
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem));
|
||||
Composition composition =
|
||||
new Composition(
|
||||
ImmutableList.of(sequence), Effects.EMPTY, /* experimentalForceAudioTrack= */ true);
|
||||
|
||||
transformer.start(editedMediaItem, outputPath);
|
||||
transformer.start(composition, outputPath);
|
||||
TransformerTestRunner.runLooper(transformer);
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
@ -326,31 +334,36 @@ public final class TransformerEndToEndTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void start_silentAudioRemoveVideo_isIgnored() throws Exception {
|
||||
Transformer transformer =
|
||||
createTransformerBuilder(/* enableFallback= */ false)
|
||||
.experimentalSetGenerateSilentAudio(true)
|
||||
.build();
|
||||
public void start_forceAudioTrackAndRemoveVideo_isIgnored() throws Exception {
|
||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||
EditedMediaItem editedMediaItem =
|
||||
new EditedMediaItem.Builder(MediaItem.fromUri(ASSET_URI_PREFIX + FILE_AUDIO_VIDEO))
|
||||
.setRemoveVideo(true)
|
||||
.build();
|
||||
EditedMediaItemSequence sequence =
|
||||
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem));
|
||||
Composition composition =
|
||||
new Composition(
|
||||
ImmutableList.of(sequence), Effects.EMPTY, /* experimentalForceAudioTrack= */ true);
|
||||
|
||||
transformer.start(editedMediaItem, outputPath);
|
||||
transformer.start(composition, outputPath);
|
||||
TransformerTestRunner.runLooper(transformer);
|
||||
DumpFileAsserts.assertOutput(
|
||||
context, testMuxer, getDumpFileName(FILE_AUDIO_VIDEO + ".novideo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void start_silentAudioOnVideoOnly_completesSuccessfully() throws Exception {
|
||||
Transformer transformer =
|
||||
createTransformerBuilder(/* enableFallback= */ false)
|
||||
.experimentalSetGenerateSilentAudio(true)
|
||||
.build();
|
||||
public void start_forceAudioTrackOnVideoOnly_generatesSilentAudio() throws Exception {
|
||||
Transformer transformer = createTransformerBuilder(/* enableFallback= */ false).build();
|
||||
MediaItem mediaItem = MediaItem.fromUri(ASSET_URI_PREFIX + FILE_VIDEO_ONLY);
|
||||
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem).build();
|
||||
EditedMediaItemSequence sequence =
|
||||
new EditedMediaItemSequence(ImmutableList.of(editedMediaItem));
|
||||
Composition composition =
|
||||
new Composition(
|
||||
ImmutableList.of(sequence), Effects.EMPTY, /* experimentalForceAudioTrack= */ true);
|
||||
|
||||
transformer.start(mediaItem, outputPath);
|
||||
transformer.start(composition, outputPath);
|
||||
TransformerTestRunner.runLooper(transformer);
|
||||
|
||||
DumpFileAsserts.assertOutput(
|
||||
|
Loading…
x
Reference in New Issue
Block a user