Android FFmpeg 编译可执行命令程序(依赖动态库)

项目中有两种情况用到 FFmpeg :

  1. C++ 底层代码调用 FFmpeg 用于音视频解码
  2. Android 上层使用 FFmpeg 命令行工具用于音视频裁剪、分离、加水印等

一般用法是编译一份 FFmpeg 静态库或动态库(大小 4M+)用于底层依赖和调用,再编译一份 ffmpeg 可执行程序(大小 4M+),但这样实际上项目中有两份 ffmpeg 核心库,会增加安装包体积。因此优化如下:

  1. 编译一份 libffmepg.so (大小 4M+),底层代码依赖和可执行程序共同依赖该动态库;
  2. 将 ffmpeg.c 等代码依赖 libffmepg.so 编译 libffmpeg_tool.so 编译成可执行程序(大小几百K,安装包中 90K)

这样项目中减少一份 ffmpeg 核心库的大小(4M+),安装包能减小 1.5~1.7M

libffmpeg_tool.so 调用方式:
1、通过 adb shell 调用测试:

# 将 libffmpeg_tool.so 和 libffmpeg.so 放到 /data/local/tmp 目录
adb push libffmpeg_tool.so /data/local/tmp
adb push libffmpeg.so /data/local/tmp
# adb shell 并进入 /data/local/tmp 目录
adb shell
cd /data/local/tmp
# 给 libffmpeg_tool.so 赋予可执行权限
chmod +x libffmpeg_tool.so
# 增加链接库路径(因为 libffmpeg_tool.so 执行时需要依赖 libffmpeg.so)
export LD_LIBRARY_PATH=/data/local/tmp:$LD_LIBRARY_PATH
./libffmpeg_tool.so -i /sdcard/Alan/ffmpeg/test.mp4

2、在 Android 项目中执行

private Process exec(String cmd) throws IOException {
     
        String filepath = getSoFilePath();
        if (!TextUtils.isEmpty(filepath)) {
     
            String nativeLibrariesPath = mContext.getApplicationContext().getApplicationInfo().nativeLibraryDir;
            Log.e(TAG ," nativeLibrariesPath = " + nativeLibrariesPath);

            ProcessBuilder processBuilder = new ProcessBuilder();
            Map<String, String> envMap = processBuilder.environment();
            envMap.put("LD_LIBRARY_PATH", nativeLibrariesPath);

            String _cmd = String.format("%s %s", filepath, cmd);
            Log.d(TAG, "_cmd:" + _cmd);
            String[] commands = {
      "sh", "-c", _cmd };
            processBuilder.command(commands);

            return processBuilder.start();
        }
        return null;
    }

完整测试 Demo 及编译脚本见我的 github

参考链接1
参考链接2

你可能感兴趣的:(Android,音视频,FFmpeg,ffmpeg,android,可执行程序,依赖库,动态库)