demonstrate how use to use SAF with some demo tabs

SAF is enabled for API 19 or higher
SAF pickers are used for FFprobe on CommandTabFragment and for video output on PipeTabFragment
This commit is contained in:
alexcohn
2020-08-06 15:06:43 +03:00
parent 2a1168867c
commit 97b2581522
11 changed files with 125 additions and 16 deletions
@@ -263,6 +263,7 @@ public class AudioTabFragment extends Fragment implements AdapterView.OnItemSele
disableLogCallback();
createAudioSample();
enableLogCallback();
((MainActivity)requireActivity()).enableSaf(true);
Popup.show(requireContext(), getString(R.string.audio_test_tooltip_text));
}
@@ -19,6 +19,8 @@
package com.arthenica.mobileffmpeg.test;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.AndroidRuntimeException;
@@ -43,6 +45,8 @@ public class CommandTabFragment extends Fragment {
private EditText commandText;
private TextView outputText;
private static final int REQUEST_SAF_FFPROBE = 11;
private boolean backFromIntent = false;
public CommandTabFragment() {
super(R.layout.fragment_command_tab);
@@ -59,7 +63,7 @@ public class CommandTabFragment extends Fragment {
@Override
public void onClick(View v) {
runFFmpeg();
runFFmpeg(commandText.getText().toString());
}
});
@@ -68,7 +72,10 @@ public class CommandTabFragment extends Fragment {
@Override
public void onClick(View v) {
runFFprobe();
if (((MainActivity)requireActivity()).isSafUsed())
chooseInputFile();
else
runFFprobe(commandText.getText().toString());
}
});
@@ -81,7 +88,9 @@ public class CommandTabFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
setActive();
if (!backFromIntent)
setActive();
backFromIntent = false;
}
public static CommandTabFragment newInstance() {
@@ -107,11 +116,9 @@ public class CommandTabFragment extends Fragment {
});
}
public void runFFmpeg() {
private void runFFmpeg(final String ffmpegCommand) {
clearLog();
final String ffmpegCommand = String.format("%s", commandText.getText().toString());
android.util.Log.d(MainActivity.TAG, String.format("Current log level is %s.", Config.getLogLevel()));
android.util.Log.d(MainActivity.TAG, "Testing FFmpeg COMMAND synchronously.");
@@ -127,11 +134,9 @@ public class CommandTabFragment extends Fragment {
}
}
public void runFFprobe() {
private void runFFprobe(String ffprobeCommand) {
clearLog();
final String ffprobeCommand = String.format("%s", commandText.getText().toString());
android.util.Log.d(MainActivity.TAG, "Testing FFprobe COMMAND synchronously.");
android.util.Log.d(MainActivity.TAG, String.format("FFprobe process started with arguments\n\'%s\'", ffprobeCommand));
@@ -145,9 +150,19 @@ public class CommandTabFragment extends Fragment {
}
}
private void runFFprobe(Uri inputUri) {
if (commandText.getText().toString().trim().isEmpty()) {
runFFprobe("-hide_banner -print_format json -show_format -show_streams " + Config.getSafParameterForRead(requireContext(), inputUri));
}
else {
runFFprobe(commandText.getText().toString() + " " + Config.getSafParameterForRead(requireContext(), inputUri));
}
}
private void setActive() {
Log.i(MainActivity.TAG, "Command Tab Activated");
enableLogCallback();
((MainActivity)requireActivity()).enableSaf(true);
Popup.show(requireContext(), getString(R.string.command_test_tooltip_text));
}
@@ -159,4 +174,22 @@ public class CommandTabFragment extends Fragment {
outputText.setText("");
}
private void chooseInputFile() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT)
.setType("*/*")
.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"image/*", "video/*", "audio/*"})
.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_SAF_FFPROBE);
Popup.show(requireContext(), "choose input for FFPROBE");
backFromIntent = true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SAF_FFPROBE && resultCode == MainActivity.RESULT_OK && data != null) {
runFFprobe(data.getData());
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
@@ -263,6 +263,7 @@ public class ConcurrentExecutionTabFragment extends Fragment {
public void setActive() {
Log.i(MainActivity.TAG, "Concurrent Execution Tab Activated");
enableLogCallback();
((MainActivity)requireActivity()).enableSaf(false);
Popup.show(requireContext(), getString(R.string.concurrent_execution_test_tooltip_text));
}
@@ -216,6 +216,7 @@ public class HttpsTabFragment extends Fragment {
public void setActive() {
Log.i(MainActivity.TAG, "Https Tab Activated");
enableLogCallback();
((MainActivity)requireActivity()).enableSaf(false);
Popup.show(requireContext(), getString(R.string.https_test_tooltip_text));
}
@@ -23,9 +23,15 @@ import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Switch;
import android.widget.ToggleButton;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
@@ -189,4 +195,26 @@ public class MainActivity extends AppCompatActivity {
}
}
private Switch saf_button;
public boolean isSafUsed() {
return saf_button != null ? saf_button.isChecked() : false;
}
public void enableSaf(boolean enabled) {
if (saf_button != null)
saf_button.setEnabled(enabled);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.saf_menu, menu);
MenuItem item = (MenuItem) menu.findItem(R.id.saf_button);
saf_button = item.getActionView().findViewById(R.id.saf_button);
saf_button.setText("SAF");
}
return true;
}
}
@@ -20,6 +20,7 @@
package com.arthenica.mobileffmpeg.test;
import android.app.AlertDialog;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
@@ -58,13 +59,16 @@ public class PipeTabFragment extends Fragment {
private VideoView videoView;
private AlertDialog progressDialog;
private Statistics statistics;
private Uri videoUri;
private static final int REQUEST_CREATE_DOCUMENT = 12;
private boolean backFromIntent = false;
public PipeTabFragment() {
super(R.layout.fragment_pipe_tab);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View createButton = view.findViewById(R.id.createButton);
@@ -73,7 +77,12 @@ public class PipeTabFragment extends Fragment {
@Override
public void onClick(View v) {
createVideo();
if (((MainActivity)requireActivity()).isSafUsed())
chooseOutputVideoAndCreate();
else {
videoUri = Uri.fromFile(getVideoFile());
createVideo(videoUri.getPath());
}
}
});
}
@@ -86,7 +95,9 @@ public class PipeTabFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
setActive();
if (!backFromIntent)
setActive();
backFromIntent = false;
}
public static PipeTabFragment newInstance() {
@@ -126,11 +137,11 @@ public class PipeTabFragment extends Fragment {
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imagePath, namedPipePath);
}
public void createVideo() {
public void createVideo(String videoPath) {
final File image1File = new File(requireContext().getCacheDir(), "colosseum.jpg");
final File image2File = new File(requireContext().getCacheDir(), "pyramid.jpg");
final File image3File = new File(requireContext().getCacheDir(), "tajmahal.jpg");
final File videoFile = getVideoFile();
final File videoFile = new File(videoPath);
String pipe1 = Config.registerNewFFmpegPipe(requireContext());
String pipe2 = Config.registerNewFFmpegPipe(requireContext());
@@ -153,7 +164,7 @@ public class PipeTabFragment extends Fragment {
ResourcesUtil.resourceToFile(getResources(), R.drawable.pyramid, image2File);
ResourcesUtil.resourceToFile(getResources(), R.drawable.tajmahal, image3File);
final String ffmpegCommand = Video.generateCreateVideoWithPipesScript(pipe1, pipe2, pipe3, videoFile.getAbsolutePath());
final String ffmpegCommand = Video.generateCreateVideoWithPipesScript(pipe1, pipe2, pipe3, videoPath);
Log.d(TAG, String.format("FFmpeg process started with arguments\n'%s'.", ffmpegCommand));
@@ -197,7 +208,7 @@ public class PipeTabFragment extends Fragment {
protected void playVideo() {
MediaController mediaController = new MediaController(requireContext());
mediaController.setAnchorView(videoView);
videoView.setVideoURI(Uri.parse("file://" + getVideoFile().getAbsolutePath()));
videoView.setVideoURI(videoUri);
videoView.setMediaController(mediaController);
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@@ -222,10 +233,30 @@ public class PipeTabFragment extends Fragment {
return new File(requireContext().getFilesDir(), "video.mp4");
}
private void chooseOutputVideoAndCreate() {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
.setType("video/*")
.putExtra(Intent.EXTRA_TITLE, "video.mp4")
.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_CREATE_DOCUMENT);
backFromIntent = true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CREATE_DOCUMENT && resultCode == MainActivity.RESULT_OK && data != null) {
videoUri = data.getData();
createVideo(Config.getSafParameterForReadAndWrite(requireContext(), videoUri));
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
public void setActive() {
Log.i(MainActivity.TAG, "Pipe Tab Activated");
enableLogCallback();
enableStatisticsCallback();
((MainActivity)requireActivity()).enableSaf(false);
Popup.show(requireContext(), getString(R.string.pipe_test_tooltip_text));
}
@@ -272,6 +272,7 @@ public class SubtitleTabFragment extends Fragment {
Log.i(MainActivity.TAG, "Subtitle Tab Activated");
enableLogCallback();
enableStatisticsCallback();
((MainActivity)requireActivity()).enableSaf(false);
Popup.show(requireContext(), getString(R.string.subtitle_test_tooltip_text));
}
@@ -282,6 +282,7 @@ public class VidStabTabFragment extends Fragment {
public void setActive() {
Log.i(MainActivity.TAG, "VidStab Tab Activated");
enableLogCallback();
((MainActivity)requireActivity()).enableSaf(false);
Popup.show(requireContext(), getString(R.string.vidstab_test_tooltip_text));
}
@@ -356,6 +356,7 @@ public class VideoTabFragment extends Fragment implements AdapterView.OnItemSele
Log.i(MainActivity.TAG, "Video Tab Activated");
enableLogCallback();
enableStatisticsCallback();
((MainActivity)requireActivity()).enableSaf(false);
Popup.show(requireContext(), getString(R.string.video_test_tooltip_text));
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="@+id/saf_button"
android:title="@string/saf_button_text"
app:actionViewClass="android.widget.Switch"
android:orderInCategory="100"
app:showAsAction="always"/>
</menu>
@@ -25,4 +25,5 @@
<string name="cancel_button_text_2">Cancel 2</string>
<string name="cancel_button_text_3">Cancel 3</string>
<string name="cancel_button_text_all">Cancel All</string>
<string name="saf_button_text">SAF</string>
</resources>