macOS上将ffmpeg.c编译成Framework

1 前言

    本文介绍下在macOS上将ffmpeg的fftools目录下的ffmpeg.c程序,也就是ffmpeg的命令行程序,编译成framework的方法。编译成.a或.dylib的方法类似。 

    编译环境如下:

  • xcode15.3;
  • ffmpeg release/6.1;

2 编译ffmpeg

    首先clone我们的FFmpeg代码仓到本地,并更名为ffmpeg,切换分支为release/6.1:

git clone https://github.com/FFmpeg/FFmpeg.git ffmpeg && git checkout release/6.1

    然后在ffmpeg的根目录执行如下命令,由于是学习使用,configure配置的是缺省选项,编译后安装目录在根目录下的mac_build目录下: 

mkdir -p mac_build && ./configure --prefix=./mac_build

     然后执行如下命令,编译并安装ffmpeg:

make -j8 && make install

     configure并编译安装完成之后,会在根目录下生成如下文件:

  • configure配置完毕,会在根目录产生config.hconfig_components.h文件;
  • 生成了ffmpeg/ffplay/ffprobe可执行文件;
  • mac_build目录是ffmpeg的bin/include/lib/share文件;

    其中,mac_build目录结构如下: 

xxxxxx@localhost:~/Applications/workspace/av/ffmpeg/mac_build$tree -L 2
.
├── bin
│   ├── ffmpeg
│   ├── ffplay
│   └── ffprobe
├── include
│   ├── libavcodec
│   ├── libavdevice
│   ├── libavfilter
│   ├── libavformat
│   ├── libavutil
│   ├── libswresample
│   └── libswscale
├── lib
│   ├── libavcodec.a
│   ├── libavdevice.a
│   ├── libavfilter.a
│   ├── libavformat.a
│   ├── libavutil.a
│   ├── libswresample.a
│   ├── libswscale.a
│   └── pkgconfig
└── share├── ffmpeg└── man15 directories, 10 files

    编译安装完成之后,就可以拿该目录下的includelib下的文件引入到工程使用了。 

3 编译ffmpeg.c

3.1 新建xcode工程

    打开xcode新建一个xcode的app工程:

    然后,新建一个target,FFmpegFramework,接着把ffmpeg相关c程序拖进来编译:

    然后在FFmpegFramework => Build Settings => Search Paths里加入ffmpeg的includelib以及config.h的搜索路径:

    到此,xcode工程和FFmpegFramework的创建和初始化工作完成,接下来就是将FFmpegFramework编译成framework了。 

3.2 改写ffmpeg.c的接口方法

  • 在ffmpeg.h文件中,将int main(int argc, char* argv[])方法名改成ffmpeg
  • ffmpeg.c对应文件的main方法名按以上同步修改为ffmpeg

    ffmpeg.h头文件中修改方法名: 

// 将main方法名改为ffmpeg名
int ffmpeg(int argc, char* argv[]);

     ffmpeg.c同步修改方法名:

// 将main方法名改为ffmpeg
int ffmpeg(int argc, char **argv)
{int ret, err_rate_exceeded;BenchmarkTimeStamps ti;init_dynload();setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */av_log_set_flags(AV_LOG_SKIP_REPEATED);parse_loglevel(argc, argv, options);#if CONFIG_AVDEVICEavdevice_register_all();
#endifavformat_network_init();show_banner(argc, argv, options);/* parse options and open all input/output files */ret = ffmpeg_parse_options(argc, argv);if (ret < 0)goto finish;if (nb_output_files <= 0 && nb_input_files == 0) {show_usage();av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);ret = 1;goto finish;}if (nb_output_files <= 0) {av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");ret = 1;goto finish;}current_time = ti = get_benchmark_time_stamps();ret = transcode(&err_rate_exceeded);if (ret >= 0 && do_benchmark) {int64_t utime, stime, rtime;current_time = get_benchmark_time_stamps();utime = current_time.user_usec - ti.user_usec;stime = current_time.sys_usec  - ti.sys_usec;rtime = current_time.real_usec - ti.real_usec;av_log(NULL, AV_LOG_INFO,"bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);}ret = received_nb_signals ? 255 :err_rate_exceeded   ?  69 : ret;finish:if (ret == AVERROR_EXIT)ret = 0;ffmpeg_cleanup(ret);return ret;
}

