mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add local file picker to ConfigurationActivity
PiperOrigin-RevId: 480349627
This commit is contained in:
parent
0468b5ab72
commit
b515e0bd7f
@ -18,9 +18,11 @@ package androidx.media3.demo.transformer;
|
|||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
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 android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -29,9 +31,14 @@ import android.widget.Button;
|
|||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import androidx.activity.result.ActivityResult;
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
@ -78,7 +85,8 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
public static final int COLOR_FILTER_GRAYSCALE = 0;
|
public static final int COLOR_FILTER_GRAYSCALE = 0;
|
||||||
public static final int COLOR_FILTER_INVERTED = 1;
|
public static final int COLOR_FILTER_INVERTED = 1;
|
||||||
public static final int COLOR_FILTER_SEPIA = 2;
|
public static final int COLOR_FILTER_SEPIA = 2;
|
||||||
private static final String[] INPUT_URIS = {
|
public static final int FILE_PERMISSION_REQUEST_CODE = 1;
|
||||||
|
private static final String[] PRESET_FILE_URIS = {
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/android-screens-10s.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/android-screens-10s.mp4",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-0/android-block-1080-hevc.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-0/android-block-1080-hevc.mp4",
|
||||||
"https://html5demos.com/assets/dizzy.mp4",
|
"https://html5demos.com/assets/dizzy.mp4",
|
||||||
@ -93,7 +101,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
"https://storage.googleapis.com/exoplayer-test-media-1/gen/screens/dash-vod-single-segment/manifest-baseline.mpd",
|
"https://storage.googleapis.com/exoplayer-test-media-1/gen/screens/dash-vod-single-segment/manifest-baseline.mpd",
|
||||||
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/samsung-s21-hdr-hdr10.mp4",
|
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/samsung-s21-hdr-hdr10.mp4",
|
||||||
};
|
};
|
||||||
private static final String[] URI_DESCRIPTIONS = { // same order as INPUT_URIS
|
private static final String[] PRESET_FILE_URI_DESCRIPTIONS = { // same order as PRESET_FILE_URIS
|
||||||
"720p H264 video and AAC audio",
|
"720p H264 video and AAC audio",
|
||||||
"1080p H265 video and AAC audio",
|
"1080p H265 video and AAC audio",
|
||||||
"360p H264 video and AAC audio",
|
"360p H264 video and AAC audio",
|
||||||
@ -129,7 +137,9 @@ 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 Button selectFileButton;
|
private @MonotonicNonNull ActivityResultLauncher<Intent> localFilePickerLauncher;
|
||||||
|
private @MonotonicNonNull Button selectPresetFileButton;
|
||||||
|
private @MonotonicNonNull Button selectLocalFileButton;
|
||||||
private @MonotonicNonNull TextView selectedFileTextView;
|
private @MonotonicNonNull TextView selectedFileTextView;
|
||||||
private @MonotonicNonNull CheckBox removeAudioCheckbox;
|
private @MonotonicNonNull CheckBox removeAudioCheckbox;
|
||||||
private @MonotonicNonNull CheckBox removeVideoCheckbox;
|
private @MonotonicNonNull CheckBox removeVideoCheckbox;
|
||||||
@ -146,6 +156,7 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
private @MonotonicNonNull CheckBox enableHdrEditingCheckBox;
|
private @MonotonicNonNull CheckBox enableHdrEditingCheckBox;
|
||||||
private @MonotonicNonNull Button selectDemoEffectsButton;
|
private @MonotonicNonNull Button selectDemoEffectsButton;
|
||||||
private boolean @MonotonicNonNull [] demoEffectsSelections;
|
private boolean @MonotonicNonNull [] demoEffectsSelections;
|
||||||
|
private @Nullable Uri localFileUri;
|
||||||
private int inputUriPosition;
|
private int inputUriPosition;
|
||||||
private long trimStartMs;
|
private long trimStartMs;
|
||||||
private long trimEndMs;
|
private long trimEndMs;
|
||||||
@ -169,11 +180,10 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
findViewById(R.id.transform_button).setOnClickListener(this::startTransformation);
|
findViewById(R.id.transform_button).setOnClickListener(this::startTransformation);
|
||||||
|
|
||||||
selectFileButton = findViewById(R.id.select_file_button);
|
flattenForSlowMotionCheckbox = findViewById(R.id.flatten_for_slow_motion_checkbox);
|
||||||
selectFileButton.setOnClickListener(this::selectFile);
|
|
||||||
|
|
||||||
selectedFileTextView = findViewById(R.id.selected_file_text_view);
|
selectedFileTextView = findViewById(R.id.selected_file_text_view);
|
||||||
selectedFileTextView.setText(URI_DESCRIPTIONS[inputUriPosition]);
|
selectedFileTextView.setText(PRESET_FILE_URI_DESCRIPTIONS[inputUriPosition]);
|
||||||
|
|
||||||
removeAudioCheckbox = findViewById(R.id.remove_audio_checkbox);
|
removeAudioCheckbox = findViewById(R.id.remove_audio_checkbox);
|
||||||
removeAudioCheckbox.setOnClickListener(this::onRemoveAudio);
|
removeAudioCheckbox.setOnClickListener(this::onRemoveAudio);
|
||||||
@ -181,7 +191,11 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
removeVideoCheckbox = findViewById(R.id.remove_video_checkbox);
|
removeVideoCheckbox = findViewById(R.id.remove_video_checkbox);
|
||||||
removeVideoCheckbox.setOnClickListener(this::onRemoveVideo);
|
removeVideoCheckbox.setOnClickListener(this::onRemoveVideo);
|
||||||
|
|
||||||
flattenForSlowMotionCheckbox = findViewById(R.id.flatten_for_slow_motion_checkbox);
|
selectPresetFileButton = findViewById(R.id.select_preset_file_button);
|
||||||
|
selectPresetFileButton.setOnClickListener(this::selectPresetFile);
|
||||||
|
|
||||||
|
selectLocalFileButton = findViewById(R.id.select_local_file_button);
|
||||||
|
selectLocalFileButton.setOnClickListener(this::selectLocalFile);
|
||||||
|
|
||||||
ArrayAdapter<String> audioMimeAdapter =
|
ArrayAdapter<String> audioMimeAdapter =
|
||||||
new ArrayAdapter<>(/* context= */ this, R.layout.spinner_item);
|
new ArrayAdapter<>(/* context= */ this, R.layout.spinner_item);
|
||||||
@ -239,6 +253,27 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
demoEffectsSelections = new boolean[DEMO_EFFECTS.length];
|
demoEffectsSelections = new boolean[DEMO_EFFECTS.length];
|
||||||
selectDemoEffectsButton = findViewById(R.id.select_demo_effects_button);
|
selectDemoEffectsButton = findViewById(R.id.select_demo_effects_button);
|
||||||
selectDemoEffectsButton.setOnClickListener(this::selectDemoEffects);
|
selectDemoEffectsButton.setOnClickListener(this::selectDemoEffects);
|
||||||
|
|
||||||
|
localFilePickerLauncher =
|
||||||
|
registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
this::localFilePickerLauncherResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(
|
||||||
|
int requestCode, String[] permissions, int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
|
||||||
|
if (requestCode == FILE_PERMISSION_REQUEST_CODE
|
||||||
|
&& grantResults.length == 1
|
||||||
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
launchLocalFilePicker();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
getApplicationContext(), getString(R.string.permission_denied), Toast.LENGTH_LONG)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -246,7 +281,8 @@ 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(selectFileButton).setEnabled(false);
|
checkNotNull(selectPresetFileButton).setEnabled(false);
|
||||||
|
checkNotNull(selectLocalFileButton).setEnabled(false);
|
||||||
checkNotNull(selectedFileTextView).setText(intentUri.toString());
|
checkNotNull(selectedFileTextView).setText(intentUri.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,22 +362,64 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
bundle.putFloat(PERIODIC_VIGNETTE_OUTER_RADIUS, periodicVignetteOuterRadius);
|
bundle.putFloat(PERIODIC_VIGNETTE_OUTER_RADIUS, periodicVignetteOuterRadius);
|
||||||
transformerIntent.putExtras(bundle);
|
transformerIntent.putExtras(bundle);
|
||||||
|
|
||||||
@Nullable Uri intentUri = getIntent().getData();
|
@Nullable Uri intentUri;
|
||||||
transformerIntent.setData(
|
if (getIntent().getData() != null) {
|
||||||
intentUri != null ? intentUri : Uri.parse(INPUT_URIS[inputUriPosition]));
|
intentUri = getIntent().getData();
|
||||||
|
} else if (localFileUri != null) {
|
||||||
|
intentUri = localFileUri;
|
||||||
|
} else {
|
||||||
|
intentUri = Uri.parse(PRESET_FILE_URIS[inputUriPosition]);
|
||||||
|
}
|
||||||
|
transformerIntent.setData(intentUri);
|
||||||
|
|
||||||
startActivity(transformerIntent);
|
startActivity(transformerIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectFile(View view) {
|
private void selectPresetFile(View view) {
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.select_file_title)
|
.setTitle(R.string.select_preset_file_title)
|
||||||
.setSingleChoiceItems(URI_DESCRIPTIONS, inputUriPosition, this::selectFileInDialog)
|
.setSingleChoiceItems(
|
||||||
|
PRESET_FILE_URI_DESCRIPTIONS, inputUriPosition, this::selectPresetFileInDialog)
|
||||||
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
.setPositiveButton(android.R.string.ok, /* listener= */ null)
|
||||||
.create()
|
.create()
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresNonNull("selectedFileTextView")
|
||||||
|
private void selectPresetFileInDialog(DialogInterface dialog, int which) {
|
||||||
|
inputUriPosition = which;
|
||||||
|
localFileUri = null;
|
||||||
|
selectedFileTextView.setText(PRESET_FILE_URI_DESCRIPTIONS[inputUriPosition]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectLocalFile(View view) {
|
||||||
|
int permissionStatus =
|
||||||
|
ActivityCompat.checkSelfPermission(
|
||||||
|
ConfigurationActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
|
if (permissionStatus != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
String[] neededPermissions = {Manifest.permission.READ_EXTERNAL_STORAGE};
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
ConfigurationActivity.this, neededPermissions, FILE_PERMISSION_REQUEST_CODE);
|
||||||
|
} else {
|
||||||
|
launchLocalFilePicker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchLocalFilePicker() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
intent.setType("video/*");
|
||||||
|
checkNotNull(localFilePickerLauncher).launch(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresNonNull("selectedFileTextView")
|
||||||
|
private void localFilePickerLauncherResult(ActivityResult result) {
|
||||||
|
Intent data = result.getData();
|
||||||
|
if (data != null) {
|
||||||
|
localFileUri = checkNotNull(data.getData());
|
||||||
|
selectedFileTextView.setText(localFileUri.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void selectDemoEffects(View view) {
|
private void selectDemoEffects(View view) {
|
||||||
new AlertDialog.Builder(/* context= */ this)
|
new AlertDialog.Builder(/* context= */ this)
|
||||||
.setTitle(R.string.select_demo_effects)
|
.setTitle(R.string.select_demo_effects)
|
||||||
@ -373,12 +451,6 @@ public final class ConfigurationActivity extends AppCompatActivity {
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull("selectedFileTextView")
|
|
||||||
private void selectFileInDialog(DialogInterface dialog, int which) {
|
|
||||||
inputUriPosition = which;
|
|
||||||
selectedFileTextView.setText(URI_DESCRIPTIONS[inputUriPosition]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresNonNull("demoEffectsSelections")
|
@RequiresNonNull("demoEffectsSelections")
|
||||||
private void selectDemoEffect(DialogInterface dialog, int which, boolean isChecked) {
|
private void selectDemoEffect(DialogInterface dialog, int which, boolean isChecked) {
|
||||||
demoEffectsSelections[which] = isChecked;
|
demoEffectsSelections[which] = isChecked;
|
||||||
|
@ -34,16 +34,26 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/select_file_button"
|
android:id="@+id/select_preset_file_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="32dp"
|
android:layout_marginTop="32dp"
|
||||||
android:layout_marginStart="32dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginEnd="32dp"
|
android:text="@string/select_preset_file_title"
|
||||||
android:text="@string/select_file_title"
|
android:textSize="12sp"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/configuration_text_view"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/configuration_text_view" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/select_local_file_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/select_local_file_title"
|
||||||
|
android:textSize="12sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintTop_toBottomOf="@+id/configuration_text_view" />
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/selected_file_text_view"
|
android:id="@+id/selected_file_text_view"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@ -57,7 +67,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/select_file_button" />
|
app:layout_constraintTop_toBottomOf="@+id/select_preset_file_button" />
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="app_name" translatable="false">Transformer Demo</string>
|
<string name="app_name" translatable="false">Transformer Demo</string>
|
||||||
<string name="configuration" translatable="false">Configuration</string>
|
<string name="configuration" translatable="false">Configuration</string>
|
||||||
<string name="select_file_title" translatable="false">Choose file</string>
|
<string name="select_preset_file_title" translatable="false">Choose preset file</string>
|
||||||
|
<string name="select_local_file_title">Choose local file</string>
|
||||||
<string name="remove_audio" translatable="false">Remove audio</string>
|
<string name="remove_audio" translatable="false">Remove audio</string>
|
||||||
<string name="remove_video" translatable="false">Remove video</string>
|
<string name="remove_video" translatable="false">Remove video</string>
|
||||||
<string name="flatten_for_slow_motion" translatable="false">Flatten for slow motion</string>
|
<string name="flatten_for_slow_motion" translatable="false">Flatten for slow motion</string>
|
||||||
@ -61,6 +62,7 @@
|
|||||||
<string name="lightness_adjustment">Lightness adjustment</string>
|
<string name="lightness_adjustment">Lightness adjustment</string>
|
||||||
<string name="input_video">Input video:</string>
|
<string name="input_video">Input video:</string>
|
||||||
<string name="output_video">Output video:</string>
|
<string name="output_video">Output video:</string>
|
||||||
|
<string name="permission_denied">Permission Denied</string>
|
||||||
<string name="hide_input_video">Hide input video</string>
|
<string name="hide_input_video">Hide input video</string>
|
||||||
<string name="show_input_video">Show input video</string>
|
<string name="show_input_video">Show input video</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user