FFmpeg Xcode 环境搭建

安装 FFmpeg

根据 官方文档 的描述,有三种安装 FFmpeg 的方式,这里我们选择最简单快速的一种,使用 Homebrew 命令安装。

如果还没有安装 Homebrew 的话,请先安装 Homebrew点击跳转官方网站

我们执行如下命令即可安装好 FFmpeg:

1
brew install ffmpeg

Xcode 相关配置

Build Settings

我们通过如下命令即可查看 FFmpeg 的相关信息

1
brew info ffmpeg

会输出类似下面一样的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ffmpeg: stable 4.4 (bottled), HEAD
Play, record, convert, and stream audio and video
https://ffmpeg.org/
/usr/local/Cellar/ffmpeg/4.4_2 (276 files, 52.7MB) *
Poured from bottle on 2021-06-25 at 00:50:35
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/ffmpeg.rb
License: GPL-2.0-or-later
==> Dependencies
Build: nasm ✔, pkg-config ✔
Required: aom ✔, dav1d ✔, fontconfig ✔, freetype ✔, frei0r ✔, gnutls ✔, lame ✔, libass ✔, libbluray ✔, libsoxr ✔, libvidstab ✔, libvorbis ✔, libvpx ✔, opencore-amr ✔, openjpeg ✔, opus ✔, rav1e ✔, rubberband ✔, sdl2 ✔, snappy ✔, speex ✔, srt ✔, tesseract ✔, theora ✔, webp ✔, x264 ✔, x265 ✔, xvid ✔, xz ✔, zeromq ✔, zimg ✔
==> Options
--HEAD
Install HEAD version
==> Analytics
install: 124,147 (30 days), 436,612 (90 days), 1,751,038 (365 days)
install-on-request: 102,817 (30 days), 366,434 (90 days), 1,443,249 (365 days)
build-error: 0 (30 days)

我们在信息中可以找到 FFmpeg 的安装目录如下:

1
/usr/local/Cellar/ffmpeg/4.4_2

目录中包括两个文件夹 libinclude,这两个文件夹我们需要在 Xcode 中配置相关搜索路径。我们打开 XcodeBuild Settings 界面,配置 Header Search PathsLibrary Search Paths。我的本地环境配置如下图所示:

Library

我们切换到 GeneralBuild Phases,将 FFmpeg 目录下的 lib 文件夹中的 .a 文件按需添加,如下图:

此时我们的环境就算是配置完毕。

我们在类中随便加点代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import Cocoa

class ViewController: NSViewController {

override func viewDidLoad() {
super.viewDidLoad()

av_log_set_flags(AV_LOG_SKIP_REPEATED);

#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
avformat_network_init()
}

override var representedObject: Any? {
didSet {

}
}
}

桥接文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import <libavutil/avstring.h>
#import <libavutil/eval.h>
#import <libavutil/mathematics.h>
#import <libavutil/pixdesc.h>
#import <libavutil/imgutils.h>
#import <libavutil/dict.h>
#import <libavutil/fifo.h>
#import <libavutil/parseutils.h>
#import <libavutil/samplefmt.h>
#import <libavutil/avassert.h>
#import <libavutil/time.h>
#import <libavutil/bprint.h>
#import <libavformat/avformat.h>
#import <libavdevice/avdevice.h>
#import <libswscale/swscale.h>
#import <libavutil/opt.h>
#import <libavcodec/avfft.h>
#import <libswresample/swresample.h>

此时我们 Build 一下,发现是可以编译通过的。

遇到的问题

Build 没问题了,我们 run 一下。此时我们可能碰到 crash,提示信息如下:

1
2
3
4
5
6
dyld: Library not loaded: /usr/local/opt/ffmpeg/lib/libswscale.5.dylib
Referenced from: /Users/jiafengwu/Library/Developer/Xcode/DerivedData/ffdemo-gqmgjyhlyiyktmdpikmfktmubkzg/Build/Products/Debug/ffdemo.app/Contents/MacOS/ffdemo
Reason: no suitable image found. Did find:
/usr/local/opt/ffmpeg/lib/libswscale.5.dylib: code signature in (/usr/local/opt/ffmpeg/lib/libswscale.5.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
/usr/local/lib/libswscale.5.dylib: code signature in (/usr/local/lib/libswscale.5.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
/usr/local/Cellar/ffmpeg/4.4_2/lib/libswscale.5.9.100.dylib: code signature in (/usr/local/Cellar/ffmpeg/4.4_2/lib/libswscale.5.9.100.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.

从提示信息我们可知,是动态库没有签名。我们还需将其手动签名一下。顺便说一句,上面的报错是在 FFmpeg 目录中的 lib 目录下,我们将其签名后可能还有其他库需要签名,我的解决方式是,直接吧报错目录下的所有动态库批量签名。

我们从钥匙串中找到我们证书的名字,类似于:Apple Development: xxx

我们打开终端,进入对应目录,执行如下签名命令:

1
codesign -f -s "Apple Development: xxx" *.dylib

引号中的证书信息需要替换成自己的

因为 Xcode 运行代码使用了系统的库,所以我就批量的进行了签名:

1
codesign -f -s "Mac Developer: xxx" /usr/local/opt/*/lib/*.dylib

当我们签名完成之后,再次进行 run,发现就能跑起来了。

总结

签名的相关命令

1、清除动态库的签名

1
codesign --remove-signature xxx.dylib

2、查看签名

1
codesign -vv -d xxx.dylib

或者

1
codesign -dvvv xxx.dylib

3、重新签名

codesign-f 参数就是强制签名的意思,本文使用的 codesign -f -s 就能直接重新签名。如果不想覆盖原来的签名,可以把 -f 参数去掉。