Android中Chaquopy调用yt_dlp无法访问FFmpeg二进制文件问题
解决Chaquopy中yt_dlp无法调用FFmpeg的问题
先理清几个关键问题:
- 普通Linux arm64的FFmpeg二进制不能直接在Android上运行,Android的内核和系统库与标准Linux存在差异,必须使用针对Android编译的版本。
- app私有目录(
getFilesDir())不需要申请外部存储权限,之前添加的权限完全多余,无需在这方面浪费时间。
步骤1:替换为Android兼容的FFmpeg二进制
- 获取适配
arm64-v8a架构的FFmpeg:- 可以从ffmpeg-kit的预编译资源中提取对应架构的ffmpeg文件;
- 或者自行使用Android NDK编译FFmpeg,编译时需指定Android目标平台和系统库依赖。
- 将正确的二进制文件替换
src/main/assets目录下的原文件。
步骤2:确保文件复制与权限设置生效
修改FileUtils中的权限设置代码,并直接测试FFmpeg能否正常运行:
// 替换原权限设置部分 outFile.setExecutable(true, false); // 给文件所有者设置可执行权限,私有目录场景下足够 outFile.setReadable(true, false); outFile.setWritable(true, false); // 复制完成后立即测试FFmpeg是否可执行 try { Process process = Runtime.getRuntime().exec(ffmpegPath + " -version"); int exitCode = process.waitFor(); Log.d("FileUtils", "FFmpeg测试退出码:" + exitCode); // 退出码为0说明二进制正常,非0则表示二进制不兼容 } catch (Exception e) { e.printStackTrace(); }
步骤3:动态传递路径给Python,避免硬编码
Python中硬编码包名路径极易出错,直接从Java层传递正确路径:
// MainActivity中,完成FFmpeg复制后传递路径给Python Python py = Python.getInstance(); PyObject pyScript = py.getModule("你的Python脚本名(不带.py后缀)"); pyScript.callAttr("set_ffmpeg_path", ffmpegPath);
在Python脚本中接收路径:
import yt_dlp as youtube_dl ffmpeg_path = None def set_ffmpeg_path(path): global ffmpeg_path ffmpeg_path = path # 配置yt_dlp时使用传递过来的路径 ydl_opts = { 'ffmpeg_location': ffmpeg_path, 'format': 'bestvideo+bestaudio/best', 'postprocessors': [{ 'key': 'FFmpegVideoConvertor', 'preferedformat': 'mp4' }], 'noplaylist': True, 'quiet': True, 'merge_output_format': 'mp4', 'outtmpl': filename + '.%(ext)s', }
步骤4:在Python中验证FFmpeg可访问性
下载操作前先测试FFmpeg能否被Python调用,精准定位问题:
import subprocess try: result = subprocess.run([ffmpeg_path, "-version"], capture_output=True, text=True) print("FFmpeg版本信息:", result.stdout) if result.returncode != 0: print("FFmpeg执行错误:", result.stderr) except Exception as e: print("调用FFmpeg失败:", str(e))
根据输出判断问题类型:
Permission denied:权限设置有误,回到步骤2检查;No such file or directory:路径传递错误,核对Java层传递的路径;error while loading shared libraries:二进制不兼容,回到步骤1更换正确版本。
额外提醒
- 不要将FFmpeg放入
jniLibs目录,Python无法直接访问该目录下的文件; - 确保在Python脚本运行前完成FFmpeg的复制操作,例如在
onCreate中先执行复制再初始化Python环境; - Android 11+的私有目录访问限制不会影响
getFilesDir(),可放心使用。
内容的提问来源于stack exchange,提问作者Dudek 3D
相关产品推荐
相关产品推荐

