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

in 在路上 | No Comments »

本文主要内容:讲述遇到集成 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 在路上 | No Comments »

本文主要内容:介绍一些在 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视音频编解码零基础学习方法

真正的 Android 冷启动长时间白屏原因与解决方案

in 垃圾文章 | No Comments »

注:本文属于 垃圾文章补完计划

近期在 Android 开发过程中发现 App 每次启动时白屏事件特别长(大概 3s),检查了首屏 Activity 与 Application 都没发现问题,并且新建了一个空的项目问题依旧,遂谷歌之,发现一大把的文章都是介绍如何把主题的白色背景色改为透明来达到显得没有白屏。

实际产生原因是新版 Android Studio 自带的 Instant Run 功能。大概解释就是 Instant Run 为了能快速运行做了一系列操作,这部分时间就体现到了启动白屏的时间上了。

那么是否我们应该关闭 Instant Run 呢?我并不推荐,诚然在 Android Studio2.0 时代这个功能一堆 bug,连页面都没法正常渲染好,那时候毫无疑问关闭了这个功能,不过现在 Instant Run 已经改进了很多了,甚至在 Android Studio3.0 发布的时候还呼吁大家重新试试,现在的体验确实不错,缩短了很多编译时间。

那么怎么解决这个白屏时间过长的问题呢?把 apk 打包成 release 版即可。

详细介绍可以阅读郭霖大神的Android 冷启动白屏解析,带你一步步分析和解决问题。我之所以又写一篇与郭霖大神内容几乎相同的短文,是希望将来其他人遇到该问题时能得到正确的原因,而不是那漫山遍野的修改 style 方案。

记我在傻逼华为手机上遇到的坑

in 在路上 | 1 Comment »

本文内容:介绍我用傻逼华为手机调试时遇到的种种奇葩蛋疼问题
我在前司的时候,兼容性问题遇到最多的就是华为了,不过当时并没把问题记录下来,这次又换了一台华为测试机,受不了这些破问题了,怒记下来供后人参考。

华为手机不显示 log

拨号页面输入*#*#2846579#*#*,选择「1.后台设置」,「3.LOG设置」,打开「AP日志」选项。即可。
注意1:如果勾选了还没显示,你可能需要重启手机。
注意2:也许重启多了该选项又会关闭需再次打开。

华为手机后台调试的密码是什么

如果你误以为那个「后台调试」才是显示 log 的话,恭喜你你被误导了。而这个破密码我搜了半天都没搜到!你们论坛是摆着好看的么!?那么多用户问结果没一个官方人员解决问题。

华为手机在页面有 EditText 时会闪退,报错java.lang.ref.SoftReference cannot be cast to android.view.inputmethod.InputConnection

解决办法是进入运行配置页面(运行按钮左边,点击那个 app,选「Edit Configurtions…」),选择「Profiling」选项卡,关闭「Enable advanced profiling(required for API level < 26 only)」选项。
这个功能是具体分析 App 性能的,很实用,有的人会以为这是 Android6.0 的问题,然而我自用的小米同样是6.0,并不存在这种问题。

Vivo 手机解析安装包错误

关闭「Instant Run」,MD 这些破手机怎么这么多蛋疼的问题。

JoJo,这是我最后的波纹了,收下它吧!——Android 波纹效果使用

in 垃圾文章 | No Comments »

本文主要内容:介绍 Android 波纹效果与兼容方式
注:本文属于 垃圾文章补完计划

在 Android App 中,触摸反馈是非常重要的,能让用户有点下去的感觉。

最简单的实现方式莫过于用户按下的时候改变背景色,例如:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <color android:color="@color/white_hover" />
    </item>
    <item>
        <color android:color="@color/white" />
    </item>
</selector>

然后直接android:background="@drawable/white_bg" 即可。

在 Android5.0后,Android 是支持了波纹效果的,视觉体验比单纯改变背景色好,使用起来也很简单,android:background="?attr/selectableItemBackground" 即可。但是问题在于它是没背景色的,难道还得再加一层 FrameLayout 不成?并不需要,直接加一个 drawable 即可:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid android:color="@color/white"/>
            <corners android:radius="0dp"/>
        </shape>
    </item>
    <item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

这样便是一个白底的波纹背景了,需要的话也可设置圆角之类的。

但是,该方式在 Android6.0 上会有渲染 bug,加载的第一个用该背景的控件波纹是不会生效的。因此查了下 API,发现提供了更科学的波纹方式,在 drawable-21 中添加:

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/white_hover"
    >
    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white"/>
    <item android:drawable="@color/white"/>
</ripple>

这样兼容性就彻底没问题了。

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