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:
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
+42
-9
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+38
-7
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user