关于编译:多媒体开发7编译Android与iOS平台的FFmpeg

22次阅读

共计 4022 个字符,预计需要花费 11 分钟才能阅读完成。

编译 FFmpeg,一个古老的话题,但我还是介绍一遍,就当记录。之前介绍怎么给视频增加水印时,就曾经提到 FFmpeg 的编译,并且在编译时指定了滤镜的性能。

然而,在手机流行的时代,你可能更须要的是能在 iOS 或 Android 平台上运行的 FFmpeg,而对于命令行的 ffmpeg,你能够在个人电脑下面应用(因为它简洁易操作),也能够在服务程序中应用(装置 FFmpeg 后间接调用 ffmpeg 命令),比方小程常常在本人的 mac 机上应用 ffmpeg 命令。

本文介绍怎么编译出 iOS 或 Android 平台应用的 FFmpeg 链接库。

正如编译 macos 平台应用的 FFmpeg 一样,编译 iOS 或 Android 平台应用的 FFmpeg,主线也是先 configure 再 make,只不过,有更多的细节须要思考。

我应用的是 macos 零碎,以下介绍的就是在 mac 上穿插编译,编译出挪动平台应用的 FFmpeg。

(1)编译环境筹备

pkg-config

FFmpeg 在编译时常常应用到第三方库(比方 x264、rtmp 等),编译器在查找这些第三方库的头文件与库文件时,须要应用到程序 pkg-config。

pkg-conifig 给编译器提供门路与链接选项。第三方库在 make install 时会生成 pc 后缀的文件并拷贝到系统目录,而 pkg-config 就是从这个 pc 文件读取出门路信息。

能够设置 PKG_CONFIG_PATH 这个环境变量,指定目录,让 pkg-config 到这个目录上面去找 pc 文件,如果不设置,则默认在 /usr/local/lib/pkgconfig 目录上面查找,比方某个时刻我的 pkgconfig 目录上面是这样的一堆 pc 文件:

这样装置 pkg-config:

brew install pkg-config

装置 pkg-config 后,能够这样获取第三方库的门路信息:

pkg-config –cflags –libs freetype2

以下是对于 pkg-config 命令的一个载图:

须要留神,尽管 pkg-config 查找到的 pc 文件外面有记录到第三方动态库的门路,但理论在编译 FFmpeg 动态库时,并不会链接上这个第三方库,而且在 FFmpeg 的编译脚本中能够指定第三方库的门路。

freetype

此项只在应用滤镜性能时须要装置。

如果编译时遇到这样的提醒:freetype2 not found using pkg-config,那阐明还没有装置 freetype,这样装置即可:

brew install freetype

clang 编译器

此项只在编译 iOS 平台的 FFmpeg 时才须要。

因为我的 mac 机曾经装置过 xcode,所以 clang 曾经存在。如果你的 mac 还没有装置 clang 的话,那倡议把 xcode 装置好。

asm 编译器

此项只在编译 iOS 平台的 FFmpeg 时才须要。

x264 或 FFmpeg 等,都有汇编代码,编译这些汇编代码,须要应用更先进的编译脚本来解决,而 mac 零碎没有这样的脚本。

这个脚本是gas-preprocessor.pl

能够这样下载并应用 gas-preprocessor.pl:

git clone git://github.com/mansr/gas-preprocessor.git
sudo cp -f gas-preprocessor/gas-preprocessor.pl /usr/local/bin/
chmod +x /usr/local/bin/gas-preprocessor.pl

yasm

另一个须要的工具是 yasm 汇编编译器,能够这样装置:

brew install yasm

NDK 工具包

此项只在编译 Android 平台的 FFmpeg 时才须要。

能够应用 ndk-r9d 版本,或者最新的版本,来编译 FFmpeg,下载地址:https://developer.android.goo…

(2)FFmpeg 源码下载

git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg

(3)编译脚本

不用本人重写了,找开源的我的项目过去批改一下(留神开源协定)就能够了,比方参考这个开源我的项目:https://github.com/yixia/FFmp…