3.3 将ffmpeg.c编译成Framework

    接下来就是将ffmpeg.c编译成framework了,期间遇到了很多问题,但基本是一类问题,那就是链接时的Undefined symbol

    解决方式就是将ffmpeg.c所依赖的macOS系统framework和基础.a或者.dylib库链接到本framework即可。如下图,总共依赖了39个库,其中SDL2需用dylib库(若使用libSDL2.a则会报错找不到_FFCreateDevice symbol等):

    ffmpeg.c所依赖的.a和.dylib库路径:

mingo@localhost:~/Applications/workspace/av/ffmpeg/mac_build/lib$ll
total 292680
drwxr-xr-x  23 mingo  staff       736  5 10 23:58 ./
drwxr-xr-x   7 mingo  staff       224  5 10 11:38 ../
-rw-r--r--@  1 mingo  staff      6148  5 10 23:51 .DS_Store
-r--r--r--   1 mingo  staff   2514640  5 10 23:33 libSDL2.a
-rw-r--r--@  1 mingo  staff   1561488  5 10 23:58 libSDL2.dylib
-r--r--r--   1 mingo  staff       848  5 10 22:49 libX11-xcb.a
-r--r--r--   1 mingo  staff   1402392  5 10 22:49 libX11.a
-r--r--r--   1 mingo  staff     11656  5 10 23:25 libXau.a
-r--r--r--   1 mingo  staff     20696  5 10 23:27 libXdmcp.a
-rw-r--r--   1 mingo  staff  78648416  5 10 11:35 libavcodec.a
-rw-r--r--   1 mingo  staff    574072  5 10 11:35 libavdevice.a
-rw-r--r--   1 mingo  staff  22947096  5 10 11:35 libavfilter.a
-rw-r--r--   1 mingo  staff  26952064  5 10 11:35 libavformat.a
-rw-r--r--   1 mingo  staff   3054552  5 10 11:35 libavutil.a
-r--r--r--   1 mingo  staff   7380136  5 10 22:27 libcrypto.a
-r--r--r--   1 mingo  staff   1386648  5 10 22:24 libssl.a
-rw-r--r--   1 mingo  staff    411520  5 10 11:35 libswresample.a
-rw-r--r--   1 mingo  staff   2655320  5 10 11:35 libswscale.a
-r--r--r--   1 mingo  staff     11160  5 10 22:47 libxcb-shape.a
-r--r--r--   1 mingo  staff      8864  5 10 22:45 libxcb-shm.a
-r--r--r--   1 mingo  staff     39352  5 10 22:43 libxcb-xfixes.a
-r--r--r--   1 mingo  staff    218768  5 10 21:31 libxcb.a
drwxr-xr-x   9 mingo  staff       288  5 10 11:35 pkgconfig/
mingo@localhost:~/Applications/workspace/av/ffmpeg/mac_build/lib$

    ffmpeg.c所依赖的macOS系统库及ffmpeg相关库39个: 

    按以上操作,便可顺利编译FFmpegFramework了。接下来就可以在learn-ffmpeg项目中使用它了。 

4 使用framework

    贴出main.m调用ffmpeg.c接口的代码:

