如何在 Android 31 中通过 ffmpeg 操作文件:权限被拒绝
How to manipulate files by ffmpeg in Android 31: permission denied
我正在尝试在我的 android 应用程序中使用 FFmpeg。所以我想在继续之前测试它是否有效。我使用外部库:github link
代码如下所示:
package net.omidn.aslanmediaconverter;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.arthenica.ffmpegkit.ExecuteCallback;
import com.arthenica.ffmpegkit.FFmpegKit;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.arthenica.ffmpegkit.Session;
import net.bramp.ffmpeg.job.FFmpegJob;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
FFmpegJob myjob;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text_view);
FFmpegJob job = null;
File inFile = new File("/storage/emulated/0/video_2021-05-29_17-50-20.mp4");
String inputName = Uri.fromFile(inFile).toString();
Log.d(TAG, inputName);
Log.d(TAG,"file exists : " + String.valueOf(inFile.exists()));
Log.d(TAG,"file canRead : " + String.valueOf(inFile.canRead()));
FFmpegSession fFmpegSession = FFmpegKit.executeAsync("-i file:///storage/emulated/0/video_2021-05-29_17-50-20.mp4 -c:v mpeg4 file:///storage/emulated/0/out.mp4",
new ExecuteCallback() {
@Override
public void apply(Session session) {
}
});
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
textView.setText("" + fFmpegSession.getState().name() + " " + fFmpegSession.getOutput());
}
}
如您所见,我使用 file:///
协议提供文件。如果我不使用它,结果是一样的。 Log.d(...)
的三行将打印:
2021-06-03 00:58:08.869 8376-8376/net.omidn.aslanmediaconverter D/MainActivity: file:///storage/emulated/0/video_2021-05-29_17-50-20.mp4
2021-06-03 00:58:08.869 8376-8376/net.omidn.aslanmediaconverter D/MainActivity: file exists : true
2021-06-03 00:58:08.869 8376-8376/net.omidn.aslanmediaconverter D/MainActivity: file canRead : false
视频文件对存储具有读取权限:
我从 the libraries wiki 页面找到了执行此操作的方法。
这里引用一下:
如果要将使用存储访问框架 (SAF) 选择的文件与 FFmpegKit
一起使用,可以使用以下方法将 Uri
转换为使用 [=12] 定义的文件路径=] 的 saf: 协议。该路径可以安全地用作 FFmpegKit
和 FFprobeKit
命令中的输入或输出。
输入
Uri uri = intent.getData();
String inputPath = FFmpegKitConfig.getSafParameterForRead(requireContext(), uri);
FFmpegKit.execute("-i " + inputPath + " ... output.mp4");
输出
Uri uri = intent.getData();
String outputPath = FFmpegKitConfig.getSafParameterForWrite(requireContext(), uri);
FFmpegKit.execute("-i input.mp4 ... " + outputPath);
我正在尝试在我的 android 应用程序中使用 FFmpeg。所以我想在继续之前测试它是否有效。我使用外部库:github link
代码如下所示:
package net.omidn.aslanmediaconverter;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.arthenica.ffmpegkit.ExecuteCallback;
import com.arthenica.ffmpegkit.FFmpegKit;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.arthenica.ffmpegkit.Session;
import net.bramp.ffmpeg.job.FFmpegJob;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
FFmpegJob myjob;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text_view);
FFmpegJob job = null;
File inFile = new File("/storage/emulated/0/video_2021-05-29_17-50-20.mp4");
String inputName = Uri.fromFile(inFile).toString();
Log.d(TAG, inputName);
Log.d(TAG,"file exists : " + String.valueOf(inFile.exists()));
Log.d(TAG,"file canRead : " + String.valueOf(inFile.canRead()));
FFmpegSession fFmpegSession = FFmpegKit.executeAsync("-i file:///storage/emulated/0/video_2021-05-29_17-50-20.mp4 -c:v mpeg4 file:///storage/emulated/0/out.mp4",
new ExecuteCallback() {
@Override
public void apply(Session session) {
}
});
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
textView.setText("" + fFmpegSession.getState().name() + " " + fFmpegSession.getOutput());
}
}
如您所见,我使用 file:///
协议提供文件。如果我不使用它,结果是一样的。 Log.d(...)
的三行将打印:
2021-06-03 00:58:08.869 8376-8376/net.omidn.aslanmediaconverter D/MainActivity: file:///storage/emulated/0/video_2021-05-29_17-50-20.mp4
2021-06-03 00:58:08.869 8376-8376/net.omidn.aslanmediaconverter D/MainActivity: file exists : true
2021-06-03 00:58:08.869 8376-8376/net.omidn.aslanmediaconverter D/MainActivity: file canRead : false
视频文件对存储具有读取权限:
我从 the libraries wiki 页面找到了执行此操作的方法。
这里引用一下:
如果要将使用存储访问框架 (SAF) 选择的文件与 FFmpegKit
一起使用,可以使用以下方法将 Uri
转换为使用 [=12] 定义的文件路径=] 的 saf: 协议。该路径可以安全地用作 FFmpegKit
和 FFprobeKit
命令中的输入或输出。
输入
Uri uri = intent.getData();
String inputPath = FFmpegKitConfig.getSafParameterForRead(requireContext(), uri);
FFmpegKit.execute("-i " + inputPath + " ... output.mp4");
输出
Uri uri = intent.getData();
String outputPath = FFmpegKitConfig.getSafParameterForWrite(requireContext(), uri);
FFmpegKit.execute("-i input.mp4 ... " + outputPath);