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:
parent
253fcb1fd1
commit
cc046d5ce7
@ -15,10 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.demo.composition;
|
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.app.Activity;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -59,7 +55,6 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@ -70,18 +65,17 @@ import org.json.JSONObject;
|
|||||||
public final class CompositionPreviewActivity extends AppCompatActivity {
|
public final class CompositionPreviewActivity extends AppCompatActivity {
|
||||||
private static final String TAG = "CompPreviewActivity";
|
private static final String TAG = "CompPreviewActivity";
|
||||||
|
|
||||||
private final ArrayList<String> sequenceAssetTitles = new ArrayList<>();
|
private ArrayList<String> sequenceAssetTitles;
|
||||||
|
private boolean[] selectedMediaItems;
|
||||||
@Nullable private boolean[] selectedMediaItems = null;
|
private String[] presetDescriptions;
|
||||||
private String[] presetDescriptions = new String[0];
|
private AssetItemAdapter assetItemAdapter;
|
||||||
@Nullable private AssetItemAdapter assetItemAdapter;
|
|
||||||
@Nullable private CompositionPlayer compositionPlayer;
|
@Nullable private CompositionPlayer compositionPlayer;
|
||||||
@Nullable private Transformer transformer;
|
@Nullable private Transformer transformer;
|
||||||
@Nullable private File outputFile;
|
@Nullable private File outputFile;
|
||||||
private @MonotonicNonNull PlayerView playerView;
|
private PlayerView playerView;
|
||||||
private @MonotonicNonNull AppCompatButton exportButton;
|
private AppCompatButton exportButton;
|
||||||
private @MonotonicNonNull AppCompatTextView exportInformationTextView;
|
private AppCompatTextView exportInformationTextView;
|
||||||
private @MonotonicNonNull Stopwatch exportStopwatch;
|
private Stopwatch exportStopwatch;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
@ -106,8 +100,9 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
selectedMediaItems = new boolean[presetDescriptions.length];
|
selectedMediaItems = new boolean[presetDescriptions.length];
|
||||||
selectedMediaItems[0] = true;
|
selectedMediaItems[0] = true;
|
||||||
selectedMediaItems[2] = true;
|
selectedMediaItems[2] = true;
|
||||||
for (int i = 0; i < checkNotNull(selectedMediaItems).length; i++) {
|
sequenceAssetTitles = new ArrayList<>();
|
||||||
if (checkNotNull(selectedMediaItems)[i]) {
|
for (int i = 0; i < selectedMediaItems.length; i++) {
|
||||||
|
if (selectedMediaItems[i]) {
|
||||||
sequenceAssetTitles.add(presetDescriptions[i]);
|
sequenceAssetTitles.add(presetDescriptions[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,38 +122,27 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
checkStateNotNull(playerView).onResume();
|
playerView.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
checkStateNotNull(playerView).onPause();
|
playerView.onPause();
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
cancelExport();
|
cancelExport();
|
||||||
checkStateNotNull(exportStopwatch).reset();
|
exportStopwatch.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Composition prepareComposition() {
|
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);
|
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);
|
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<>();
|
List<EditedMediaItem> mediaItems = new ArrayList<>();
|
||||||
ImmutableList<Effect> effects =
|
ImmutableList<Effect> effects =
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
MatrixTransformationFactory.createDizzyCropEffect(), RgbFilter.createGrayscaleFilter());
|
MatrixTransformationFactory.createDizzyCropEffect(), RgbFilter.createGrayscaleFilter());
|
||||||
for (int i = 0; i < checkNotNull(selectedMediaItems).length; i++) {
|
for (int i = 0; i < selectedMediaItems.length; i++) {
|
||||||
if (checkNotNull(selectedMediaItems)[i]) {
|
if (selectedMediaItems[i]) {
|
||||||
SonicAudioProcessor pitchChanger = new SonicAudioProcessor();
|
SonicAudioProcessor pitchChanger = new SonicAudioProcessor();
|
||||||
pitchChanger.setPitch(mediaItems.size() % 2 == 0 ? 2f : 0.2f);
|
pitchChanger.setPitch(mediaItems.size() % 2 == 0 ? 2f : 0.2f);
|
||||||
MediaItem mediaItem =
|
MediaItem mediaItem =
|
||||||
@ -190,12 +174,12 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
private void previewComposition(View view) {
|
private void previewComposition(View view) {
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
Composition composition = prepareComposition();
|
Composition composition = prepareComposition();
|
||||||
checkStateNotNull(playerView).setPlayer(null);
|
playerView.setPlayer(null);
|
||||||
|
|
||||||
CompositionPlayer player = new CompositionPlayer.Builder(getApplicationContext()).build();
|
CompositionPlayer player = new CompositionPlayer.Builder(getApplicationContext()).build();
|
||||||
this.compositionPlayer = player;
|
this.compositionPlayer = player;
|
||||||
checkStateNotNull(playerView).setPlayer(compositionPlayer);
|
playerView.setPlayer(compositionPlayer);
|
||||||
checkStateNotNull(playerView).setControllerAutoShow(false);
|
playerView.setControllerAutoShow(false);
|
||||||
player.addListener(
|
player.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
@ -213,8 +197,7 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
private void selectPreset(View view) {
|
private void selectPreset(View view) {
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.select_preset_title)
|
.setTitle(R.string.select_preset_title)
|
||||||
.setMultiChoiceItems(
|
.setMultiChoiceItems(presetDescriptions, selectedMediaItems, this::selectPresetInDialog)
|
||||||
presetDescriptions, checkNotNull(selectedMediaItems), this::selectPresetInDialog)
|
|
||||||
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.create()
|
.create()
|
||||||
@ -222,18 +205,15 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void selectPresetInDialog(DialogInterface dialog, int which, boolean isChecked) {
|
private void selectPresetInDialog(DialogInterface dialog, int which, boolean isChecked) {
|
||||||
if (selectedMediaItems == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
selectedMediaItems[which] = isChecked;
|
selectedMediaItems[which] = isChecked;
|
||||||
// The items will be added to a the sequence in the order they were selected.
|
// The items will be added to a the sequence in the order they were selected.
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
sequenceAssetTitles.add(presetDescriptions[which]);
|
sequenceAssetTitles.add(presetDescriptions[which]);
|
||||||
checkNotNull(assetItemAdapter).notifyItemInserted(sequenceAssetTitles.size() - 1);
|
assetItemAdapter.notifyItemInserted(sequenceAssetTitles.size() - 1);
|
||||||
} else {
|
} else {
|
||||||
int index = sequenceAssetTitles.indexOf(presetDescriptions[which]);
|
int index = sequenceAssetTitles.indexOf(presetDescriptions[which]);
|
||||||
sequenceAssetTitles.remove(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,
|
"Aborting export! Unable to create output file: " + e,
|
||||||
Toast.LENGTH_LONG)
|
Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
Log.e(TAG, "Aborting export! Unable to create output file: " + e);
|
Log.e(TAG, "Aborting export! Unable to create output file: ", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String filePath = outputFile.getAbsolutePath();
|
String filePath = outputFile.getAbsolutePath();
|
||||||
|
|
||||||
transformer =
|
transformer =
|
||||||
new Transformer.Builder(this)
|
new Transformer.Builder(/* context= */ this)
|
||||||
.addListener(
|
.addListener(
|
||||||
new Transformer.Listener() {
|
new Transformer.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCompleted(Composition composition, ExportResult exportResult) {
|
public void onCompleted(Composition composition, ExportResult exportResult) {
|
||||||
checkStateNotNull(exportStopwatch).stop();
|
exportStopwatch.stop();
|
||||||
long elapsedTimeMs = exportStopwatch.elapsed(TimeUnit.MILLISECONDS);
|
long elapsedTimeMs = exportStopwatch.elapsed(TimeUnit.MILLISECONDS);
|
||||||
String details =
|
String details =
|
||||||
getString(R.string.export_completed, elapsedTimeMs / 1000.f, filePath);
|
getString(R.string.export_completed, elapsedTimeMs / 1000.f, filePath);
|
||||||
Log.i(TAG, details);
|
Log.i(TAG, details);
|
||||||
checkStateNotNull(exportInformationTextView).setText(details);
|
exportInformationTextView.setText(details);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSONObject resultJson =
|
JSONObject resultJson =
|
||||||
@ -289,22 +269,22 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
Composition composition,
|
Composition composition,
|
||||||
ExportResult exportResult,
|
ExportResult exportResult,
|
||||||
ExportException exportException) {
|
ExportException exportException) {
|
||||||
checkStateNotNull(exportStopwatch).stop();
|
exportStopwatch.stop();
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
getApplicationContext(),
|
getApplicationContext(),
|
||||||
"Export error: " + exportException,
|
"Export error: " + exportException,
|
||||||
Toast.LENGTH_LONG)
|
Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
Log.e(TAG, "Export error", exportException);
|
Log.e(TAG, "Export error", exportException);
|
||||||
checkStateNotNull(exportInformationTextView).setText(R.string.export_error);
|
exportInformationTextView.setText(R.string.export_error);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
checkStateNotNull(exportInformationTextView).setText(R.string.export_started);
|
exportInformationTextView.setText(R.string.export_started);
|
||||||
checkStateNotNull(exportStopwatch).reset();
|
exportStopwatch.reset();
|
||||||
exportStopwatch.start();
|
exportStopwatch.start();
|
||||||
checkStateNotNull(transformer).start(composition, filePath);
|
transformer.start(composition, filePath);
|
||||||
Log.i(TAG, "Export started");
|
Log.i(TAG, "Export started");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +305,7 @@ public final class CompositionPreviewActivity extends AppCompatActivity {
|
|||||||
outputFile.delete();
|
outputFile.delete();
|
||||||
outputFile = null;
|
outputFile = null;
|
||||||
}
|
}
|
||||||
checkStateNotNull(exportInformationTextView).setText("");
|
exportInformationTextView.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,6 @@ package androidx.media3.demo.transformer;
|
|||||||
|
|
||||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||||
import static android.Manifest.permission.READ_MEDIA_VIDEO;
|
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.Assertions.checkState;
|
||||||
import static androidx.media3.common.util.Util.SDK_INT;
|
import static androidx.media3.common.util.Util.SDK_INT;
|
||||||
import static androidx.media3.transformer.Composition.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR;
|
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 com.google.common.collect.ImmutableMap;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
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
|
* 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 String SAME_AS_INPUT_OPTION = "same as input";
|
||||||
private static final float HALF_DIAGONAL = 1f / (float) Math.sqrt(2);
|
private static final float HALF_DIAGONAL = 1f / (float) Math.sqrt(2);
|
||||||
|
|
||||||
private @MonotonicNonNull Runnable onPermissionsGranted;
|
private Runnable onPermissionsGranted;
|
||||||
private @MonotonicNonNull ActivityResultLauncher<Intent> videoLocalFilePickerLauncher;
|
private ActivityResultLauncher<Intent> videoLocalFilePickerLauncher;
|
||||||
private @MonotonicNonNull ActivityResultLauncher<Intent> overlayLocalFilePickerLauncher;
|
private ActivityResultLauncher<Intent> overlayLocalFilePickerLauncher;
|
||||||
private @MonotonicNonNull Button selectPresetFileButton;
|
private Button selectPresetFileButton;
|
||||||
private @MonotonicNonNull Button selectLocalFileButton;
|
private Button selectLocalFileButton;
|
||||||
private @MonotonicNonNull TextView selectedFileTextView;
|
private TextView selectedFileTextView;
|
||||||
private @MonotonicNonNull CheckBox removeAudioCheckbox;
|
private CheckBox removeAudioCheckbox;
|
||||||
private @MonotonicNonNull CheckBox removeVideoCheckbox;
|
private CheckBox removeVideoCheckbox;
|
||||||
private @MonotonicNonNull CheckBox flattenForSlowMotionCheckbox;
|
private CheckBox flattenForSlowMotionCheckbox;
|
||||||
private @MonotonicNonNull CheckBox forceAudioTrackCheckbox;
|
private CheckBox forceAudioTrackCheckbox;
|
||||||
private @MonotonicNonNull Spinner audioMimeSpinner;
|
private Spinner audioMimeSpinner;
|
||||||
private @MonotonicNonNull Spinner videoMimeSpinner;
|
private Spinner videoMimeSpinner;
|
||||||
private @MonotonicNonNull Spinner resolutionHeightSpinner;
|
private Spinner resolutionHeightSpinner;
|
||||||
private @MonotonicNonNull Spinner scaleSpinner;
|
private Spinner scaleSpinner;
|
||||||
private @MonotonicNonNull Spinner rotateSpinner;
|
private Spinner rotateSpinner;
|
||||||
private @MonotonicNonNull CheckBox trimCheckBox;
|
private CheckBox trimCheckBox;
|
||||||
private @MonotonicNonNull CheckBox enableFallbackCheckBox;
|
private CheckBox enableFallbackCheckBox;
|
||||||
private @MonotonicNonNull CheckBox enableAnalyzerModeCheckBox;
|
private CheckBox enableAnalyzerModeCheckBox;
|
||||||
private @MonotonicNonNull CheckBox enableDebugPreviewCheckBox;
|
private CheckBox enableDebugPreviewCheckBox;
|
||||||
private @MonotonicNonNull CheckBox enableDebugTracingCheckBox;
|
private CheckBox enableDebugTracingCheckBox;
|
||||||
private @MonotonicNonNull CheckBox abortSlowExportCheckBox;
|
private CheckBox abortSlowExportCheckBox;
|
||||||
private @MonotonicNonNull CheckBox produceFragmentedMp4CheckBox;
|
private CheckBox produceFragmentedMp4CheckBox;
|
||||||
private @MonotonicNonNull Spinner hdrModeSpinner;
|
private Spinner hdrModeSpinner;
|
||||||
private @MonotonicNonNull Button selectAudioEffectsButton;
|
private Button selectAudioEffectsButton;
|
||||||
private @MonotonicNonNull Button selectVideoEffectsButton;
|
private Button selectVideoEffectsButton;
|
||||||
private boolean @MonotonicNonNull [] audioEffectsSelections;
|
private boolean[] audioEffectsSelections;
|
||||||
private boolean @MonotonicNonNull [] videoEffectsSelections;
|
private boolean[] videoEffectsSelections;
|
||||||
private String[] presetFileDescriptions = new String[0];
|
private String[] presetFileDescriptions;
|
||||||
private @Nullable Uri localFileUri;
|
private Uri localFileUri;
|
||||||
private int inputUriPosition;
|
private int inputUriPosition;
|
||||||
private long trimStartMs;
|
private long trimStartMs;
|
||||||
private long trimEndMs;
|
private long trimEndMs;
|
||||||
@ -198,9 +195,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private float periodicVignetteCenterY;
|
private float periodicVignetteCenterY;
|
||||||
private float periodicVignetteInnerRadius;
|
private float periodicVignetteInnerRadius;
|
||||||
private float periodicVignetteOuterRadius;
|
private float periodicVignetteOuterRadius;
|
||||||
private @MonotonicNonNull String bitmapOverlayUri;
|
private String bitmapOverlayUri;
|
||||||
private float bitmapOverlayAlpha;
|
private float bitmapOverlayAlpha;
|
||||||
private @MonotonicNonNull String textOverlayText;
|
private String textOverlayText;
|
||||||
private int textOverlayTextColor;
|
private int textOverlayTextColor;
|
||||||
private float textOverlayAlpha;
|
private float textOverlayAlpha;
|
||||||
|
|
||||||
@ -227,7 +224,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
selectLocalFileButton.setOnClickListener(
|
selectLocalFileButton.setOnClickListener(
|
||||||
view ->
|
view ->
|
||||||
selectLocalFile(
|
selectLocalFile(
|
||||||
checkNotNull(videoLocalFilePickerLauncher),
|
videoLocalFilePickerLauncher,
|
||||||
/* mimeTypes= */ new String[] {"image/*", "video/*", "audio/*"}));
|
/* mimeTypes= */ new String[] {"image/*", "video/*", "audio/*"}));
|
||||||
|
|
||||||
selectedFileTextView = findViewById(R.id.selected_file_text_view);
|
selectedFileTextView = findViewById(R.id.selected_file_text_view);
|
||||||
@ -331,7 +328,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
if (requestCode == FILE_PERMISSION_REQUEST_CODE
|
if (requestCode == FILE_PERMISSION_REQUEST_CODE
|
||||||
&& grantResults.length == 1
|
&& grantResults.length == 1
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
checkNotNull(onPermissionsGranted).run();
|
onPermissionsGranted.run();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
getApplicationContext(), getString(R.string.permission_denied), Toast.LENGTH_LONG)
|
getApplicationContext(), getString(R.string.permission_denied), Toast.LENGTH_LONG)
|
||||||
@ -344,9 +341,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
super.onResume();
|
super.onResume();
|
||||||
@Nullable Uri intentUri = getIntent().getData();
|
@Nullable Uri intentUri = getIntent().getData();
|
||||||
if (intentUri != null) {
|
if (intentUri != null) {
|
||||||
checkNotNull(selectPresetFileButton).setEnabled(false);
|
selectPresetFileButton.setEnabled(false);
|
||||||
checkNotNull(selectLocalFileButton).setEnabled(false);
|
selectLocalFileButton.setEnabled(false);
|
||||||
checkNotNull(selectedFileTextView).setText(intentUri.toString());
|
selectedFileTextView.setText(intentUri.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,26 +353,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
setIntent(intent);
|
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) {
|
private void startExport(View view) {
|
||||||
Intent transformerIntent = new Intent(/* packageContext= */ this, TransformerActivity.class);
|
Intent transformerIntent = new Intent(/* packageContext= */ this, TransformerActivity.class);
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
@ -415,8 +392,8 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
bundle.putBoolean(ENABLE_DEBUG_PREVIEW, enableDebugPreviewCheckBox.isChecked());
|
bundle.putBoolean(ENABLE_DEBUG_PREVIEW, enableDebugPreviewCheckBox.isChecked());
|
||||||
bundle.putBoolean(ABORT_SLOW_EXPORT, abortSlowExportCheckBox.isChecked());
|
bundle.putBoolean(ABORT_SLOW_EXPORT, abortSlowExportCheckBox.isChecked());
|
||||||
bundle.putBoolean(PRODUCE_FRAGMENTED_MP4, produceFragmentedMp4CheckBox.isChecked());
|
bundle.putBoolean(PRODUCE_FRAGMENTED_MP4, produceFragmentedMp4CheckBox.isChecked());
|
||||||
String selectedhdrMode = String.valueOf(hdrModeSpinner.getSelectedItem());
|
String selectedHdrMode = String.valueOf(hdrModeSpinner.getSelectedItem());
|
||||||
bundle.putInt(HDR_MODE, checkNotNull(HDR_MODE_DESCRIPTIONS.get(selectedhdrMode)));
|
bundle.putInt(HDR_MODE, HDR_MODE_DESCRIPTIONS.get(selectedHdrMode));
|
||||||
bundle.putBooleanArray(AUDIO_EFFECTS_SELECTIONS, audioEffectsSelections);
|
bundle.putBooleanArray(AUDIO_EFFECTS_SELECTIONS, audioEffectsSelections);
|
||||||
bundle.putBooleanArray(VIDEO_EFFECTS_SELECTIONS, videoEffectsSelections);
|
bundle.putBooleanArray(VIDEO_EFFECTS_SELECTIONS, videoEffectsSelections);
|
||||||
bundle.putInt(COLOR_FILTER_SELECTION, colorFilterSelection);
|
bundle.putInt(COLOR_FILTER_SELECTION, colorFilterSelection);
|
||||||
@ -462,7 +439,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull("selectedFileTextView")
|
|
||||||
private void selectPresetFileInDialog(DialogInterface dialog, int which) {
|
private void selectPresetFileInDialog(DialogInterface dialog, int which) {
|
||||||
inputUriPosition = which;
|
inputUriPosition = which;
|
||||||
localFileUri = null;
|
localFileUri = null;
|
||||||
@ -487,14 +463,13 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
intent.setType("*/*");
|
intent.setType("*/*");
|
||||||
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
|
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
|
||||||
checkNotNull(localFilePickerLauncher).launch(intent);
|
localFilePickerLauncher.launch(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull("selectedFileTextView")
|
|
||||||
private void videoLocalFilePickerLauncherResult(ActivityResult result) {
|
private void videoLocalFilePickerLauncherResult(ActivityResult result) {
|
||||||
Intent data = result.getData();
|
Intent data = result.getData();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
localFileUri = checkNotNull(data.getData());
|
localFileUri = data.getData();
|
||||||
selectedFileTextView.setText(localFileUri.toString());
|
selectedFileTextView.setText(localFileUri.toString());
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
@ -508,7 +483,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void overlayLocalFilePickerLauncherResult(ActivityResult result) {
|
private void overlayLocalFilePickerLauncherResult(ActivityResult result) {
|
||||||
Intent data = result.getData();
|
Intent data = result.getData();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
bitmapOverlayUri = checkNotNull(data.getData()).toString();
|
bitmapOverlayUri = data.getData().toString();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
getApplicationContext(),
|
getApplicationContext(),
|
||||||
@ -521,8 +496,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void selectAudioEffects(View view, String[] audioEffectsNames) {
|
private void selectAudioEffects(View view, String[] audioEffectsNames) {
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.select_audio_effects)
|
.setTitle(R.string.select_audio_effects)
|
||||||
.setMultiChoiceItems(
|
.setMultiChoiceItems(audioEffectsNames, audioEffectsSelections, this::selectAudioEffect)
|
||||||
audioEffectsNames, checkNotNull(audioEffectsSelections), this::selectAudioEffect)
|
|
||||||
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
||||||
.create()
|
.create()
|
||||||
.show();
|
.show();
|
||||||
@ -531,8 +505,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void selectVideoEffects(View view, String[] videoEffectsNames) {
|
private void selectVideoEffects(View view, String[] videoEffectsNames) {
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.select_video_effects)
|
.setTitle(R.string.select_video_effects)
|
||||||
.setMultiChoiceItems(
|
.setMultiChoiceItems(videoEffectsNames, videoEffectsSelections, this::selectVideoEffect)
|
||||||
videoEffectsNames, checkNotNull(videoEffectsSelections), this::selectVideoEffect)
|
|
||||||
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
||||||
.create()
|
.create()
|
||||||
.show();
|
.show();
|
||||||
@ -543,8 +516,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
View dialogView = getLayoutInflater().inflate(R.layout.trim_options, /* root= */ null);
|
View dialogView = getLayoutInflater().inflate(R.layout.trim_options, /* root= */ null);
|
||||||
RangeSlider trimRangeSlider =
|
RangeSlider trimRangeSlider = dialogView.findViewById(R.id.trim_bounds_range_slider);
|
||||||
checkNotNull(dialogView.findViewById(R.id.trim_bounds_range_slider));
|
|
||||||
trimRangeSlider.setValues(0f, 1f); // seconds
|
trimRangeSlider.setValues(0f, 1f); // seconds
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
@ -559,12 +531,10 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull("audioEffectsSelections")
|
|
||||||
private void selectAudioEffect(DialogInterface dialog, int which, boolean isChecked) {
|
private void selectAudioEffect(DialogInterface dialog, int which, boolean isChecked) {
|
||||||
audioEffectsSelections[which] = isChecked;
|
audioEffectsSelections[which] = isChecked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull("videoEffectsSelections")
|
|
||||||
private void selectVideoEffect(DialogInterface dialog, int which, boolean isChecked) {
|
private void selectVideoEffect(DialogInterface dialog, int which, boolean isChecked) {
|
||||||
videoEffectsSelections[which] = isChecked;
|
videoEffectsSelections[which] = isChecked;
|
||||||
if (!isChecked) {
|
if (!isChecked) {
|
||||||
@ -617,10 +587,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void controlRgbAdjustmentsScale() {
|
private void controlRgbAdjustmentsScale() {
|
||||||
View dialogView =
|
View dialogView =
|
||||||
getLayoutInflater().inflate(R.layout.rgb_adjustment_options, /* root= */ null);
|
getLayoutInflater().inflate(R.layout.rgb_adjustment_options, /* root= */ null);
|
||||||
Slider redScaleSlider = checkNotNull(dialogView.findViewById(R.id.rgb_adjustment_red_scale));
|
Slider redScaleSlider = dialogView.findViewById(R.id.rgb_adjustment_red_scale);
|
||||||
Slider greenScaleSlider =
|
Slider greenScaleSlider = dialogView.findViewById(R.id.rgb_adjustment_green_scale);
|
||||||
checkNotNull(dialogView.findViewById(R.id.rgb_adjustment_green_scale));
|
Slider blueScaleSlider = dialogView.findViewById(R.id.rgb_adjustment_blue_scale);
|
||||||
Slider blueScaleSlider = checkNotNull(dialogView.findViewById(R.id.rgb_adjustment_blue_scale));
|
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.rgb_adjustment_options)
|
.setTitle(R.string.rgb_adjustment_options)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
@ -637,7 +606,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private void controlContrastSettings() {
|
private void controlContrastSettings() {
|
||||||
View dialogView = getLayoutInflater().inflate(R.layout.contrast_options, /* root= */ null);
|
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)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
.setPositiveButton(
|
.setPositiveButton(
|
||||||
@ -650,11 +619,9 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void controlHslAdjustmentSettings() {
|
private void controlHslAdjustmentSettings() {
|
||||||
View dialogView =
|
View dialogView =
|
||||||
getLayoutInflater().inflate(R.layout.hsl_adjustment_options, /* root= */ null);
|
getLayoutInflater().inflate(R.layout.hsl_adjustment_options, /* root= */ null);
|
||||||
Slider hueAdjustmentSlider = checkNotNull(dialogView.findViewById(R.id.hsl_adjustments_hue));
|
Slider hueAdjustmentSlider = dialogView.findViewById(R.id.hsl_adjustments_hue);
|
||||||
Slider saturationAdjustmentSlider =
|
Slider saturationAdjustmentSlider = dialogView.findViewById(R.id.hsl_adjustments_saturation);
|
||||||
checkNotNull(dialogView.findViewById(R.id.hsl_adjustments_saturation));
|
Slider lightnessAdjustmentSlider = dialogView.findViewById(R.id.hsl_adjustment_lightness);
|
||||||
Slider lightnessAdjustmentSlider =
|
|
||||||
checkNotNull(dialogView.findViewById(R.id.hsl_adjustment_lightness));
|
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.hsl_adjustment_options)
|
.setTitle(R.string.hsl_adjustment_options)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
@ -672,12 +639,10 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void controlPeriodicVignetteSettings() {
|
private void controlPeriodicVignetteSettings() {
|
||||||
View dialogView =
|
View dialogView =
|
||||||
getLayoutInflater().inflate(R.layout.periodic_vignette_options, /* root= */ null);
|
getLayoutInflater().inflate(R.layout.periodic_vignette_options, /* root= */ null);
|
||||||
Slider centerXSlider =
|
Slider centerXSlider = dialogView.findViewById(R.id.periodic_vignette_center_x_slider);
|
||||||
checkNotNull(dialogView.findViewById(R.id.periodic_vignette_center_x_slider));
|
Slider centerYSlider = dialogView.findViewById(R.id.periodic_vignette_center_y_slider);
|
||||||
Slider centerYSlider =
|
|
||||||
checkNotNull(dialogView.findViewById(R.id.periodic_vignette_center_y_slider));
|
|
||||||
RangeSlider radiusRangeSlider =
|
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);
|
radiusRangeSlider.setValues(0f, HALF_DIAGONAL);
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.periodic_vignette_options)
|
.setTitle(R.string.periodic_vignette_options)
|
||||||
@ -698,13 +663,12 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private void controlBitmapOverlaySettings() {
|
private void controlBitmapOverlaySettings() {
|
||||||
View dialogView =
|
View dialogView =
|
||||||
getLayoutInflater().inflate(R.layout.bitmap_overlay_options, /* root= */ null);
|
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(
|
uriButton.setOnClickListener(
|
||||||
(view ->
|
(view ->
|
||||||
selectLocalFile(
|
selectLocalFile(
|
||||||
checkNotNull(overlayLocalFilePickerLauncher),
|
overlayLocalFilePickerLauncher, /* mimeTypes= */ new String[] {"image/*"})));
|
||||||
/* mimeTypes= */ new String[] {"image/*"})));
|
Slider alphaSlider = dialogView.findViewById(R.id.bitmap_overlay_alpha_slider);
|
||||||
Slider alphaSlider = checkNotNull(dialogView.findViewById(R.id.bitmap_overlay_alpha_slider));
|
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.bitmap_overlay_settings)
|
.setTitle(R.string.bitmap_overlay_settings)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
@ -719,16 +683,16 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private void controlTextOverlaySettings() {
|
private void controlTextOverlaySettings() {
|
||||||
View dialogView = getLayoutInflater().inflate(R.layout.text_overlay_options, /* root= */ null);
|
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 =
|
ArrayAdapter<String> textColorAdapter =
|
||||||
new ArrayAdapter<>(/* context= */ this, R.layout.spinner_item);
|
new ArrayAdapter<>(/* context= */ this, R.layout.spinner_item);
|
||||||
textColorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_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);
|
textColorSpinner.setAdapter(textColorAdapter);
|
||||||
textColorAdapter.addAll(OVERLAY_COLORS.keySet());
|
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)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.bitmap_overlay_settings)
|
.setTitle(R.string.bitmap_overlay_settings)
|
||||||
.setView(dialogView)
|
.setView(dialogView)
|
||||||
@ -737,26 +701,13 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
(DialogInterface dialogInterface, int i) -> {
|
(DialogInterface dialogInterface, int i) -> {
|
||||||
textOverlayText = textEditText.getText().toString();
|
textOverlayText = textEditText.getText().toString();
|
||||||
String selectedTextColor = String.valueOf(textColorSpinner.getSelectedItem());
|
String selectedTextColor = String.valueOf(textColorSpinner.getSelectedItem());
|
||||||
textOverlayTextColor = checkNotNull(OVERLAY_COLORS.get(selectedTextColor));
|
textOverlayTextColor = OVERLAY_COLORS.get(selectedTextColor);
|
||||||
textOverlayAlpha = alphaSlider.getValue();
|
textOverlayAlpha = alphaSlider.getValue();
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull({
|
|
||||||
"removeVideoCheckbox",
|
|
||||||
"forceAudioTrackCheckbox",
|
|
||||||
"audioMimeSpinner",
|
|
||||||
"videoMimeSpinner",
|
|
||||||
"resolutionHeightSpinner",
|
|
||||||
"scaleSpinner",
|
|
||||||
"rotateSpinner",
|
|
||||||
"enableDebugPreviewCheckBox",
|
|
||||||
"hdrModeSpinner",
|
|
||||||
"selectAudioEffectsButton",
|
|
||||||
"selectVideoEffectsButton"
|
|
||||||
})
|
|
||||||
private void onRemoveAudio(View view) {
|
private void onRemoveAudio(View view) {
|
||||||
if (((CheckBox) view).isChecked()) {
|
if (((CheckBox) view).isChecked()) {
|
||||||
removeVideoCheckbox.setChecked(false);
|
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) {
|
private void onRemoveVideo(View view) {
|
||||||
if (((CheckBox) view).isChecked()) {
|
if (((CheckBox) view).isChecked()) {
|
||||||
removeAudioCheckbox.setChecked(false);
|
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) {
|
private void enableTrackSpecificOptions(boolean isAudioEnabled, boolean isVideoEnabled) {
|
||||||
forceAudioTrackCheckbox.setEnabled(isVideoEnabled);
|
forceAudioTrackCheckbox.setEnabled(isVideoEnabled);
|
||||||
audioMimeSpinner.setEnabled(isAudioEnabled);
|
audioMimeSpinner.setEnabled(isAudioEnabled);
|
||||||
|
@ -112,8 +112,6 @@ import java.util.Arrays;
|
|||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@ -121,21 +119,21 @@ import org.json.JSONObject;
|
|||||||
public final class TransformerActivity extends AppCompatActivity {
|
public final class TransformerActivity extends AppCompatActivity {
|
||||||
private static final String TAG = "TransformerActivity";
|
private static final String TAG = "TransformerActivity";
|
||||||
|
|
||||||
private @MonotonicNonNull Button displayInputButton;
|
private Button displayInputButton;
|
||||||
private @MonotonicNonNull MaterialCardView inputCardView;
|
private MaterialCardView inputCardView;
|
||||||
private @MonotonicNonNull TextView inputTextView;
|
private TextView inputTextView;
|
||||||
private @MonotonicNonNull ImageView inputImageView;
|
private ImageView inputImageView;
|
||||||
private @MonotonicNonNull PlayerView inputPlayerView;
|
private PlayerView inputPlayerView;
|
||||||
private @MonotonicNonNull PlayerView outputPlayerView;
|
private PlayerView outputPlayerView;
|
||||||
private @MonotonicNonNull TextView outputVideoTextView;
|
private TextView outputVideoTextView;
|
||||||
private @MonotonicNonNull TextView debugTextView;
|
private TextView debugTextView;
|
||||||
private @MonotonicNonNull TextView informationTextView;
|
private TextView informationTextView;
|
||||||
private @MonotonicNonNull ViewGroup progressViewGroup;
|
private ViewGroup progressViewGroup;
|
||||||
private @MonotonicNonNull LinearProgressIndicator progressIndicator;
|
private LinearProgressIndicator progressIndicator;
|
||||||
private @MonotonicNonNull Button cancelButton;
|
private Button cancelButton;
|
||||||
private @MonotonicNonNull Button resumeButton;
|
private Button resumeButton;
|
||||||
private @MonotonicNonNull Stopwatch exportStopwatch;
|
private Stopwatch exportStopwatch;
|
||||||
private @MonotonicNonNull AspectRatioFrameLayout debugFrame;
|
private AspectRatioFrameLayout debugFrame;
|
||||||
|
|
||||||
@Nullable private DebugTextViewHelper debugTextViewHelper;
|
@Nullable private DebugTextViewHelper debugTextViewHelper;
|
||||||
@Nullable private ExoPlayer inputPlayer;
|
@Nullable private ExoPlayer inputPlayer;
|
||||||
@ -183,8 +181,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
startExport();
|
startExport();
|
||||||
|
|
||||||
checkNotNull(inputPlayerView).onResume();
|
inputPlayerView.onResume();
|
||||||
checkNotNull(outputPlayerView).onResume();
|
outputPlayerView.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// The stop watch is reset after cancelling the export, in case cancelling causes the stop watch
|
||||||
// to be stopped in a transformer callback.
|
// to be stopped in a transformer callback.
|
||||||
checkNotNull(exportStopwatch).reset();
|
exportStopwatch.reset();
|
||||||
|
|
||||||
checkNotNull(inputPlayerView).onPause();
|
inputPlayerView.onPause();
|
||||||
checkNotNull(outputPlayerView).onPause();
|
outputPlayerView.onPause();
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
|
|
||||||
checkNotNull(outputFile).delete();
|
outputFile.delete();
|
||||||
outputFile = null;
|
outputFile = null;
|
||||||
if (oldOutputFile != null) {
|
if (oldOutputFile != null) {
|
||||||
oldOutputFile.delete();
|
oldOutputFile.delete();
|
||||||
@ -213,22 +211,6 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startExport() {
|
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);
|
requestReadVideoPermission(/* activity= */ this);
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
@ -297,20 +279,6 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
return mediaItemBuilder.build();
|
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) {
|
private Transformer createTransformer(@Nullable Bundle bundle, Uri inputUri, String filePath) {
|
||||||
Transformer.Builder transformerBuilder =
|
Transformer.Builder transformerBuilder =
|
||||||
new Transformer.Builder(/* context= */ this)
|
new Transformer.Builder(/* context= */ this)
|
||||||
@ -380,12 +348,6 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull({
|
|
||||||
"inputCardView",
|
|
||||||
"outputPlayerView",
|
|
||||||
"exportStopwatch",
|
|
||||||
"progressViewGroup",
|
|
||||||
})
|
|
||||||
private Composition createComposition(MediaItem mediaItem, @Nullable Bundle bundle) {
|
private Composition createComposition(MediaItem mediaItem, @Nullable Bundle bundle) {
|
||||||
EditedMediaItem.Builder editedMediaItemBuilder = new EditedMediaItem.Builder(mediaItem);
|
EditedMediaItem.Builder editedMediaItemBuilder = new EditedMediaItem.Builder(mediaItem);
|
||||||
// For image inputs. Automatically ignored if input is audio/video.
|
// For image inputs. Automatically ignored if input is audio/video.
|
||||||
@ -657,7 +619,7 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
BitmapOverlay bitmapOverlay =
|
BitmapOverlay bitmapOverlay =
|
||||||
BitmapOverlay.createStaticBitmapOverlay(
|
BitmapOverlay.createStaticBitmapOverlay(
|
||||||
getApplicationContext(),
|
getApplicationContext(),
|
||||||
Uri.parse(checkNotNull(bundle.getString(ConfigurationActivity.BITMAP_OVERLAY_URI))),
|
Uri.parse(bundle.getString(ConfigurationActivity.BITMAP_OVERLAY_URI)),
|
||||||
overlaySettings);
|
overlaySettings);
|
||||||
overlaysBuilder.add(bitmapOverlay);
|
overlaysBuilder.add(bitmapOverlay);
|
||||||
}
|
}
|
||||||
@ -668,8 +630,7 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
bundle.getFloat(ConfigurationActivity.TEXT_OVERLAY_ALPHA, /* defaultValue= */ 1))
|
bundle.getFloat(ConfigurationActivity.TEXT_OVERLAY_ALPHA, /* defaultValue= */ 1))
|
||||||
.build();
|
.build();
|
||||||
SpannableString overlayText =
|
SpannableString overlayText =
|
||||||
new SpannableString(
|
new SpannableString(bundle.getString(ConfigurationActivity.TEXT_OVERLAY_TEXT));
|
||||||
checkNotNull(bundle.getString(ConfigurationActivity.TEXT_OVERLAY_TEXT)));
|
|
||||||
overlayText.setSpan(
|
overlayText.setSpan(
|
||||||
new ForegroundColorSpan(bundle.getInt(ConfigurationActivity.TEXT_OVERLAY_TEXT_COLOR)),
|
new ForegroundColorSpan(bundle.getInt(ConfigurationActivity.TEXT_OVERLAY_TEXT_COLOR)),
|
||||||
/* start= */ 0,
|
/* start= */ 0,
|
||||||
@ -683,12 +644,6 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
return overlays.isEmpty() ? null : new OverlayEffect(overlays);
|
return overlays.isEmpty() ? null : new OverlayEffect(overlays);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull({
|
|
||||||
"informationTextView",
|
|
||||||
"progressViewGroup",
|
|
||||||
"debugFrame",
|
|
||||||
"exportStopwatch",
|
|
||||||
})
|
|
||||||
private void onError(ExportException exportException) {
|
private void onError(ExportException exportException) {
|
||||||
exportStopwatch.stop();
|
exportStopwatch.stop();
|
||||||
informationTextView.setText(R.string.export_error);
|
informationTextView.setText(R.string.export_error);
|
||||||
@ -699,20 +654,6 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
Log.e(TAG, "Export error", exportException);
|
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) {
|
private void onCompleted(Uri inputUri, String filePath, ExportResult exportResult) {
|
||||||
exportStopwatch.stop();
|
exportStopwatch.stop();
|
||||||
long elapsedTimeMs = exportStopwatch.elapsed(TimeUnit.MILLISECONDS);
|
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) {
|
private void playMediaItems(MediaItem inputMediaItem, MediaItem outputMediaItem) {
|
||||||
inputPlayerView.setPlayer(null);
|
inputPlayerView.setPlayer(null);
|
||||||
outputPlayerView.setPlayer(null);
|
outputPlayerView.setPlayer(null);
|
||||||
@ -791,8 +724,8 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
|
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
|
||||||
inputPlayerView.setPlayer(inputPlayer);
|
inputPlayerView.setPlayer(inputPlayer);
|
||||||
inputPlayerView.setControllerAutoShow(false);
|
inputPlayerView.setControllerAutoShow(false);
|
||||||
inputPlayerView.setOnClickListener(this::onClickingPlayerView);
|
inputPlayerView.setOnClickListener(this::handlePlayerViewClick);
|
||||||
outputPlayerView.setOnClickListener(this::onClickingPlayerView);
|
outputPlayerView.setOnClickListener(this::handlePlayerViewClick);
|
||||||
inputPlayer.setMediaItem(inputMediaItem);
|
inputPlayer.setMediaItem(inputMediaItem);
|
||||||
inputPlayer.prepare();
|
inputPlayer.prepare();
|
||||||
this.inputPlayer = inputPlayer;
|
this.inputPlayer = inputPlayer;
|
||||||
@ -805,21 +738,21 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
debugTextViewHelper.start();
|
debugTextViewHelper.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onClickingPlayerView(View view) {
|
private void handlePlayerViewClick(View view) {
|
||||||
if (view == inputPlayerView) {
|
if (view == inputPlayerView) {
|
||||||
if (inputPlayer != null && inputTextView != null) {
|
if (inputPlayer != null) {
|
||||||
inputPlayer.setVolume(1f);
|
inputPlayer.setVolume(1f);
|
||||||
inputTextView.setText(R.string.input_video_playing_sound);
|
inputTextView.setText(R.string.input_video_playing_sound);
|
||||||
}
|
}
|
||||||
checkNotNull(outputPlayer).setVolume(0f);
|
outputPlayer.setVolume(0f);
|
||||||
checkNotNull(outputVideoTextView).setText(R.string.output_video_no_sound);
|
outputVideoTextView.setText(R.string.output_video_no_sound);
|
||||||
} else {
|
} else {
|
||||||
if (inputPlayer != null && inputTextView != null) {
|
if (inputPlayer != null) {
|
||||||
inputPlayer.setVolume(0f);
|
inputPlayer.setVolume(0f);
|
||||||
inputTextView.setText(getString(R.string.input_video_no_sound));
|
inputTextView.setText(getString(R.string.input_video_no_sound));
|
||||||
}
|
}
|
||||||
checkNotNull(outputPlayer).setVolume(1f);
|
outputPlayer.setVolume(1f);
|
||||||
checkNotNull(outputVideoTextView).setText(R.string.output_video_playing_sound);
|
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();
|
Toast.makeText(getApplicationContext(), getString(messageResource), Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull({
|
|
||||||
"inputCardView",
|
|
||||||
"displayInputButton",
|
|
||||||
})
|
|
||||||
private void toggleInputVideoDisplay(View view) {
|
private void toggleInputVideoDisplay(View view) {
|
||||||
if (inputCardView.getVisibility() == View.GONE) {
|
if (inputCardView.getVisibility() == View.GONE) {
|
||||||
inputCardView.setVisibility(View.VISIBLE);
|
inputCardView.setVisibility(View.VISIBLE);
|
||||||
@ -867,7 +796,6 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull({"transformer", "exportStopwatch", "cancelButton", "resumeButton"})
|
|
||||||
private void cancelExport(View view) {
|
private void cancelExport(View view) {
|
||||||
transformer.cancel();
|
transformer.cancel();
|
||||||
transformer = null;
|
transformer = null;
|
||||||
@ -882,7 +810,7 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private final class DemoDebugViewProvider implements DebugViewProvider {
|
private final class DemoDebugViewProvider implements DebugViewProvider {
|
||||||
|
|
||||||
private @MonotonicNonNull SurfaceView surfaceView;
|
@Nullable private SurfaceView surfaceView;
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
|
|
||||||
@ -909,7 +837,7 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
runOnUiThread(
|
runOnUiThread(
|
||||||
() -> {
|
() -> {
|
||||||
surfaceView = new SurfaceView(/* context= */ TransformerActivity.this);
|
surfaceView = new SurfaceView(/* context= */ TransformerActivity.this);
|
||||||
AspectRatioFrameLayout debugFrame = checkNotNull(TransformerActivity.this.debugFrame);
|
AspectRatioFrameLayout debugFrame = TransformerActivity.this.debugFrame;
|
||||||
debugFrame.addView(surfaceView);
|
debugFrame.addView(surfaceView);
|
||||||
debugFrame.setAspectRatio((float) width / height);
|
debugFrame.setAspectRatio((float) width / height);
|
||||||
surfaceView
|
surfaceView
|
||||||
|
Loading…
x
Reference in New Issue
Block a user