gow*_*ami 25 permissions android ffmpeg rtsp android-10.0
我想使用 ffmpeg 从 RTSP 视频中获取帧。但是对于上面的 android 10,我收到如下错误。
E/FFmpeg: Exception while trying to run: [Ljava.lang.String;@55e447f
java.io.IOException: Cannot run program "/data/user/0/com.example.downloadimagefromurl/files/ffmpeg": error=13, Permission denied
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1050)
at java.lang.Runtime.exec(Runtime.java:698)
at java.lang.Runtime.exec(Runtime.java:563)
at com.github.hiteshsondhi88.libffmpeg.ShellCommand.run(ShellCommand.java:10)
at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:38)
at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:10)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.io.IOException: error=13, Permission denied
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:133)
Run Code Online (Sandbox Code Playgroud)
正如@Saurabh Thorat 提供的答案一样,Google 不允许应用程序从 /data/user 目录运行二进制文件。
我知道的一个糟糕的解决方案是将 compileSdkVersion 和 targetSdkVersion 更改为 28 或更低,然后重新发布我不推荐的应用程序。
因此,我也在为未来的版本寻找更可行的解决方案。
任何提示、链接或建议将不胜感激。提前致谢。
Sau*_*rat 11
从 Android Q 开始,您无法在应用的私有数据目录中执行二进制文件。
来自问题跟踪器:https ://issuetracker.google.com/issues/128554619
在 targetAPI >= Q 的应用程序数据文件上阻止 exec() 的更改按预期工作。 有关此更改的背景信息,请参阅 https://android-review.googlesource.com/c/platform/system/sepolicy/+/804149。在可写的应用程序文件上调用 exec() 是 W^X ( https://en.wikipedia.org/wiki/W%5EX ) 违规,代表不安全的应用程序实践。可执行代码应始终从应用程序 APK 加载。
虽然 exec() 不再适用于应用程序主目录中的文件,但它继续支持只读 /data/app 目录中的文件。特别是,应该可以将二进制文件打包到应用程序的本机 libs 目录中并启用 android:extractNativeLibs=true,然后在 /data/app 工件上调用 exec()。使用 wrap.sh 功能完成了类似的方法,记录在 https://developer.android.com/ndk/guides/wrap-script#packaging_wrapsh 。
此外,请注意通过 exec() 执行的可执行文件不是根据 Android 进程生命周期管理的,一般来说,Android 应用程序不鼓励 exec()。虽然不是 Android 文档, 但在NDK 中使用“exec()”对此进行了一些详细说明。依赖 exec() 在未来的 Android 版本中可能会出现问题。
仅将 Build.gradle 文件 targetSdkVersion 29更改为 28 并在您的设备上重新安装您的应用程序 - 由于 targetSdkVersion 29 是在 Play 商店发布构建所需的平台,因此暂时解决了您的权限问题,因此我建议您使用它库,支持目标Sdk 30
https://github.com/SimformSolutionsPvtLtd/SSffmpegVideoOperation
根据@Saurabh Thorat 的回答,我提出了一个解决问题的拉取请求。你可以在这里找到它。
快速总结:
将 ffmpeg 二进制文件移至 libs 文件夹并添加
android:extractNativeLibs = "true"到清单中,以便它可以将自身复制到其中/data/app/{package_name}/lib/{arch}/,然后从那里执行(Android 10 支持)。
编辑(一般用途):为了将可执行文件复制到/data/app/{package_name}/lib/{arch}/,文件名必须是lib(something).so. 如果名称不以 开头lib和结尾.so,则不会复制它们。
在早期的答案正确地解释你打的问题。这也是去年 9 月提出的一个悬而未决的问题,在您使用的库的论坛上进行了讨论(从我在堆栈跟踪中看到的内容)。
为 SDK 29 编译的解决方案是停止将二进制文件放在 /data/ 目录中,并确保它们位于本机 libs 目录中。在非 root 设备上安装和解压 APK 后无法实现,因此在准备 Android 项目时应正确完成(例如通过 gradle 设置),并确保在安装时正确解压内容:android:extractNativeLibs=true.
在您的情况下,此代码将打包为“资产”的二进制文件移动到用户数据目录中:
这是在可读/可写位置运行任何可执行文件的安全问题。我上面链接的源代码需要删除,而是打包在 /libs 中的本机二进制文件。由于应用程序安装目录中的 /libs 位置是可执行的但不可写,因此更改更加安全。
总之,第 3 方库需要解决它,或者您可以这样做并贡献一个拉取请求。或者 fork 自己的并为自己重新编译。
如果您的应用程序在安装后实际下载内容,并希望执行任何下载,那么仍然存在问题。据我所知,现在在 Android 10 中这是不可能的。
面向未来的解决方案是停止使用外部二进制文件,并将依赖项编译为 NDK 项目。他们将需要围绕本机代码的 jni 包装器(一些工作)。还有一个相关的项目,我知道的,你可以看看。
我在使用FFmpeg-Android-Java时遇到了同样的情况。似乎不再支持这个库......所以我只是转移到MobileFFmpeg并且工作起来很有魅力!
如果您使用 gradle 插件 4.0.0(及更高版本),您唯一需要注意的是在模块级 build.gradle 中添加以下内容:
android {
packagingOptions {
pickFirst 'lib/x86/libc++_shared.so'
pickFirst 'lib/x86_64/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15411 次 |
| 最近记录: |