#include "libavutil/log.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/opt.h"
#include "ffmpeg.h"static void test_ffmpeg(int argc, const char* argv[]) {ffmpeg(argc, argv);
}int main(int argc, const char * argv[]) {@autoreleasepool {// Setup code that might create autoreleased objects goes here.av_log_set_level(AV_LOG_DEBUG);av_log(NULL, AV_LOG_INFO, "hello ffmpeg");// 示例ffmpeg -h命令const char* args[] = { "ffmpeg", "-h" };test_ffmpeg(2, args);}return NSApplicationMain(argc, argv);
}

    然后,选中learn-ffmpeg target,在learn-ffmpeg => Build Settings => Search Paths => Header Search Paths/Library Search Paths中指定ffmpeg及其framework相关的includelib文件:

    include搜索路径:

    lib搜索路径: 

     在learn-ffmpeg target中 Build Settings => Link Binary with Library中加入FFmpegFramework: 

     接下来就可以顺利编译learn-ffmpeg程序,并开始调试ffmpeg.c程序了:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/690406.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stl学习以及abc比赛例题

1.引例 一提到查找&#xff0c;我们一上来想的肯定是find()函数或者search()函数&#xff0c;但是这种查找的底层逻辑终究是用顺序查找的方式&#xff0c;运行的时间成本非常高昂&#xff0c;所以平时能不用就不用&#xff0c;比赛的时候用这种查找和自己while遍历&#xff0c…

Maven 的仓库、周期和插件

优质博文&#xff1a;IT-BLOG-CN 一、Maven 仓库 在Maven的世界中&#xff0c;任何一个依赖、插件或者项目构建的输出&#xff0c;都可以称为构建。Maven在某个统一的位置存储所有项目的共享的构建&#xff0c;这个统一的位置&#xff0c;我们就称之为仓库。任何的构建都有唯一…

基于Java+SpringBoot+Mybaties-plus+Vue+elememt 驾校管理 设计与实现

一.项目介绍 系统角色&#xff1a;管理员、驾校教练、学员 管理员&#xff1a; 个人中心&#xff1a;修改密码以及个人信息修改 学员管理&#xff1a;维护学员信息&#xff0c;维护学员成绩信息 驾校教练管理&#xff1a;驾校教练信息的维护 驾校车辆管理&…

从0开发、发布油猴脚本(保姆级)

概览 项目中使用conify集成图标&#xff0c;有些内网用户只能使用离线图标&#xff0c;但是如何判断使用的conify集成图标是在线还是离线呢&#xff1f;这个时候就需要一个油猴脚本&#xff0c;作用于iconify官网&#xff0c;对离线图标进行标识。 此篇文章主要从如下几点去梳…

ITMS-91053: Missing API declaration

1. 添加PrivacyInfo.xcprivacy File → New → File → App Privacy 2. 格式 3. 已知对应关系 NSPrivacyAccessedAPICategoryFileTimestamp 3B52.1: Files provided to app by user, per documentation&#xff1a;File Timestamp NSPrivacyAccessedAPICategoryDiskSpace …

企业设置,支持自定义短信签名

05/08 主要更新模块概览 自动换行 启动封面 使用统计 短信签名 01表单管理 1.1 【表单外链】- 查询外链支持多个外链 说明&#xff1a; 表单查询外链原仅支持一个&#xff0c;现支持增加多个外链功能&…

从loss角度理解LLM涌现能力

如今的很多研究都表明小模型也能出现涌现能力&#xff0c;本文的作者团队通过大量实验发现模型的涌现能力与模型大小、训练计算量无关&#xff0c;只与预训练loss相关。 作者团队惊奇地发现&#xff0c;不管任何下游任务&#xff0c;不管模型大小&#xff0c;模型出现涌现能力…

D - Another Sigma Problem(ABC)

思路&#xff1a;我们可以处理一个后缀来记录当前数a[i]需要乘上多少&#xff08;类似于1110这样的&#xff09;&#xff0c;然后对于当前位来说&#xff0c;对答案的贡献还要加上(i - 1) * a[i]&#xff0c;因为a[i]还要做前(i - 1)个数的后缀。 代码&#xff1a; #include &…

IDEA安装使用Git

IDEA安装使用Git 1 Git下载与安装 2 在IDEA中使用Git 2.1 IDEA中配置Git 在IDEA中使用Git&#xff0c;本质上还是使用本地安装的Git软件&#xff0c;所以需要在IDEA中配置Git。 2.2 在IDEA中使用Git 2.2.1 获取Git仓库 在IDEA中使用Git获取仓库有两种方式: 本地初始化仓库从…

信息检索(36):ConTextual Masked Auto-Encoder for Dense Passage Retrieval

ConTextual Masked Auto-Encoder for Dense Passage Retrieval 标题摘要1 引言2 相关工作3 方法3.1 初步&#xff1a;屏蔽自动编码3.2 CoT-MAE&#xff1a;上下文屏蔽自动编码器3.3 密集通道检索的微调 4 实验4.1 预训练4.2 微调4.3 主要结果 5 分析5.1 与蒸馏检索器的比较5.2 …

Excel 分组汇总后删除明细

有 Excel 数据如下所示&#xff1a; IDCriteria1Criteria2Criteria3Criteria4101210271239312381236123171826182918239182120182147 需要按 ID 分组汇总其余列&#xff0c;结果如下&#xff1a; IDCriteria1Criteria2Criteria3Criteria410121027123932561826939267 解法及简…

[Kubernetes] Istio on Kubernetes 实践

文章目录 1.Kubernetes 创建2.Istio 部署2.1 下载 Istio2.2 安装 Istio 3.Istio on Kubernetes 实践3.1 部署 Bookinfo 示例应用3.2 确定入站 IP 和端口 1.Kubernetes 创建 主机名内部ip外部ipmaster192.168.66.2139.198.36.40node1192.168.66.3139.198.1.192node2192.168.66.…