简介
FFmpeg介绍
FFmpeg创始人Fabrice Bellard。
FFmpeg是领先的多媒体框架,能够解码,编码, 转码,复用,解复用,流式传输,过滤和播放人类和机器创建的任何内容。它支持最晦涩难懂的古代格式,直至最前沿。无论它们是由某些标准委员会,社区还是公司设计的。它还具有高度可移植性:FFmpeg 在各种构建环境、机器架构和配置下,跨Linux、Mac OS X、Microsoft Windows、BSD、Solaris等编译。
FFmpeg项目结构:
它包含可供应用程序使用的libavcodec,libavutil,libavformat,libavfilter,libavdevice,libswscale和libswresample。以及最终用户可用于转码和播放的ffmpeg,ffplay和ffprobe。
Library:
- libavutil是一个包含简化编程功能的库,包括随机数生成器,数据结构,数学例程,核心多媒体实用程序等等。
- libavcodec是一个包含用于音频/视频编解码器的解码器和编码器的库。
- libavformat是一个包含多媒体容器格式的解复用器和复用器的库。
- libavdevice是一个包含输入和输出设备的库,用于从许多常见的多媒体输入/输出软件框架中获取和呈现,包括Video4Linux,Video4Linux2,VfW和ALSA。
- libavfilter是一个包含媒体过滤器的库。
- libswscale是一个执行高度优化的图像缩放和色彩空间/像素格式转换操作的库。
- libswresample是一个执行高度优化的音频重采样,重新矩阵化和样本格式转换操作的库。
Tool:
FFmpeg的小插曲
FFmpeg还有个分身Libav,他们最开始其实是一个团队的成员,由于FFmpeg为了迎合开发商,导致的代码凌乱和ABI不稳定而使得团队分裂了,Libav是FFmpeg镜像过来的,每当Libav有更新的时候FFmpeg会去拉取最新的修改。可以说FFmpeg是Libav的超集,并且FFmpeg似乎更受欢迎。
编译
macOS - FFmpeg
编译环境:
安装HomeBrew:
mac自带brew,不过版本有可能比较老了,需要更新
1
2
3
4
5
$ xcode-select --install #Xcode提供编译环境
$ brew update #更新,有可能会很慢,慢到以为没反应,可以先卸载再安装,也可以继续等待
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" #卸载
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" #安装
$ brew cleanup # 清理所有包的旧版本
安装FFmpeg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ brew info ffmpeg #获取安装选项帮助
$ brew install ffmpeg #安装FFmpeg
#安装FFmpeg完全版,所有的可选依赖项都选中。这可能需要花费上不少的时间,有可能你的网络状态不佳中断了,那还得从新执行一次安装命令,好的是之前下载成功过的不会再次下载了
$ brew install ffmpeg \
--with-aom \
--with-chromaprint \
--with-fdk-aac \
--with-fontconfig \
--with-freetype \
--with-frei0r \
--with-game-music-emu \
--with-libass \
--with-libbluray \
--with-libbs2b \
--with-libcaca \
--with-libgsm \
--with-libmodplug \
--with-librsvg \
--with-libsoxr \
--with-libssh \
--with-libvidstab \
--with-libvmaf \
--with-opencore-amr \
--with-openh264 \
--with-openjpeg \
--with-openssl \
--with-rtmpdump \
--with-rubberband \
--with-speex \
--with-srt \
--with-tesseract \
--with-two-lame \
--with-wavpack \
--with-webp \
--with-zeromq \
--with-zimg
如果出现Empty installation
如下所示,可参考这个issues
1
2
3
4
5
Type `exit' to return and finalize the installation
Install to this prefix: /usr/local/Cellar/ffmpeg/4.1_1......
bash-3.2$ exit
exit
Error: Empty installation
安装成功后查看版本会得到以下信息,我是安装的完整版的FFmpeg
1
2
3
4
5
6
7
8
9
10
11
12
13
$ ffmpeg -version #检测是否安装成功
ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1_1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags=-I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/ --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-chromaprint --enable-frei0r --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfdk-aac --enable-libfontconfig --enable-libfreetype --enable-libgme --enable-libgsm --enable-libmodplug --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-librsvg --enable-librtmp --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtesseract --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libwavpack --enable-libwebp --enable-libzimg --enable-libzmq --enable-opencl --enable-openssl --enable-videotoolbox --enable-libopenjpeg --disable-decoder=jpeg2000 --extra-cflags=-I/usr/local/Cellar/openjpeg/2.3.0/include/openjpeg-2.3 --enable-nonfree
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
此时就可以在终端执行ffmpeg命令进行多媒体处理了。
iOS - FFmpeg
编译环境:
安装yasm:
1
2
3
4
5
6
$ brew install yasm
$ yasm --version
yasm 1.3.0
Compiled on Oct 14 2018.
Copyright (c) 2001-2014 Peter Johnson and other Yasm developers.
Run yasm --license for licensing overview and summary.
使用FFmpeg-iOS-build-script
在Github上下载下来找到build-ffmpeg.sh
,感谢这个国外的朋友,可以给他star。
在build-ffmpeg.sh
文件中修改FF_VERSION
、CONFIGURE_FLAGS
两个参数,我只修改了版本信息为4.1
,没有修改编译的配置参数。
CONFIGURE_FLAGS 部分配置选项:
1
2
$ cd ~/ffmpeg-4.1
$ ./configure --help
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Configuration options:
--disable-static do not build static libraries [no]
--enable-shared build shared libraries [no]
--enable-small optimize for size instead of speed
--disable-runtime-cpudetect disable detecting CPU capabilities at runtime (smaller binary)
--enable-gray enable full grayscale support (slower color)
--disable-swscale-alpha disable alpha channel support in swscale
--disable-all disable building components, libraries and programs
--disable-autodetect disable automatically detected external libraries [no]
Program options:
--disable-programs do not build command line programs
--disable-ffmpeg disable ffmpeg build
--disable-ffplay disable ffplay build
--disable-ffprobe disable ffprobe build
.
.
.
需要精简和优化FFmpeg的话,可以在build-ffmpeg.sh
脚本文件中修改CONFIGURE_FLAGS
参数。比如添加参数:
1
2
3
4
5
6
7
8
9
--disable-muxers disable all muxers
--disable-avdevice disable libavdevice build
--enable-small optimize for size instead of speed
--disable-sdl2 disable sdl2 [autodetect]
Program options:
--disable-programs do not build command line programs
--disable-ffmpeg disable ffmpeg build
--disable-ffplay disable ffplay build
--disable-ffprobe disable ffprobe build
此时CONFIGURE_FLAGS
值为:
1
2
3
CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
--disable-doc --enable-pic \
--enable-gpl --enable-small --disable-sdl2 --disable-ffmpeg --disable-ffplay --disable-ffprobe --disable-avdevice --disable-network --disable-postproc"
在终端中运行build-ffmpeg.sh
文件,等待一段时间,得到4个文件夹:
1
2
3
4
ffmpeg-4.1
FFmpeg-iOS
scratch
thin
集成
iOS集成FFmpeg静态库
把FFmpeg-iOS
中的文件全部拖入到项目工程里面,再到TARGETS->Build Phases->Link Binary With Libraries
中添加下面几个依赖库:
iOS集成FFmpeg Tool
- 找到
./ffmpeg-4.1
中的fftools
拖入工程,当然也可以自己编写C/C++
去调用FFmpeg-Tool
。注意如果是C++
写的Tool话,上面的Libraries还需再添加一个libc++.tbd
。 - 在TARGETS->Build Setting中搜索header search选项添加
$(PROJECT_DIR)/.../include、$(PROJECT_DIR)/fftools
。 - 报错的代码块和
not found
的#include
该注释掉的就直接注释掉好了,因为根本就没用到。 - 项目中只允许一个
main
函数,所以在ffmpeg.c
文件中修改main -> ffmpeg_main
并在头文件中声明。 - 在
ffmpeg.c
文件中导入:#include <pthread/pthread.h>
头文件
优化
在ffmpeg.c
文件中 exit_program
是退出的功能,我们不需要,直接全局改名为ffmpeg_cleanup
。再在ffmpeg_cleanup
函数中结尾处添加一下代码:
1
2
3
4
5
nb_filtergraphs = 0;
nb_output_files = 0;
nb_output_streams = 0;
nb_input_files = 0;
nb_input_streams = 0;
当输出文件已经存在时,APP会闪退。为防止这种情况闪退,在static void assert_file_overwrite(const char *filename)
函数开头添加avpriv_io_delete(filename);
移除旧文件。
更多的优化请自行查找,因为不同版本的优化大多有差异,而且几乎每3个月就有一次版本更新。如果嫌麻烦的话,那就放弃定制化编译吧,这个开源项目MobileFFmpeg可以了解下。
使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#import "ViewController.h"
#import "ffmpeg.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray * array = @[@"ffmpeg",
@"-i",
@"/Users/snloveydus/Desktop/GitHub/NEW/NEW/video.mov",
@"-f",
@"wav",
@"-ar",
@"16000",
@"/Users/snloveydus/Desktop/GitHub/NEW/NEW/video.wav"
];
int argc = (int)array.count;
char **argv = calloc(argc, sizeof(char *));
for (int i = 0; i < array.count; i ++) {
argv[i] = (char *)[array[i] UTF8String];
}
if (!ffmpeg_main(argc, argv)) {
NSLog(@"👌");
}
}
@end
本文项目:DEMO。我会及时更新项目中FFmpeg的版本,并且会陆续开发一个iOS APP来作FFmpeg的使用教程。