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

20 篇文章 1 订阅
7 篇文章 3 订阅

项目中有两种情况用到 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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用 ffmpeg 进行编译时,如果需要编译动态并且动态依赖静态,可以通过以下步骤完成: 1. 下载 ffmpeg 源码,并解压缩到一个目录中。 2. 进入解压缩后的目录,执行以下命令: ``` ./configure --enable-shared --disable-static ``` 这个命令将会编译动态,并禁用静态。 3. 执行 `make` 命令进行编译。 4. 编译完成后,可以在 `./lib` 目录下看到编译好的动态文件,例如 `libavcodec.so`、`libavformat.so` 等。 5. 如果需要在编译其他程序时链接这些动态,需要添加 `-L` 和 `-l` 选项,例如: ``` gcc main.c -L./lib -lavcodec -lavformat -lavutil -o myapp ``` 这个命令将会链接 `libavcodec.so`、`libavformat.so` 和 `libavutil.so` 三个动态,并生成可执行文件 `myapp`。 6. 如果这些动态依赖静态,需要在链接时添加 `-Wl,-Bstatic` 和 `-Wl,-Bdynamic` 选项,例如: ``` gcc main.c -L./lib -Wl,-Bstatic -lavcodec_static -lavformat_static -lavutil_static -Wl,-Bdynamic -o myapp ``` 这个命令将会链接 `libavcodec.a`、`libavformat.a` 和 `libavutil.a` 三个静态作为动态依赖,并生成可执行文件 `myapp`。 注意:在链接动态时,如果依赖的静态不存在,或者版本不兼容,可能会导致链接失败。因此,建议在编译时尽量使用同一版本的静态动态。同时,如果静态动态都存在,建议优先使用动态,以减小可执行文件的体积。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值