在这个我的项目外面,有编译 Android 跟 iOS 平台的相应脚本,而且有相应的优化解决。在挪动平台应用的库都很重视两个货色,一个是性能,另一个是体积大小。一个好的脚本,既要依据不同的硬件类型作编译上的优化,也要依据软件需要裁剪 FFmpeg 的性能使得进去的库尽可能小(毕竟 FFmpeg 的性能并非全副都用上)。

(4)脚本批改

小程先介绍一下脚本外面的一些要害参数,这些参数并非平台通用。

指定指令集:

–extra-cflags=’-arch armv7s’ –extra-ldflags=’-arch armv7s’

指定 cpu 类型:

–arch=arm –cpu=cortex-a9

留神,应该依据不同的指令集应用不同的 cpu 优化;–arch=arm64,像这样指定具体指令架构也是能够的。

指定零碎:

–target-os=darwin

指定 sdk:

–sysroot=/Applications/Xcode.app/…/xxx.sdk

指定编译器:

–cc=xxx/clang

指定库生成目录:

–prefix=build

指定应用的 muxer/demuxer/encoder/decoder 等:

–enable-muxer=mp4

基本上应用下面介绍的脚本就能够编译了,但有时候也能够作一些批改,比方要退出第三方库时,或者要对某个指令集作优化时,等等。

小程再提一些留神点,有可能帮你解决编译过程中遇到的问题:

--sysroot 须要指定。iOS 平台为....sdk/,不包含 usr/inclue;Android 平台是编译链的目录。extra-cflags 跟 extra-ldflags 要指定 -arch(iOS)或 -march(Android)。在 xcode8.3.2(sdk 为 10.3)上,armv7/armv7s/arm64 不能应用 "-mfloat-abi=hard" 选项,并且 arm64 要指定 -mcpu=cortex-a53。在 xcode9.2(sdk 为 11.2)上,须要 --disable-asm。

对于理论我的项目来说,FFmpeg 的编译是要害的一步,应该多花工夫去钻研一些要害的细节 – 性能、性能跟体积大小都很重要。

(5)开始编译与应用

运行脚本即可。最终会生成二进制库,比方 iOS 个别为动态库(.a 文件),而 Android 个别为动静库(.so 文件)。

在编译失去 FFmpeg 的链接库后,就能够调用它,让它运行起来。这时,须要写本人的调用程序。在这里给出一个简略的调用示例,并且不做代码解释,只是让有须要的读者有一个感知。

extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
}

void dump_file_format(const char* filepath) {av_register_all();
    av_log_set_level(AV_LOG_DEBUG);
    AVFormatContext* formatContext = avformat_alloc_context();
    AVCodecContext* codecContext = NULL;
    int status = 0;
    bool success = false;
    int audioindex = -1;
    status = avformat_open_input(&formatContext, filepath, NULL, NULL);
    if (status == 0) {status = avformat_find_stream_info(formatContext, NULL);
        if (status >= 0) {for (int i = 0; i < formatContext->nb_streams; i ++) {if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
                    audioindex = i;
                    break;
                }    
            }
            if (audioindex > -1) {codecContext = formatContext->streams[audioindex]->codec;
                AVCodec* codec = avcodec_find_decoder(codecContext->codec_id);
                if (codec) {status = avcodec_open2(codecContext, codec, NULL);
                    if (status == 0) {success = true;}
                }
            }
        }
    }
    if (success) {av_dump_format(formatContext, 0, filepath, false);
        av_log(NULL, AV_LOG_DEBUG, "format and decoder sucessful, and now in decoding each frame\n");
        printf("sample_rate=%d, channels=%d\n", codecContext->sample_rate, codecContext->channels);
    }
    avformat_free_context(formatContext);
}

int main(int argc, const char *argv[])
{const char filepath[] = "test2.mp3";    
    dump_file_format(filepath);
    return 0;
}

好了,总结一下,本文介绍了在 macos 上,编译出 iOS 平台或 Android 平台的 FFmpeg 的链接库的过程,波及到编译环境的筹备、编译脚本的了解与定制等内容。有缘再见,see you.


正文完
 0