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.xdnf.cn/news/1420188.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

第二届“盘古石杯”全国电子数据取证大赛wp

服务器取证 先对网站进行重构 [rootstudy ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 643626ab3d8b mattermost/mattermost-pre…

使用VSCode刷LeetCode

使用VS Code刷LeetCode 一、前言 1.1、说明 本文章用来记录使用VS Code刷LeetCode中遇到的一系列问题。 1.2、原因 leetcode 网站中的在线编程环境代码提示、快捷键不友好 VS Code中可以通过插件同步Leetcode所有题目&#xff0c;并且在VS Code中进行查看、测试、提交。 …

超详细的胎教级Stable Diffusion使用教程(四)

这套课程分为五节课&#xff0c;会系统性的介绍sd的全部功能和实操案例&#xff0c;让你打下坚实牢靠的基础 一、为什么要学Stable Diffusion&#xff0c;它究竟有多强大&#xff1f; 二、三分钟教你装好Stable Diffusion 三、小白快速上手Stable Diffusion 四、Stable dif…

递归,搜索,和回溯算法

目录 一、什么是递归&#xff1a; 二、为什么要用到递归 三、如何看待递归这个过程 四、如何写好一个递归 大家也看到了&#xff0c;我们这个算法篇章的开头就比较长&#xff0c;这主要是因为他们三者关系紧密。 一、什么是递归&#xff1a; 我们在学习C语言和数据结构二…

【JAVA进阶篇教学】第十三篇:Java中volatile关键字讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十三篇&#xff1a;volatile关键字讲解。 在 Java 中&#xff0c;volatile关键字是一种轻量级的同步机制&#xff0c;用于确保变量的可见性和禁止指令重排序。本文将详细解释volatile关键字的工作原理、可见性保证以及…

线下研讨会 技术沙龙|乐鑫芯片与 ESP RainMaker® 为科技初创企业赋能

众多科技初创企业在智能硬件市场迅猛发展的背景下&#xff0c;对不断变化的需求展现出了高度的敏锐性&#xff0c;期望能够快速将其转化为切实的产品方案。然而&#xff0c;面对复杂繁重的软硬件集成任务&#xff0c;这些企业往往容易陷入研发瓶颈、资金短缺以及效率低下等多重…

SQLite性能测试(插入)

最近一直在思考一个问题&#xff0c;SQLite 做到这么轻量级&#xff0c;那它注定不会像 MySql 一样强性能&#xff0c;那么它的性能怎么样呢&#xff1f;并发量多高呢&#xff1f; 官方解释&#xff1a; About SQLite 最大数据库大小&#xff1a;281TB 最大行大小&#xff1…

在Qt工具栏上实现矩阵并排的按钮效果源码

如果这个要用MFC去实现头皮都得掉一层&#xff0c;建议大家以后要写GUI方面的小工具尽量转QT或其他吧&#xff0c;MFC真不适合搞这种花里胡哨的界面. 在Qt工具栏上实现矩阵并排的按钮效果源码如下&#xff1a; #include "mainwindow.h" #include "ui_mainwind…

conan2 基础入门(06)-conanfile.py入门

conan2 基础入门(06)-conanfile.py入门 文章目录 conan2 基础入门(06)-conanfile.py入门⭐准备预备文件和Code ⭐使用流程指令 ⭐具体讲解conanfile.pyconan install END视频教学 ⭐准备 注意&#xff0c;如果想跟好的学习conanfile.py建议使用python来安装conan。 当然使用其…

【Ubuntu20.04安装java-8-openjdk】

1 下载 官网下载链接&#xff1a; https://www.oracle.com/java/technologies/downloads/#java8 下载 最后一行 jdk-8u411-linux-x64.tar.gz&#xff0c;并解压&#xff1a; tar -zxvf jdk-8u411-linux-x64.tar.gz2 环境配置 1、打开~/.bashrc文件 sudo gedit ~/.bashrc2、…

LeetCode 题目 119:杨辉三角 II

题目描述 给定一个非负索引 rowIndex&#xff0c;返回杨辉三角的第 rowIndex 行。在这里&#xff0c;rowIndex 从 0 开始。 此题与生成杨辉三角的完整图形略有不同&#xff0c;要求的是能够直接计算出杨辉三角的某一特定行。因此&#xff0c;优化算法的空间复杂度是关键。 方…

Unity开发中导弹路径散射的原理与实现

Unity开发中导弹路径散射的原理与实现 前言逻辑原理代码实现导弹自身脚本外部控制脚本 应用效果结语 前言 前面我们学习了导弹的追踪的效果&#xff0c;但是在动画或游戏中&#xff0c;我们经常可以看到导弹发射后的弹道是不规则的&#xff0c;扭扭曲曲的飞行&#xff0c;然后击…

Linux服务器常用巡检命令,查看日志

查看日志 3.1 通过journalctl命令查看系统日志 命令&#xff1a;journalctl 3.2 通过tail查看系统日志 查看日志文件多少行代码&#xff1a;tail -n [行数] [日志文件] 4. 服务状态 4.1 查看指定服务的状态 命令&#xff1a;systemctl status <service> 比如查看防火墙…

软考-软件工程

软件工程概述 软件工程指的是应用计算机科学、数学及管理科学等原理&#xff0c;以工程化的原则和方法来解决软件 问题的工程&#xff0c;目的是提高软件生产率、提高软件质量、降低软件成本。 概述&#xff1a; 软件开发模型&#xff1a;指导软件开发的体系 需求分析确定软件…

##15 探索高级数据增强技术以提高模型泛化能力

文章目录 前言数据增强的重要性常见的数据增强技术高级数据增强技术在PyTorch中实现数据增强结论 前言 在深度学习领域&#xff0c;数据增强是一种有效的技术&#xff0c;它可以通过在原始数据上应用一系列变换来生成新的训练样本&#xff0c;从而增加数据的多样性&#xff0c…

Remix Client/Server 架构

Remix 框架是服务端渲染架构&#xff0c;当路由请求时生成 HTML 并返回浏览器。这种 SSR 是如何实现的呢&#xff1f;如果不使用 Remix 这种框架&#xff0c;可以在服务器段启动一个无头浏览器进行页面渲染并返回&#xff0c;代价就是要在服务器上启动一个 Chrome 服务&#xf…

萤火虫优化算法(Firefly Algorithm)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 萤火虫优化算法&#xff0c;是由剑桥大学的Xin-She Yang在2009年提出的一种基于群体智能的优化算法。它的灵感来源于萤火虫在夜晚闪烁…

[算法面试]_01_L1和L2正则化,为什么L1正则化更容易导致稀疏?

本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&#xff0c;后续会陆续分享出来&#xff0c;感兴趣的朋友可关注收…

OBS插件--复合模糊

复合模糊 复合是一款滤镜插件&#xff0c;支持多种模糊类型和多种蒙版效果。支持模糊源的部分显示区域&#xff0c;可以反选区域进行模糊&#xff0c;这个功能对于场景部分区域需要遮盖非常实用。 下面截图演示下操作步骤&#xff1a; 首先&#xff0c;打开 OBS直播助手 在…

2024年数维杯数学建模

高质量原创论文已完成 需要的私我