Remove most nullness marking from Transformer demos

The nullness checking is very verbose and redundant in some places, for
example, the ensures-non-null marking in the transformer activity, and it makes
changing features in the demo app more time consuming. The cost/benefit balance
seems to be in favor of removing this for demo code.

Note: the ExoPlayer main demo has nullness checks turned off.
PiperOrigin-RevId: 641890618
This commit is contained in:
andrewlewis 2024-06-10 07:11:03 -07:00 committed by Copybara-Service
parent 253fcb1fd1
commit cc046d5ce7
3 changed files with 127 additions and 293 deletions

View File

@ -15,10 +15,6 @@
*/
package androidx.media3.demo.composition;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Assertions.checkStateNotNull;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
@ -59,7 +55,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.json.JSONException;
import org.json.JSONObject;
@ -70,18 +65,17 @@ import org.json.JSONObject;
public final class CompositionPreviewActivity extends AppCompatActivity {
private static final String TAG = "CompPreviewActivity";
private final ArrayList<String> sequenceAssetTitles = new ArrayList<>();
@Nullable private boolean[] selectedMediaItems = null;
private String[] presetDescriptions = new String[0];
@Nullable private AssetItemAdapter assetItemAdapter;
private ArrayList<String> sequenceAssetTitles;
private boolean[] selectedMediaItems;
private String[] presetDescriptions;
private AssetItemAdapter assetItemAdapter;
@Nullable private CompositionPlayer compositionPlayer;
@Nullable private Transformer transformer;
@Nullable private File outputFile;
private @MonotonicNonNull PlayerView playerView;
private @MonotonicNonNull AppCompatButton exportButton;
private @MonotonicNonNull AppCompatTextView exportInformationTextView;
private @MonotonicNonNull Stopwatch exportStopwatch;
private PlayerView playerView;
private AppCompatButton exportButton;
private AppCompatTextView exportInformationTextView;
private Stopwatch exportStopwatch;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -106,8 +100,9 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
selectedMediaItems = new boolean[presetDescriptions.length];
selectedMediaItems[0] = true;
selectedMediaItems[2] = true;
for (int i = 0; i < checkNotNull(selectedMediaItems).length; i++) {
if (checkNotNull(selectedMediaItems)[i]) {
sequenceAssetTitles = new ArrayList<>();
for (int i = 0; i < selectedMediaItems.length; i++) {
if (selectedMediaItems[i]) {
sequenceAssetTitles.add(presetDescriptions[i]);
}
}
@ -127,38 +122,27 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
@Override
protected void onStart() {
super.onStart();
checkStateNotNull(playerView).onResume();
playerView.onResume();
}
@Override
protected void onStop() {
super.onStop();
checkStateNotNull(playerView).onPause();
playerView.onPause();
releasePlayer();
cancelExport();
checkStateNotNull(exportStopwatch).reset();
exportStopwatch.reset();
}
private Composition prepareComposition() {
// Reading from resources here does not create a performance bottleneck, this
// method is called as part of more expensive operations.
String[] presetUris = getResources().getStringArray(/* id= */ R.array.preset_uris);
checkState(
/* expression= */ checkStateNotNull(presetUris).length == presetDescriptions.length,
/* errorMessage= */ "Unexpected array length "
+ getResources().getResourceName(R.array.preset_uris));
int[] presetDurationsUs = getResources().getIntArray(/* id= */ R.array.preset_durations);
checkState(
/* expression= */ checkStateNotNull(presetDurationsUs).length == presetDescriptions.length,
/* errorMessage= */ "Unexpected array length "
+ getResources().getResourceName(R.array.preset_durations));
List<EditedMediaItem> mediaItems = new ArrayList<>();
ImmutableList<Effect> effects =
ImmutableList.of(
MatrixTransformationFactory.createDizzyCropEffect(), RgbFilter.createGrayscaleFilter());
for (int i = 0; i < checkNotNull(selectedMediaItems).length; i++) {
if (checkNotNull(selectedMediaItems)[i]) {
for (int i = 0; i < selectedMediaItems.length; i++) {
if (selectedMediaItems[i]) {
SonicAudioProcessor pitchChanger = new SonicAudioProcessor();
pitchChanger.setPitch(mediaItems.size() % 2 == 0 ? 2f : 0.2f);
MediaItem mediaItem =
@ -190,12 +174,12 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
private void previewComposition(View view) {
releasePlayer();
Composition composition = prepareComposition();
checkStateNotNull(playerView).setPlayer(null);
playerView.setPlayer(null);
CompositionPlayer player = new CompositionPlayer.Builder(getApplicationContext()).build();
this.compositionPlayer = player;
checkStateNotNull(playerView).setPlayer(compositionPlayer);
checkStateNotNull(playerView).setControllerAutoShow(false);
playerView.setPlayer(compositionPlayer);
playerView.setControllerAutoShow(false);
player.addListener(
new Player.Listener() {
@Override
@ -213,8 +197,7 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
private void selectPreset(View view) {
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.select_preset_title)
.setMultiChoiceItems(
presetDescriptions, checkNotNull(selectedMediaItems), this::selectPresetInDialog)
.setMultiChoiceItems(presetDescriptions, selectedMediaItems, this::selectPresetInDialog)
.setPositiveButton(android.R.string.ok, /* listener= */ null)
.setCancelable(false)
.create()
@ -222,18 +205,15 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
}
private void selectPresetInDialog(DialogInterface dialog, int which, boolean isChecked) {
if (selectedMediaItems == null) {
return;
}
selectedMediaItems[which] = isChecked;
// The items will be added to a the sequence in the order they were selected.
if (isChecked) {
sequenceAssetTitles.add(presetDescriptions[which]);
checkNotNull(assetItemAdapter).notifyItemInserted(sequenceAssetTitles.size() - 1);
assetItemAdapter.notifyItemInserted(sequenceAssetTitles.size() - 1);
} else {
int index = sequenceAssetTitles.indexOf(presetDescriptions[which]);
sequenceAssetTitles.remove(presetDescriptions[which]);
checkNotNull(assetItemAdapter).notifyItemRemoved(index);
assetItemAdapter.notifyItemRemoved(index);
}
}
@ -253,23 +233,23 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
"Aborting export! Unable to create output file: " + e,
Toast.LENGTH_LONG)
.show();
Log.e(TAG, "Aborting export! Unable to create output file: " + e);
Log.e(TAG, "Aborting export! Unable to create output file: ", e);
return;
}
String filePath = outputFile.getAbsolutePath();
transformer =
new Transformer.Builder(this)
new Transformer.Builder(/* context= */ this)
.addListener(
new Transformer.Listener() {
@Override
public void onCompleted(Composition composition, ExportResult exportResult) {
checkStateNotNull(exportStopwatch).stop();
exportStopwatch.stop();
long elapsedTimeMs = exportStopwatch.elapsed(TimeUnit.MILLISECONDS);
String details =
getString(R.string.export_completed, elapsedTimeMs / 1000.f, filePath);
Log.i(TAG, details);
checkStateNotNull(exportInformationTextView).setText(details);
exportInformationTextView.setText(details);
try {
JSONObject resultJson =
@ -289,22 +269,22 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
Composition composition,
ExportResult exportResult,
ExportException exportException) {
checkStateNotNull(exportStopwatch).stop();
exportStopwatch.stop();
Toast.makeText(
getApplicationContext(),
"Export error: " + exportException,
Toast.LENGTH_LONG)
.show();
Log.e(TAG, "Export error", exportException);
checkStateNotNull(exportInformationTextView).setText(R.string.export_error);
exportInformationTextView.setText(R.string.export_error);
}
})
.build();
checkStateNotNull(exportInformationTextView).setText(R.string.export_started);
checkStateNotNull(exportStopwatch).reset();
exportInformationTextView.setText(R.string.export_started);
exportStopwatch.reset();
exportStopwatch.start();
checkStateNotNull(transformer).start(composition, filePath);
transformer.start(composition, filePath);
Log.i(TAG, "Export started");
}
@ -325,7 +305,7 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
outputFile.delete();
outputFile = null;
}
checkStateNotNull(exportInformationTextView).setText("");
exportInformationTextView.setText("");
}
/**

View File

@ -17,7 +17,6 @@ package androidx.media3.demo.transformer;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_MEDIA_VIDEO;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.SDK_INT;
import static androidx.media3.transformer.Composition.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR;
@ -56,8 +55,6 @@ import com.google.android.material.slider.Slider;
import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.List;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
/**
* An {@link Activity} that sets the configuration to use for exporting and playing media, using
@ -154,35 +151,35 @@ public final class ConfigurationActivity extends AppCompatActivity {
private static final String SAME_AS_INPUT_OPTION = "same as input";
private static final float HALF_DIAGONAL = 1f / (float) Math.sqrt(2);
private @MonotonicNonNull Runnable onPermissionsGranted;
private @MonotonicNonNull ActivityResultLauncher<Intent> videoLocalFilePickerLauncher;
private @MonotonicNonNull ActivityResultLauncher<Intent> overlayLocalFilePickerLauncher;
private @MonotonicNonNull Button selectPresetFileButton;
private @MonotonicNonNull Button selectLocalFileButton;
private @MonotonicNonNull TextView selectedFileTextView;
private @MonotonicNonNull CheckBox removeAudioCheckbox;
private @MonotonicNonNull CheckBox removeVideoCheckbox;
private @MonotonicNonNull CheckBox flattenForSlowMotionCheckbox;
private @MonotonicNonNull CheckBox forceAudioTrackCheckbox;
private @MonotonicNonNull Spinner audioMimeSpinner;
private @MonotonicNonNull Spinner videoMimeSpinner;
private @MonotonicNonNull Spinner resolutionHeightSpinner;
private @MonotonicNonNull Spinner scaleSpinner;
private @MonotonicNonNull Spinner rotateSpinner;
private @MonotonicNonNull CheckBox trimCheckBox;
private @MonotonicNonNull CheckBox enableFallbackCheckBox;
private @MonotonicNonNull CheckBox enableAnalyzerModeCheckBox;
private @MonotonicNonNull CheckBox enableDebugPreviewCheckBox;
private @MonotonicNonNull CheckBox enableDebugTracingCheckBox;
private @MonotonicNonNull CheckBox abortSlowExportCheckBox;
private @MonotonicNonNull CheckBox produceFragmentedMp4CheckBox;
private @MonotonicNonNull Spinner hdrModeSpinner;
private @MonotonicNonNull Button selectAudioEffectsButton;
private @MonotonicNonNull Button selectVideoEffectsButton;
private boolean @MonotonicNonNull [] audioEffectsSelections;
private boolean @MonotonicNonNull [] videoEffectsSelections;
private String[] presetFileDescriptions = new String[0];
private @Nullable Uri localFileUri;
private Runnable onPermissionsGranted;
private ActivityResultLauncher<Intent> videoLocalFilePickerLauncher;
private ActivityResultLauncher<Intent> overlayLocalFilePickerLauncher;
private Button selectPresetFileButton;
private Button selectLocalFileButton;
private TextView selectedFileTextView;
private CheckBox removeAudioCheckbox;
private CheckBox removeVideoCheckbox;
private CheckBox flattenForSlowMotionCheckbox;
private CheckBox forceAudioTrackCheckbox;
private Spinner audioMimeSpinner;
private Spinner videoMimeSpinner;
private Spinner resolutionHeightSpinner;
private Spinner scaleSpinner;
private Spinner rotateSpinner;
private CheckBox trimCheckBox;
private CheckBox enableFallbackCheckBox;
private CheckBox enableAnalyzerModeCheckBox;
private CheckBox enableDebugPreviewCheckBox;
private CheckBox enableDebugTracingCheckBox;
private CheckBox abortSlowExportCheckBox;
private CheckBox produceFragmentedMp4CheckBox;
private Spinner hdrModeSpinner;
private Button selectAudioEffectsButton;
private Button selectVideoEffectsButton;
private boolean[] audioEffectsSelections;
private boolean[] videoEffectsSelections;
private String[] presetFileDescriptions;
private Uri localFileUri;
private int inputUriPosition;
private long trimStartMs;
private long trimEndMs;
@ -198,9 +195,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
private float periodicVignetteCenterY;
private float periodicVignetteInnerRadius;
private float periodicVignetteOuterRadius;
private @MonotonicNonNull String bitmapOverlayUri;
private String bitmapOverlayUri;
private float bitmapOverlayAlpha;
private @MonotonicNonNull String textOverlayText;
private String textOverlayText;
private int textOverlayTextColor;
private float textOverlayAlpha;
@ -227,7 +224,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
selectLocalFileButton.setOnClickListener(
view ->
selectLocalFile(
checkNotNull(videoLocalFilePickerLauncher),
videoLocalFilePickerLauncher,
/* mimeTypes= */ new String[] {"image/*", "video/*", "audio/*"}));
selectedFileTextView = findViewById(R.id.selected_file_text_view);
@ -331,7 +328,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
if (requestCode == FILE_PERMISSION_REQUEST_CODE
&& grantResults.length == 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
checkNotNull(onPermissionsGranted).run();
onPermissionsGranted.run();
} else {
Toast.makeText(
getApplicationContext(), getString(R.string.permission_denied), Toast.LENGTH_LONG)
@ -344,9 +341,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
super.onResume();
@Nullable Uri intentUri = getIntent().getData();
if (intentUri != null) {
checkNotNull(selectPresetFileButton).setEnabled(false);
checkNotNull(selectLocalFileButton).setEnabled(false);
checkNotNull(selectedFileTextView).setText(intentUri.toString());
selectPresetFileButton.setEnabled(false);
selectLocalFileButton.setEnabled(false);
selectedFileTextView.setText(intentUri.toString());
}
}
@ -356,26 +353,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
setIntent(intent);
}
@RequiresNonNull({
"removeAudioCheckbox",
"removeVideoCheckbox",
"flattenForSlowMotionCheckbox",
"forceAudioTrackCheckbox",
"audioMimeSpinner",
"videoMimeSpinner",
"resolutionHeightSpinner",
"scaleSpinner",
"rotateSpinner",
"trimCheckBox",
"enableFallbackCheckBox",
"enableAnalyzerModeCheckBox",
"enableDebugPreviewCheckBox",
"abortSlowExportCheckBox",
"produceFragmentedMp4CheckBox",
"hdrModeSpinner",
"audioEffectsSelections",
"videoEffectsSelections"
})
private void startExport(View view) {
Intent transformerIntent = new Intent(/* packageContext= */ this, TransformerActivity.class);
Bundle bundle = new Bundle();
@ -415,8 +392,8 @@ public final class ConfigurationActivity extends AppCompatActivity {
bundle.putBoolean(ENABLE_DEBUG_PREVIEW, enableDebugPreviewCheckBox.isChecked());
bundle.putBoolean(ABORT_SLOW_EXPORT, abortSlowExportCheckBox.isChecked());
bundle.putBoolean(PRODUCE_FRAGMENTED_MP4, produceFragmentedMp4CheckBox.isChecked());
String selectedhdrMode = String.valueOf(hdrModeSpinner.getSelectedItem());
bundle.putInt(HDR_MODE, checkNotNull(HDR_MODE_DESCRIPTIONS.get(selectedhdrMode)));
String selectedHdrMode = String.valueOf(hdrModeSpinner.getSelectedItem());
bundle.putInt(HDR_MODE, HDR_MODE_DESCRIPTIONS.get(selectedHdrMode));
bundle.putBooleanArray(AUDIO_EFFECTS_SELECTIONS, audioEffectsSelections);
bundle.putBooleanArray(VIDEO_EFFECTS_SELECTIONS, videoEffectsSelections);
bundle.putInt(COLOR_FILTER_SELECTION, colorFilterSelection);
@ -462,7 +439,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
.show();
}
@RequiresNonNull("selectedFileTextView")
private void selectPresetFileInDialog(DialogInterface dialog, int which) {
inputUriPosition = which;
localFileUri = null;
@ -487,14 +463,13 @@ public final class ConfigurationActivity extends AppCompatActivity {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
checkNotNull(localFilePickerLauncher).launch(intent);
localFilePickerLauncher.launch(intent);
}
@RequiresNonNull("selectedFileTextView")
private void videoLocalFilePickerLauncherResult(ActivityResult result) {
Intent data = result.getData();
if (data != null) {
localFileUri = checkNotNull(data.getData());
localFileUri = data.getData();
selectedFileTextView.setText(localFileUri.toString());
} else {
Toast.makeText(
@ -508,7 +483,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void overlayLocalFilePickerLauncherResult(ActivityResult result) {
Intent data = result.getData();
if (data != null) {
bitmapOverlayUri = checkNotNull(data.getData()).toString();
bitmapOverlayUri = data.getData().toString();
} else {
Toast.makeText(
getApplicationContext(),
@ -521,8 +496,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void selectAudioEffects(View view, String[] audioEffectsNames) {
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.select_audio_effects)
.setMultiChoiceItems(
audioEffectsNames, checkNotNull(audioEffectsSelections), this::selectAudioEffect)
.setMultiChoiceItems(audioEffectsNames, audioEffectsSelections, this::selectAudioEffect)
.setPositiveButton(android.R.string.ok, /* listener= */ null)
.create()
.show();
@ -531,8 +505,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void selectVideoEffects(View view, String[] videoEffectsNames) {
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.select_video_effects)
.setMultiChoiceItems(
videoEffectsNames, checkNotNull(videoEffectsSelections), this::selectVideoEffect)
.setMultiChoiceItems(videoEffectsNames, videoEffectsSelections, this::selectVideoEffect)
.setPositiveButton(android.R.string.ok, /* listener= */ null)
.create()
.show();
@ -543,8 +516,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
return;
}
View dialogView = getLayoutInflater().inflate(R.layout.trim_options, /* root= */ null);
RangeSlider trimRangeSlider =
checkNotNull(dialogView.findViewById(R.id.trim_bounds_range_slider));
RangeSlider trimRangeSlider = dialogView.findViewById(R.id.trim_bounds_range_slider);
trimRangeSlider.setValues(0f, 1f); // seconds
new AlertDialog.Builder(/* context= */ this)
.setView(dialogView)
@ -559,12 +531,10 @@ public final class ConfigurationActivity extends AppCompatActivity {
.show();
}
@RequiresNonNull("audioEffectsSelections")
private void selectAudioEffect(DialogInterface dialog, int which, boolean isChecked) {
audioEffectsSelections[which] = isChecked;
}
@RequiresNonNull("videoEffectsSelections")
private void selectVideoEffect(DialogInterface dialog, int which, boolean isChecked) {
videoEffectsSelections[which] = isChecked;
if (!isChecked) {
@ -617,10 +587,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void controlRgbAdjustmentsScale() {
View dialogView =
getLayoutInflater().inflate(R.layout.rgb_adjustment_options, /* root= */ null);
Slider redScaleSlider = checkNotNull(dialogView.findViewById(R.id.rgb_adjustment_red_scale));
Slider greenScaleSlider =
checkNotNull(dialogView.findViewById(R.id.rgb_adjustment_green_scale));
Slider blueScaleSlider = checkNotNull(dialogView.findViewById(R.id.rgb_adjustment_blue_scale));
Slider redScaleSlider = dialogView.findViewById(R.id.rgb_adjustment_red_scale);
Slider greenScaleSlider = dialogView.findViewById(R.id.rgb_adjustment_green_scale);
Slider blueScaleSlider = dialogView.findViewById(R.id.rgb_adjustment_blue_scale);
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.rgb_adjustment_options)
.setView(dialogView)
@ -637,7 +606,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void controlContrastSettings() {
View dialogView = getLayoutInflater().inflate(R.layout.contrast_options, /* root= */ null);
Slider contrastSlider = checkNotNull(dialogView.findViewById(R.id.contrast_slider));
Slider contrastSlider = dialogView.findViewById(R.id.contrast_slider);
new AlertDialog.Builder(/* context= */ this)
.setView(dialogView)
.setPositiveButton(
@ -650,11 +619,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void controlHslAdjustmentSettings() {
View dialogView =
getLayoutInflater().inflate(R.layout.hsl_adjustment_options, /* root= */ null);
Slider hueAdjustmentSlider = checkNotNull(dialogView.findViewById(R.id.hsl_adjustments_hue));
Slider saturationAdjustmentSlider =
checkNotNull(dialogView.findViewById(R.id.hsl_adjustments_saturation));
Slider lightnessAdjustmentSlider =
checkNotNull(dialogView.findViewById(R.id.hsl_adjustment_lightness));
Slider hueAdjustmentSlider = dialogView.findViewById(R.id.hsl_adjustments_hue);
Slider saturationAdjustmentSlider = dialogView.findViewById(R.id.hsl_adjustments_saturation);
Slider lightnessAdjustmentSlider = dialogView.findViewById(R.id.hsl_adjustment_lightness);
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.hsl_adjustment_options)
.setView(dialogView)
@ -672,12 +639,10 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void controlPeriodicVignetteSettings() {
View dialogView =
getLayoutInflater().inflate(R.layout.periodic_vignette_options, /* root= */ null);
Slider centerXSlider =
checkNotNull(dialogView.findViewById(R.id.periodic_vignette_center_x_slider));
Slider centerYSlider =
checkNotNull(dialogView.findViewById(R.id.periodic_vignette_center_y_slider));
Slider centerXSlider = dialogView.findViewById(R.id.periodic_vignette_center_x_slider);
Slider centerYSlider = dialogView.findViewById(R.id.periodic_vignette_center_y_slider);
RangeSlider radiusRangeSlider =
checkNotNull(dialogView.findViewById(R.id.periodic_vignette_radius_range_slider));
dialogView.findViewById(R.id.periodic_vignette_radius_range_slider);
radiusRangeSlider.setValues(0f, HALF_DIAGONAL);
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.periodic_vignette_options)
@ -698,13 +663,12 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void controlBitmapOverlaySettings() {
View dialogView =
getLayoutInflater().inflate(R.layout.bitmap_overlay_options, /* root= */ null);
Button uriButton = checkNotNull(dialogView.findViewById(R.id.bitmap_overlay_uri));
Button uriButton = dialogView.findViewById(R.id.bitmap_overlay_uri);
uriButton.setOnClickListener(
(view ->
selectLocalFile(
checkNotNull(overlayLocalFilePickerLauncher),
/* mimeTypes= */ new String[] {"image/*"})));
Slider alphaSlider = checkNotNull(dialogView.findViewById(R.id.bitmap_overlay_alpha_slider));
overlayLocalFilePickerLauncher, /* mimeTypes= */ new String[] {"image/*"})));
Slider alphaSlider = dialogView.findViewById(R.id.bitmap_overlay_alpha_slider);
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.bitmap_overlay_settings)
.setView(dialogView)
@ -719,16 +683,16 @@ public final class ConfigurationActivity extends AppCompatActivity {
private void controlTextOverlaySettings() {
View dialogView = getLayoutInflater().inflate(R.layout.text_overlay_options, /* root= */ null);
EditText textEditText = checkNotNull(dialogView.findViewById(R.id.text_overlay_text));
EditText textEditText = dialogView.findViewById(R.id.text_overlay_text);
ArrayAdapter<String> textColorAdapter =
new ArrayAdapter<>(/* context= */ this, R.layout.spinner_item);
textColorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner textColorSpinner = checkNotNull(dialogView.findViewById(R.id.text_overlay_text_color));
Spinner textColorSpinner = dialogView.findViewById(R.id.text_overlay_text_color);
textColorSpinner.setAdapter(textColorAdapter);
textColorAdapter.addAll(OVERLAY_COLORS.keySet());
Slider alphaSlider = checkNotNull(dialogView.findViewById(R.id.text_overlay_alpha_slider));
Slider alphaSlider = dialogView.findViewById(R.id.text_overlay_alpha_slider);
new AlertDialog.Builder(/* context= */ this)
.setTitle(R.string.bitmap_overlay_settings)
.setView(dialogView)
@ -737,26 +701,13 @@ public final class ConfigurationActivity extends AppCompatActivity {
(DialogInterface dialogInterface, int i) -> {
textOverlayText = textEditText.getText().toString();
String selectedTextColor = String.valueOf(textColorSpinner.getSelectedItem());
textOverlayTextColor = checkNotNull(OVERLAY_COLORS.get(selectedTextColor));
textOverlayTextColor = OVERLAY_COLORS.get(selectedTextColor);
textOverlayAlpha = alphaSlider.getValue();
})
.create()
.show();
}
@RequiresNonNull({
"removeVideoCheckbox",
"forceAudioTrackCheckbox",
"audioMimeSpinner",
"videoMimeSpinner",
"resolutionHeightSpinner",
"scaleSpinner",
"rotateSpinner",
"enableDebugPreviewCheckBox",
"hdrModeSpinner",
"selectAudioEffectsButton",
"selectVideoEffectsButton"
})
private void onRemoveAudio(View view) {
if (((CheckBox) view).isChecked()) {
removeVideoCheckbox.setChecked(false);
@ -766,19 +717,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
}
}
@RequiresNonNull({
"removeAudioCheckbox",
"forceAudioTrackCheckbox",
"audioMimeSpinner",
"videoMimeSpinner",
"resolutionHeightSpinner",
"scaleSpinner",
"rotateSpinner",
"enableDebugPreviewCheckBox",
"hdrModeSpinner",
"selectAudioEffectsButton",
"selectVideoEffectsButton"
})
private void onRemoveVideo(View view) {
if (((CheckBox) view).isChecked()) {
removeAudioCheckbox.setChecked(false);
@ -788,18 +726,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
}
}
@RequiresNonNull({
"forceAudioTrackCheckbox",
"audioMimeSpinner",
"videoMimeSpinner",
"resolutionHeightSpinner",
"scaleSpinner",
"rotateSpinner",
"enableDebugPreviewCheckBox",
"hdrModeSpinner",
"selectAudioEffectsButton",
"selectVideoEffectsButton"
})
private void enableTrackSpecificOptions(boolean isAudioEnabled, boolean isVideoEnabled) {
forceAudioTrackCheckbox.setEnabled(isVideoEnabled);
audioMimeSpinner.setEnabled(isAudioEnabled);

View File

@ -112,8 +112,6 @@ import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
import org.json.JSONException;
import org.json.JSONObject;
@ -121,21 +119,21 @@ import org.json.JSONObject;
public final class TransformerActivity extends AppCompatActivity {
private static final String TAG = "TransformerActivity";
private @MonotonicNonNull Button displayInputButton;
private @MonotonicNonNull MaterialCardView inputCardView;
private @MonotonicNonNull TextView inputTextView;
private @MonotonicNonNull ImageView inputImageView;
private @MonotonicNonNull PlayerView inputPlayerView;
private @MonotonicNonNull PlayerView outputPlayerView;
private @MonotonicNonNull TextView outputVideoTextView;
private @MonotonicNonNull TextView debugTextView;
private @MonotonicNonNull TextView informationTextView;
private @MonotonicNonNull ViewGroup progressViewGroup;
private @MonotonicNonNull LinearProgressIndicator progressIndicator;
private @MonotonicNonNull Button cancelButton;
private @MonotonicNonNull Button resumeButton;
private @MonotonicNonNull Stopwatch exportStopwatch;
private @MonotonicNonNull AspectRatioFrameLayout debugFrame;
private Button displayInputButton;
private MaterialCardView inputCardView;
private TextView inputTextView;
private ImageView inputImageView;
private PlayerView inputPlayerView;
private PlayerView outputPlayerView;
private TextView outputVideoTextView;
private TextView debugTextView;
private TextView informationTextView;
private ViewGroup progressViewGroup;
private LinearProgressIndicator progressIndicator;
private Button cancelButton;
private Button resumeButton;
private Stopwatch exportStopwatch;
private AspectRatioFrameLayout debugFrame;
@Nullable private DebugTextViewHelper debugTextViewHelper;
@Nullable private ExoPlayer inputPlayer;
@ -183,8 +181,8 @@ public final class TransformerActivity extends AppCompatActivity {
startExport();
checkNotNull(inputPlayerView).onResume();
checkNotNull(outputPlayerView).onResume();
inputPlayerView.onResume();
outputPlayerView.onResume();
}
@Override
@ -198,13 +196,13 @@ public final class TransformerActivity extends AppCompatActivity {
// The stop watch is reset after cancelling the export, in case cancelling causes the stop watch
// to be stopped in a transformer callback.
checkNotNull(exportStopwatch).reset();
exportStopwatch.reset();
checkNotNull(inputPlayerView).onPause();
checkNotNull(outputPlayerView).onPause();
inputPlayerView.onPause();
outputPlayerView.onPause();
releasePlayer();
checkNotNull(outputFile).delete();
outputFile.delete();
outputFile = null;
if (oldOutputFile != null) {
oldOutputFile.delete();
@ -213,22 +211,6 @@ public final class TransformerActivity extends AppCompatActivity {
}
private void startExport() {
checkNotNull(progressIndicator);
checkNotNull(informationTextView);
checkNotNull(exportStopwatch);
checkNotNull(inputCardView);
checkNotNull(inputTextView);
checkNotNull(inputImageView);
checkNotNull(inputPlayerView);
checkNotNull(outputPlayerView);
checkNotNull(outputVideoTextView);
checkNotNull(debugTextView);
checkNotNull(progressViewGroup);
checkNotNull(debugFrame);
checkNotNull(displayInputButton);
checkNotNull(cancelButton);
checkNotNull(resumeButton);
requestReadVideoPermission(/* activity= */ this);
Intent intent = getIntent();
@ -297,20 +279,6 @@ public final class TransformerActivity extends AppCompatActivity {
return mediaItemBuilder.build();
}
@RequiresNonNull({
"inputCardView",
"inputTextView",
"inputImageView",
"inputPlayerView",
"outputPlayerView",
"outputVideoTextView",
"displayInputButton",
"debugTextView",
"informationTextView",
"exportStopwatch",
"progressViewGroup",
"debugFrame",
})
private Transformer createTransformer(@Nullable Bundle bundle, Uri inputUri, String filePath) {
Transformer.Builder transformerBuilder =
new Transformer.Builder(/* context= */ this)
@ -380,12 +348,6 @@ public final class TransformerActivity extends AppCompatActivity {
return file;
}
@RequiresNonNull({
"inputCardView",
"outputPlayerView",
"exportStopwatch",
"progressViewGroup",
})
private Composition createComposition(MediaItem mediaItem, @Nullable Bundle bundle) {
EditedMediaItem.Builder editedMediaItemBuilder = new EditedMediaItem.Builder(mediaItem);
// For image inputs. Automatically ignored if input is audio/video.
@ -657,7 +619,7 @@ public final class TransformerActivity extends AppCompatActivity {
BitmapOverlay bitmapOverlay =
BitmapOverlay.createStaticBitmapOverlay(
getApplicationContext(),
Uri.parse(checkNotNull(bundle.getString(ConfigurationActivity.BITMAP_OVERLAY_URI))),
Uri.parse(bundle.getString(ConfigurationActivity.BITMAP_OVERLAY_URI)),
overlaySettings);
overlaysBuilder.add(bitmapOverlay);
}
@ -668,8 +630,7 @@ public final class TransformerActivity extends AppCompatActivity {
bundle.getFloat(ConfigurationActivity.TEXT_OVERLAY_ALPHA, /* defaultValue= */ 1))
.build();
SpannableString overlayText =
new SpannableString(
checkNotNull(bundle.getString(ConfigurationActivity.TEXT_OVERLAY_TEXT)));
new SpannableString(bundle.getString(ConfigurationActivity.TEXT_OVERLAY_TEXT));
overlayText.setSpan(
new ForegroundColorSpan(bundle.getInt(ConfigurationActivity.TEXT_OVERLAY_TEXT_COLOR)),
/* start= */ 0,
@ -683,12 +644,6 @@ public final class TransformerActivity extends AppCompatActivity {
return overlays.isEmpty() ? null : new OverlayEffect(overlays);
}
@RequiresNonNull({
"informationTextView",
"progressViewGroup",
"debugFrame",
"exportStopwatch",
})
private void onError(ExportException exportException) {
exportStopwatch.stop();
informationTextView.setText(R.string.export_error);
@ -699,20 +654,6 @@ public final class TransformerActivity extends AppCompatActivity {
Log.e(TAG, "Export error", exportException);
}
@RequiresNonNull({
"inputCardView",
"inputTextView",
"inputImageView",
"inputPlayerView",
"outputPlayerView",
"outputVideoTextView",
"debugTextView",
"displayInputButton",
"informationTextView",
"progressViewGroup",
"debugFrame",
"exportStopwatch",
})
private void onCompleted(Uri inputUri, String filePath, ExportResult exportResult) {
exportStopwatch.stop();
long elapsedTimeMs = exportStopwatch.elapsed(TimeUnit.MILLISECONDS);
@ -748,14 +689,6 @@ public final class TransformerActivity extends AppCompatActivity {
}
}
@RequiresNonNull({
"inputCardView",
"inputTextView",
"inputImageView",
"inputPlayerView",
"outputPlayerView",
"debugTextView",
})
private void playMediaItems(MediaItem inputMediaItem, MediaItem outputMediaItem) {
inputPlayerView.setPlayer(null);
outputPlayerView.setPlayer(null);
@ -791,8 +724,8 @@ public final class TransformerActivity extends AppCompatActivity {
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
inputPlayerView.setPlayer(inputPlayer);
inputPlayerView.setControllerAutoShow(false);
inputPlayerView.setOnClickListener(this::onClickingPlayerView);
outputPlayerView.setOnClickListener(this::onClickingPlayerView);
inputPlayerView.setOnClickListener(this::handlePlayerViewClick);
outputPlayerView.setOnClickListener(this::handlePlayerViewClick);
inputPlayer.setMediaItem(inputMediaItem);
inputPlayer.prepare();
this.inputPlayer = inputPlayer;
@ -805,21 +738,21 @@ public final class TransformerActivity extends AppCompatActivity {
debugTextViewHelper.start();
}
private void onClickingPlayerView(View view) {
private void handlePlayerViewClick(View view) {
if (view == inputPlayerView) {
if (inputPlayer != null && inputTextView != null) {
if (inputPlayer != null) {
inputPlayer.setVolume(1f);
inputTextView.setText(R.string.input_video_playing_sound);
}
checkNotNull(outputPlayer).setVolume(0f);
checkNotNull(outputVideoTextView).setText(R.string.output_video_no_sound);
outputPlayer.setVolume(0f);
outputVideoTextView.setText(R.string.output_video_no_sound);
} else {
if (inputPlayer != null && inputTextView != null) {
if (inputPlayer != null) {
inputPlayer.setVolume(0f);
inputTextView.setText(getString(R.string.input_video_no_sound));
}
checkNotNull(outputPlayer).setVolume(1f);
checkNotNull(outputVideoTextView).setText(R.string.output_video_playing_sound);
outputPlayer.setVolume(1f);
outputVideoTextView.setText(R.string.output_video_playing_sound);
}
}
@ -850,10 +783,6 @@ public final class TransformerActivity extends AppCompatActivity {
Toast.makeText(getApplicationContext(), getString(messageResource), Toast.LENGTH_LONG).show();
}
@RequiresNonNull({
"inputCardView",
"displayInputButton",
})
private void toggleInputVideoDisplay(View view) {
if (inputCardView.getVisibility() == View.GONE) {
inputCardView.setVisibility(View.VISIBLE);
@ -867,7 +796,6 @@ public final class TransformerActivity extends AppCompatActivity {
}
}
@RequiresNonNull({"transformer", "exportStopwatch", "cancelButton", "resumeButton"})
private void cancelExport(View view) {
transformer.cancel();
transformer = null;
@ -882,7 +810,7 @@ public final class TransformerActivity extends AppCompatActivity {
private final class DemoDebugViewProvider implements DebugViewProvider {
private @MonotonicNonNull SurfaceView surfaceView;
@Nullable private SurfaceView surfaceView;
private int width;
private int height;
@ -909,7 +837,7 @@ public final class TransformerActivity extends AppCompatActivity {
runOnUiThread(
() -> {
surfaceView = new SurfaceView(/* context= */ TransformerActivity.this);
AspectRatioFrameLayout debugFrame = checkNotNull(TransformerActivity.this.debugFrame);
AspectRatioFrameLayout debugFrame = TransformerActivity.this.debugFrame;
debugFrame.addView(surfaceView);
debugFrame.setAspectRatio((float) width / height);
surfaceView