阅读 30

制作FFmpeg动态库(make ffmpeg dynamic lib)

需求:将FFmpeg编译成动态库解决引入第三方SDK中包含FFmpeg以至于本项目中FFmpeg冲突的问题,可以引申为解决所有第三方库冲突问题


实现原理: 将FFmpeg编译好的静态库放入Xcode创建的动态库中重新编译以重新生成动态库


阅读前提:

  • 已经有FFmpeg编译好的静态库
  • 懂得如何灵活根据自身ffmpeg增加部分系统库或其他依赖库

GitHub地址(附代码) : XDXFFmpegDynamicLibProject

简书地址 : XDXFFmpegDynamicLibProject

博客地址 : XDXFFmpegDynamicLibProject

掘金地址 : XDXFFmpegDynamicLibProject


实现

1. 利用Xcode创建动态库

create

2. 项目设置

添加Other link flags

  • -ObjC: 这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大(因为加载了其他的objc代码进来)。但是如果静态库中有类和category的话只有加入这个flag才行。

  • -all_load: 这个flag是专门处理-ObjC的一个bug的。用了-ObjC以后,如果类库中只有category没有类的时候这些category还是加载不进来。变通方法就是加入-all_load或者-force-load。-all_load会强制链接器把目标文件都加载进来,即使没有objc代码。-force_load在xcode3.2后可用。但是-force_load后面必须跟一个只想静态库的路径。

注意:在本例中,-all_load是指将ffmpeg静态库注入动态库,否则若SDK中没有调用相关函数,编译出来的动态库则无法调用。

  • -read_only_relocs:重定位
  • suppress: 压制,不显示重定位错误。

build_setting

Enable Bitcode bitcode介绍

如果项目中有支持 Bitcode,要么让第三方库支持 Bitcode;要么关闭 Bitcode 功能, ffmpeg中需要我们关闭bitcode.

bitcode是被编译程序的一种中间形式的代码。包含bitcode配置的程序将会在App store上被编译和链接。bitcode允许苹果在后期重新优化我们程序的二进制文件,而不需要我们重新提交一个新的版本到App store上。

bitcode

3. 将FFmpeg头文件导入SDK Header中,手动拖入即可

因为我们在项目中都是使用类似下面的代码导入FFmpeg

#import "libavformat/avformat.h"
#import "libswscale/swscale.h"
#import "libavcodec/avcodec.h"
#import "libavutil/avutil.h"
#import "libswresample/swresample.h"
#import "libavresample/avresample.h"
#import "libavfilter/avfilter.h"
#import "libavdevice/avdevice.h"

复制代码
想要将头文件也按照文件夹形式放入SDK编出来的目录中的话只能使用引用的形式,否则打包出来的库无法以一个个文件夹的形式。

将ffmpeg相关的头文件夹拖入SDK header的Public文件中,创建引用即可

import1

import2

然后创建一个虚拟目录存放FFmpeg头文件,调整文件目录目录结构

header_file

header_file1

最终,项目中目录结构如下图

structure

4. 添加依赖的系统库或第三方库

ffmpeg中本身会依赖一些系统库,这一方面取决于你在编译FFmpeg源码时所打开的flag,如何开启的越多可能依赖的越多,而本例中仅仅该版本ffmpeg所依赖的系统库,所以,你编译出来仍然报错,需要自己灵活添加系统库或其他依赖的第三方库

system_lib

PS:有的版本或flag标志开启后可能需要苹果的VideoToolbox....

5. 编译成功,并拷贝Framework

build

此时可使用下面指令可进入Framework中查看当前Framework是否为动态库 $ file 二进制文件名

dynamic

6. 新建项目,关闭Bitcode,引入上面编译好的SDK

import_sdk

import_sdk

sdk

7. 配置项目Build Setting

在Header Search Paths中添加FFmpeg文件夹集合的目录,以至于我们可以使用通用的方式去调用FFmpeg,兼容项目中的代码

8.此时可在主控制器中测试,如下

经测试程序可正常运行

#import "ViewController.h"

#import "libavformat/avformat.h"
#import "libswscale/swscale.h"
#import "libavcodec/avcodec.h"
#import "libavutil/avutil.h"
#import "libswresample/swresample.h"
#import "libavresample/avresample.h"
#import "libavfilter/avfilter.h"
#import "libavdevice/avdevice.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    avdevice_register_all();
    
}


@end

复制代码
关注下面的标签,发现更多相似文章
评论