多媒体开发(7):编译Android与iOS平台的FFmpeg
编译FFmpeg,一个古老的话题,但小程还是介绍一遍,就当记录。之前介绍怎么给视频添加水印时,就已经提到FFmpeg的编译,并且在编译时指定了滤镜的功能。
但是,在手机盛行的时代,读者可能更需要的是能在iOS或Android平台上运行的FFmpeg,而对于命令行的ffmpeg,读者可以在个人电脑上面使用(因为它简洁易操作),也可以在服务程序中使用(安装FFmpeg后直接调用ffmpeg命令),比如小程经常在自己的mac机上使用ffmpeg命令。
本文介绍如何编译出iOS或Android平台使用的FFmpeg链接库。
正如编译macos平台使用的FFmpeg一样,编译iOS或Android平台使用的FFmpeg,主线也是先configure再make,只不过,有更多的细节需要考虑。
小程使用的是macos系统。
(1)编译环境准备
pkg-config
FFmpeg在编译时经常使用到第三方库(比如x264、rtmp等),编译器在查找这些第三方库的头文件与库文件时,需要使用到程序pkg-config。
pkg-conifig给编译器提供路径与链接选项。第三方库在make install时会生成pc后缀的文件并拷贝到系统目录,而pkg-config就是从这个pc文件读取出路径信息。
这样安装pkg-config:
brew install pkg-config
安装pkg-config后,可以这样得到第三方库的路径信息:
pkg-config --cflags --libs librtmp
以下是对于pkg-config命令的一个载图:
可以设置PKG_CONFIG_PATH这个环境变量,让pkg-config到这个目录下面去找pc文件,如果不设置,则默认在/usr/local/lib/pkgconfig目录下面查找。
需要注意,虽然pkg-config查找到的pc文件里面有记录到第三方静态库的路径,但实际在编译FFmpeg静态库时,并不会链接上这个第三方库,而且在FFmpeg的编译脚本中可以指定第三方库的路径。
freetype
此项只在使用滤镜功能时需要安装。
如果编译时遇到这样的提示:freetype2 not found using pkg-config,那说明还没有安装freetype,这样安装即可:
brew install freetype
clang编译器
此项只在编译iOS平台的FFmpeg时才需要。
小程的mac机已经安装过xcode,所以clang已经存在。如果读者还没有安装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.google.cn/ndk/downloads/index.html
(2)FFmpeg源码下载
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
(3)编译脚本
不必自己重写了,找开源的项目过来修改一下(注意开源协议)就可以了,比如参考这个开源项目:
https://github.com/yixia/FFmpeg-Vitamio.git
在这个项目里面,有编译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文件)。
至此,已经介绍完在iOS或Android平台编译FFmpeg的过程。
在编译得到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的链接库的过程,涉及到编译环境的准备、编译脚本的理解与定制等内容。
多媒体开发(7):编译Android与iOS平台的FFmpeg的更多相关文章
- JSBridge(Android和IOS平台)的设计和实现
前言 对于商务类的app,随着app注册使用人数递增,app的运营者们就会逐渐考虑在应用中开展一些推广活动.大多数活动具备时效性强.运营时间短的特征,一般产品们和运营者们都是通过wap页面快速投放到产 ...
- 学习笔记:APP切图那点事儿–详细介绍android和ios平台
学习笔记:APP切图那点事儿–详细介绍android和ios平台 转载自:http://www.woofeng.cn/articles/168.html 版权归原作者所有 作者:亚茹有李 原文地址 ...
- 在iOS平台使用ffmpeg解码h264视频流(转)
在iOS平台使用ffmpeg解码h264视频流,有需要的朋友可以参考下. 对于视频文件和rtsp之类的主流视频传输协议,ffmpeg提供avformat_open_input接口,直接将文件路径或UR ...
- 在iOS平台使用ffmpeg解码h264视频流
来源:http://www.aichengxu.com/view/37145 在iOS平台使用ffmpeg解码h264视频流,有需要的朋友可以参考下. 对于视频文件和rtsp之类的主流视频传输协议,f ...
- Mac下配置cocos2d-x开发环境(android和ios)
一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...
- 经典好文:android和iOS平台的崩溃捕获和收集
通过崩溃捕获和收集,可以收集到已发布应用(游戏)的异常,以便开发人员发现和修改bug,对于提高软件质量有着极大的帮助.本文介绍了iOS和android平台下崩溃捕获和收集的原理及步骤,不过如果是个人开 ...
- cocos2d-x系列 Mac下配置cocos2d-x开发环境(android和ios)
一.下载cocos2d-x http://cocos2d-x.org/projects/cocos2d-x/wiki/Download cocos2d-x-2.1.4.zip @ June.18, 2 ...
- 【Android 系统开发】 编译 Android文件系统 u-boot 内核 并烧写到 OK-6410A 开发板上
博客地址 : http://blog.csdn.net/shulianghan/article/details/40299813 本篇文章中用到的工具源码下载 : -- ok-6410A 附带的 A ...
- 嵌入式-迅为iTOP-4418/6818开发板编译Android镜像技术分享
迅为是基于Ubuntu12.04.2 平台做开发,所有的配置和编译脚本也是基于此平台.如果你对Linux 和Android 开发很熟悉,相信你会根据错误提示逐步找到原因并解决,错误提示一般是选用的平台 ...
随机推荐
- Confluence 6 复杂授权或性能问题
提交一个 服务器请求(support request) 然后在你的服务请求中同时提供下面的信息. Confluence 服务器 登录 Confluence 然后访问管理员控制台. 将 系统信息(Sys ...
- python之vscode配置开发调试环境
在vscode中下载python插件,下载量最多的就是 打开launch.json,把以下代码粘贴进去即可 { // 使用 IntelliSense 了解相关属性. // 悬停以查看现有属性的描述. ...
- spark submit参数及调优
park submit参数介绍 你可以通过spark-submit --help或者spark-shell --help来查看这些参数. 使用格式: ./bin/spark-submit \ ...
- nginx常用命令及简单配置
nginx常用命令 nginx -c /usr/local/nginx/conf/nginx.conf 启动nginx(windows下start nginx); nginx -s quit 停止ng ...
- SpringIOC框架详解
1.SpringIOC是什么? 就是一个用来管理实体类bean的容器 2.创建cppdy.xml文件(模拟springmvc.xml文件) <?xml version="1.0&quo ...
- day 08字符编码 文件处理
字符编码1.软件启动流程(打开notepad++文档)从硬盘将软件加载到内存上加载test.txt到内存中执行notepad++的代码,将test.txt打到屏幕上 python解释器也是一个应用软件 ...
- day05流程控制while循环 流程控制for循环
1.什么是循环:循环就是重复做某事 2.为何要有循环:为了计算机能够具备人重复做某事的能力 3,.如何用循环: 1.结束while循环的两种方法:1.修改条件:等到下一次循环开始时判断,条件为假才会结 ...
- LeetCode(84): 柱状图中最大的矩形
Hard! 题目描述: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度.每个柱子彼此相邻,且宽度为 1 . 求在该柱状图中,能够勾勒出来的矩形的最大面积. 以上是柱状图的示例,其中每个柱子的宽度 ...
- PDF文件编辑技巧之PDF书签怎么设置
纸质的文件想要添加书签就直接拿笔书写就可以,Word文件怎么添加书签相信大家也都知道,那么PDF文件的书签要怎么设置的呢,是不是有很多小伙伴不知道该怎么做呢,不要担心,今天小编就来跟大家分享一下在PD ...
- 使用react 在页面上引用静态图片,图片不显示
const url='../assets/logo.png'; <img src={url} alt=''/> 1.使用require <img src={require('../a ...