FFMPEG 命令不适用于 Android 10
Posted
技术标签:
【中文标题】FFMPEG 命令不适用于 Android 10【英文标题】:FFMPEG Commands is not working on Android 10 【发布时间】:2020-04-30 03:04:15 【问题描述】:我正在开发一款应用视频效果(如慢动作和快动作)的 android 应用。我的应用在 android 10 下运行良好,但在 android 10 上运行良好,FFMPEG 没有显示任何错误,只是在 onFailure 回调方法上显示空白错误消息。
我做了一些研究,发现 android 引入了范围权限,您可以通过在清单 android:requestLegacyExternalStorage="true" 上添加此行来暂时绕过它,您将获得存储权限。 添加此行后,应用程序的其余端口可以正常获取用户视频等,但 FFMPEG 无法正常工作。
如果有人对此问题有任何想法或线索,请帮助我。
【问题讨论】:
也许FFmpeg doesn't work on android 10, goes strait to onFailure(String message) with empty message 会有所帮助。 实际上是说FFmpeg正在主目录上执行,android 10删除了应用主目录的执行权限。到目前为止,它看起来像一个死胡同。 ***.com/a/59686838/8416317 感谢您的链接,这些库回调以不同的方式工作,但我会尝试一下 我也有同样的问题。 【参考方案1】:这是适用于 API 16 及以上兼容设备的工作版本。支持android API 29(Q)
dependencies
implementation 'com.arthenica:mobile-ffmpeg-full:4.4.LTS'
MobileFFmpeg v4.4 的长期支持包
支持以下设备规格
安卓
Android 4.1(API 级别 16)或更高版本
x86 和 x86-64 架构sarm-v7a、arm-v7a-neon、arm64-v8a、
您可以在official repo on github找到更多信息
更新:2021 年 6 月 20 日
不再维护,如What’s next for MobileFFmpeg?中所述
现在被FFmpegKit取代
在这里你可以找到FFmpegKit For Android
特点
在主要版本上支持 API 级别 24+,在 LTS 上支持 API 级别 16+ 发布 包括 arm-v7a、arm-v7a-neon、arm64-v8a、x86 和 x86_64 架构 可以处理存储访问框架 (SAF) Uris 支持设备上的相机访问权限 构建共享本机库 (.so) 创建带有 .aar 扩展名的 Android 存档【讨论】:
在 Manifest 中为 min API 24 编写的库 @MortezaKhodaie 请查看文档了解 LTS 版本 LTS Releases【参考方案2】:试试这个
依赖
实施 'com.arthenica:mobile-ffmpeg-full:4.4.LTS'
也看到这个.. ffmpeg-video-editor-android
【讨论】:
在 Manifest 中为 min API 24 编写的库 此库将 apk 大小增加到 64 MB 以上。【参考方案3】:使用这个支持 targetSdkVersion 29 的库。
实现'com.arthenica:mobile-ffmpeg-video:4.4'
用于视频压缩的命令:
val complexCommand = arrayOf( “-y”, “-一世”, 输入路径!!, “-s”, "640x480", "-r", "25", “-vcodec”, "mpeg4", "-b:v", "1000k", "-b:a", "48000", “-ac”, "2", “-ar”, "22050", 输出文件路径 )
压缩方式:
private fun execFFmpegBinary(command: Array<String>, inputPath: String?, listener: CompressionListener?, outputFilePath: String)
Config.enableLogCallback message -> Log.e(Config.TAG, message.text)
Config.enableStatisticsCallback newStatistics ->
Log.e(
Config.TAG,
String.format(
"frame: %d, time: %d",
newStatistics.videoFrameNumber,
newStatistics.time
)
)
Log.d(
TAG,
"Started command : ffmpeg " + Arrays.toString(command)
)
val videoLength = inputPath?.let VideoUtils.getVideoDuration(it)
Log.d(TAG, "execFFmpegBinary: Video Length : $videoLength")
val progress: Float =
java.lang.String.valueOf(newStatistics.time).toFloat() / videoLength!!
val progressFinal = progress * 100
Log.d(TAG, "Video Length: $progressFinal")
Log.d(
Config.TAG,
java.lang.String.format(
"frame: %d, time: %d",
newStatistics.videoFrameNumber,
newStatistics.time
)
)
Log.d(
Config.TAG,
java.lang.String.format(
"Quality: %f, time: %f",
newStatistics.videoQuality,
newStatistics.videoFps
)
)
//progressDialog.setProgress(progressFinal.toInt())
//val adjustProgress = progressFinal/1.5f
Log.d(TAG, "execFFmpegBinary: Progress: $progressFinal.toInt()")
listener?.onProgress(progressFinal.toInt())
Log.d(TAG, "progress : $newStatistics")
Log.d(
TAG,
"Started command : ffmpeg " + Arrays.toString(command)
)
/* progressDialog.setMessage("Processing...")
progressDialog.show()*/
val executionId = com.arthenica.mobileffmpeg.FFmpeg.executeAsync(
command
) executionId1: Long, returnCode: Int ->
if (returnCode == RETURN_CODE_SUCCESS)
Log.d(
TAG,
"Finished command : ffmpeg " + Arrays.toString(command)
)
listener?.compressionFinished(SUCCESS, true, fileOutputPath = outputFilePath)
else if (returnCode == Config.RETURN_CODE_CANCEL)
Log.e(
TAG,
"Async command execution cancelled by user."
)
listener?.onFailure(String.format(
"Async command execution cancelled by user."
))
//if (progressDialog != null) progressDialog.dismiss()
else
Log.e(
TAG,
String.format(
"Async command execution failed with returnCode=%d.",
returnCode
)
)
listener?.onFailure(String.format(
"Async command execution failed with returnCode=%d.",
returnCode
))
// if (progressDialog != null) progressDialog.dismiss()
Log.e(TAG, "execFFmpegMergeVideo executionId-$executionId")
压缩监听器:
interface CompressionListener
fun compressionFinished(
status: Int,
isVideo: Boolean,
fileOutputPath: String?
)
fun onFailure(message: String?)
fun onProgress(progress: Int)
调用方式:
execFFmpegBinary(complexCommand, inputPath, listener, outputFilePath)
【讨论】:
此库将 apk 大小增加到 64 MB 以上。 您可以在 build.gradle 中使用这样的拆分 apk 来减小大小。检查这个:developer.android.com/studio/build/configure-apk-splits.html 它会降低视频质量。你检查了吗? 你可以使用我开发的这个库。为了保持视频质量,我们需要根据视频分辨率计算 crf。查看回购。 github.com/cvivek07/FFmpegVideoCompressor以上是关于FFMPEG 命令不适用于 Android 10的主要内容,如果未能解决你的问题,请参考以下文章
ffmpeg hls_time选项不适用于h264_nvenc
buildozer 构建 apk 但不适用于 android