Android端实现FFmpeg音频转码时出现error=13权限拒绝问题求助
问题根因与排查解决步骤
1. 核心硬伤:可执行文件平台不兼容
这个报错在当前场景下根本不是常规理解的“权限没给够”,本质是Android Linux内核根本无法识别Windows格式的PE可执行文件:
- 你当前代码里指定路径的
ffmpeg.exe是面向64位Windows系统编译的程序,完全无法在Android系统上运行,内核遇到无法识别执行格式的文件时,会统一抛出权限拒绝的错误码,和你给多大文件权限无关。 - 你需要彻底弃用Windows端的exe文件,替换为对应Android CPU架构(主流为arm64-v8a,兼容老设备可额外适配armeabi-v7a)编译的原生ELF格式ffmpeg可执行文件,不能把开发宿主机Windows上的exe直接拷贝到Android设备里运行。
2. 可执行文件的存放路径合规问题
Android系统从设计层面就禁止从非应用私有目录启动可执行程序,你当前代码里涉及的路径都不符合系统规则:
- 公共外部存储目录(比如你代码里用到的
DIRECTORY_DOWNLOADS下载目录)从Android 10开始,所有文件默认都没有可执行权限,哪怕手动修改文件权限也无法通过系统限制,不存在通过申请存储权限解决的可能。 - 正确的存放位置必须是应用的私有文件目录:
/data/data/你的应用包名/files/,系统对这个目录下的文件开放全部读写、执行权限,不会触发安全拦截。- 操作流程:把编译好的Android版ffmpeg文件提前放到APK的assets目录下,应用首次启动时将assets里的ffmpeg文件拷贝到上述私有目录,再返回这个拷贝后的绝对路径给自定义的FFMPEGLocator,不要返回assets内的原始路径(assets是打包在APK压缩包内的,没有文件系统真实路径,无法直接执行)。
- 注意路径格式:Android是Linux文件系统,路径全部用正斜杠分隔,没有Windows的盘符、反斜杠、.exe后缀,你代码里现在写的
...\\\\bin\\\\ffmpeg.exe格式的路径在Android系统中根本不存在。
3. 可执行文件的权限配置
完成ffmpeg文件的私有目录拷贝后,必须给文件加上系统可识别的执行权限:
- 拷贝完成后通过执行shell命令给文件赋权:
Runtime.getRuntime().exec(String.format("chmod 755 %s", targetFfmpegFile.getAbsolutePath())); - 不要尝试给文件加过高的权限(比如777),系统安全机制会拦截权限过高的可执行文件,755的所有者可读可执行、其他用户可读的权限完全满足运行要求。
4. 现有代码的调整提示
- 自定义的
SampleLocator类不需要硬编码文件路径,可通过上下文获取当前应用私有目录路径,动态拼接ffmpeg的实际执行路径,例如:class SampleLocator extends FFMPEGLocator { private Context appContext; public SampleLocator(Context context) { this.appContext = context; } @Override protected String getFFMPEGExecutablePath() { File ffmpegFile = new File(appContext.getFilesDir(), "ffmpeg"); return ffmpegFile.getAbsolutePath(); } } - 初始化Encoder时,传入带上下文的Locator实例,不要使用无路径上下文的空构造。
注意:不要为了绕过限制申请
MANAGE_EXTERNAL_STORAGE全文件访问权限,Android应用市场对这类权限的审核非常严格,且就算申请通过,系统依然禁止从外部存储启动可执行文件,属于无效方案。
内容的提问来源于stack exchange,提问作者Fc0001
相关产品推荐
相关产品推荐

