Posts Tagged ‘FFmpeg’

Android 编译 FFmpeg 产生「error undefined reference to ‘av_register_all()」等错误的多种原因

in 在路上

本文主要内容:讲述遇到集成 NDK 时遇到的「error: undefined reference to」的解决方案

集成 NDK 有很多方式,比如 ndk-build 后把 so 库直接链接使用,或者通过 CMake 的方式链接,通常推荐后者,因为这样编写调用 native 方法方便,不需要像前者每次需要重新打包。
在实现 FFmpeg 播放视频功能时,我参考 Android Studio FFmpeg视频解码播放 该文章操作后,始终无法成功编译,按照网上的种种解决方案(比如用 C 的方式引入头文件)都无法解决,最后一步一步跟能成功运行的项目对照后终于解决。

具体报错情况为一堆 FFmpeg 相关的方法提示 「error: undefined reference to XXXX」。网上的解决方案基本都为用「extern “C”{}」包裹,原因是 FFmpeg 是一共纯 C 的项目,C++ 想正确调用 C 代码则需使用这样的方式,具体示例如下:

extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#include "libavutil/opt.h"
#include "libavutil/imgutils.h"
}

该方案能解决一部分人问题,于我却无用,随后我检查了各种引入方式,以及 NDK 的语法后,确定问题其实是出在 CMakelists.txt 文件上。
(更多…)

Windows 交叉编译 Android 版 FFmpeg 心得

in 在路上

本文主要内容:介绍一些在 win10 系统下打包出 Android 需要的 FFmpeg so 库的注意事项。

最近需要写一个短视频 Android 项目,经与领导讨论后决定不用市面上的短视频 SDK,采用 FFmpeg 实现。如何集成我选定了一篇质量不错叙述详细的教程 Android 集成 FFmpeg (一) 基础知识及简单调用 ,本以为照着来可以很轻松集成好的,没想到居然花了两天时间。现把注意事项分享给大家,供后人查阅。

假如你也有交叉编译 FFmpeg 的需求,推荐你参考上面那篇文章,遇到问题了再看看我这是否有解决方案。教程作者(后面将用该词称呼上面文章的作者)与大部分交叉编译 FFmpeg 教程的作者使用的都是 Mac,能省很多事,这让我煞是羡慕。然而我并没 Linux 环境,因此我使用了 win10 的 Linux 子系统,选择了 Ubuntu。大致步骤为「设置里开启开发者选项」→「程序和功能里启用 适用于 Linux 的 Windows 子系统」→「应用市场里安装 Ubuntu」,这个步骤很简单,网上有很多指导,我就不详细描述了。然后在命令行输入「bash」即可进入 Ubuntu,在这里 C 盘映射到了「mnt/c」目录下(其他盘类推),因此我将所有相关资料都放到了 D 盘的「Share」文件夹下,方便使用。

sh 脚本报错各种 not found

我对 sh 脚本不熟悉,因此此处尝试过其他人的编译脚本才发现问题所在,教程作者的注释影响了脚本的正常运行,你需要将所有「\」后的空格与注释都删掉才可正常运行。
同时,还有一个可能导致这个错误,就是你使用了 Windows 的换行符,假如你用的是 vscode,直接右下角将「CRLF」改成「LF」即可,其他编辑器解决方案可自行搜索。

ERROR: libmp3lame >= 3.98.3 not found

请先确保你下载了教程作者编译好的 libmp3lame,并在 sh 脚本里修改了对应路径。如果你跟我一样不方便下载 CSDN 积分内容的话,我把它传到了我的百度网盘 链接(密码:5jm6)的 lame 文件夹。
同时,你很有可能跟我一样下载且更改路径之后依然存在这个问题,当你搜索该问题时可能很多人会建议你安装 libmp3lame,Ubuntu 的话命令是「apt-get install libmp3lame-dev」,假如找不到请「apt-get update」一下。虽然我对该操作是否有效持怀疑态度(我们需要的是交叉编译出 Android 端的 FFmpeg,而不是在你的 Ubuntu 上使用 FFmpeg),但是似乎是因此解决了该问题。

make -j4 的时候各种提示 「fatal error: stdlib.h: No such file or directory」等头文件缺失

这是个很蛋疼的问题,在此时(2018年6月),我使用的都是最新版(ndk 17,FFmpeg 4.0),居然会有兼容问题而且似乎还是由来已久的,相关介绍:Unified Headers,我尝试使用它说的「-D__ANDROID_API__=$API」并没有成功(很可能是我姿势不对),最后把 NDK 版本换成了 15 解决(注意你应该下载 Linux 版的 NDK)。

如果你成功解决这些问题,你应该成功生成了动态库,如果你遇到了暂时没法解决的问题想绕过,那么同样可以直接下载我编译好的版本:百度网盘 链接(密码:5jm6)的 arm 文件夹。剩下的内容就不需要 Linux 相关了,只需要你使用 ndk 即可。(注意此时你应该使用 Windows 的 ndk)

ndk-build 时报错 「make: *** No rule to make target jni_FFmpegJni.c', needed byobj/local/armeabi-v7a/objs/ffmpeg/com_jni_FFmpegJni.o’. Stop.」

不用怀疑了,不是网上说的那些什么缓存问题,就是你的 Android.mk 写错了,仔细检查。注意教程作者贴的 Android.mk 里的 「libpostproc」我们是没有的,以及对应的版本也都更新了,其实你可以在 Android.mk 里写「libavcodec-*.so」来忽略版本问题,或者链接到目录底下的快捷方式。

然后是一个比较严重的问题,按照教程作者的第二篇文章修改 ffmpeg.c 等相关内容后,ndk-build 始终无法成功。此处我尝试过很多方法都没有解决,最后采用了其他人的实现方式,而且我觉得 CMake 的方案其实优于教程作者介绍的这种,该部分可以参考在Mac下编译 FFmpeg ,并在Android中使用

以及后续 FFmpeg 相关学习推荐参考雷神的FFMPEG视音频编解码零基础学习方法

© 2018 一隅 - Powered by Wordpress / Theme: Tabinikki