如何在ios下用代码调用ffmpeg命令

Ffmpeg是一个多平台的多媒体处理工具,在处理视频和音频方面非常强大。目前在网上找到的iOS上使用FFMPEG的信息都比较老,但是FFMPEG的更新迭代更快。而且网上的讲解也不够详细,对于刚接触FFMPEG的新手(比如我)来说真的不太好。为了防止遗忘,下面总结一下iOS下使用FFMPEG的方法。

对1的简单理解。FFMPEG层次结构

要使用FFMPEG,我们首先需要了解FFMPEG的代码结构。根据智哥的提示,ffmpeg的代码由两部分组成,一部分是库,一部分是工具。API都在库中。如果直接调api来操作视频,就需要写C或者c++。另一部分是tool,使用命令行,不需要自己编码实现视频操作过程。事实上,tool只是将命令行转换成一个api操作。

2.预热-在mac os下使用ffmpeg

在mac os下使用ffmpeg相对简单,使用命令行直接操作即可。首先,安装ffmpeg。这里默认系统已经安装了brew,你只需要输入:

brew安装ffmpeg

请等待安装完成。

安装完成后,尝试以下命令:

ffmpeg-I input.mp4输出

如果转换成功,则安装成功。

3.编译可以在iOS下使用的FFMPEG库library。

这一步就是编译1中提到的库,编译完成后就可以调用FFMPEG的api了。网上有一些方法,但是要手动编译,有点复杂和陈旧。根据app store的要求,编译后的包也必须支持arm64。我在万能的github里找到了一个可以一键编译的脚本。地址如下:

/kewlbear/FFmpeg-iOS-build-script

而且写这个脚本的歪坚果很好看,更新也很及时,已经更新到了最新的2.5.3版本。下载下来,只有一个build-ffmpeg.sh脚本文件。转到终端中脚本的目录,并执行命令:

。/build-ffmpeg.sh

脚本会自动从github下载ffmpeg源代码到本地,开始编译。

编译后,文件目录如下:

其中,ffmpeg-2.5.3是源代码,FFmpeg-iOS是编译库,里面包含了。一个我们需要的静态库,而且是七合一* * *。

执行命令:

lipo -info libavcodec.a

看看支持的体系结构。一个包裹。这些包都支持armv7 armv7s i386 x86 _ 64 arm64的架构。这个剧本真的是业界良心~ ~ ~

4.将FFMPEG库引入xcode。

新建一个项目,将上面编译的FFmpeg-iOS拖到xcode项目中,添加一个头文件引用。

#包含" avformat.h "

添加api语句:

av _ register _ all();

添加一个空类,将。可执行文件的m后缀。嗯,开始混合编辑模式。

添加相应的框架,包括avfoundation和coremedia。

运行项目,如果没有错误,说明编译成功。

5.在xcode项目中使用命令行。

到第4步,你已经可以使用库了。但是如果要操作视频,还是需要手动编写大量代码来调用api,工作量很大,自然不如直接写命令行方便。为了在xcode项目中使用命令行,需要完成以下工作:

(1)在源代码中添加工具。具体文件包括:

(2)添加标题搜索路径。

在target - build设置中搜索头搜索路径,在头搜索路径下增加源代码ffmpeg-2.5.3和scratch的路径。

(3)修改ffmpeg.h和ffmpeg.c的源代码。

如果此时运行这个项目,会得到一个错误,因为项目中有两个主要的函数,此时的处理方法是:

在ffmpeg.h中添加一个函数声明:

int ffmpeg_main(int argc,char * * argv);

在ffmpeg.c中找到主函数,将主函数改为ffmpeg_main。

(4)调用命令行示例

添加头文件:#import "ffmpeg.h "

调用命令行

int number of args = 16;

char * * arguments = calloc(numberOfArgs,sizeof(char *));

arguments[0]= " ffmpeg ";

arguments[1]= "-I ";

arguments[2] =输入路径;

参数[3]= "-ss ";

参数[4]= " 0 ";

arguments[5]= "-t ";

arguments[6]= duration char;

arguments[7]= "-vcodec ";

arguments[8]= " copy ";

arguments[9]= "-acodec ";

arguments[10]= " AAC ";

arguments[11]= "-strict ";

arguments[12]= "-2 ";

参数[13]= "-b:a ";

arguments[14]= " 32k ";

arguments[15]= output path;

int result = ffmpeg _ main(numberOfArgs,arguments);

其中,inputpath和outputpath是文件路径。经过测试,这两个路径都不支持asset-library://协议和file://协议,所以如果要使用相册文件,我目前的解决方案是复制到沙盒中。

6.将关闭过程更改为关闭线程

如果第五步顺利,你可以使用命令行处理应用程序中的视频,但会出现一个问题,应用程序将退出。经过小的提醒,他发现在命令行执行完后,他会退出进程。但是iOS下只能启动一个进程,所以需要将关闭进程改为关闭线程,或者直接备注出关闭进程的方法。

在ffmpeg.c中可以看到,执行退出进程的方法是exit_program,C语言的exit方法是在cmdutils.c中执行的,这里我把它改成了pthread_exit(需要加上#include头文件)。在xcode项目中使用时,可以使用NSThread打开一个新线程,执行后再关闭线程。然后使用NSThreadWillExitNotification的通知来监视线程退出。

7.修复ffmpeg.c中的一个bug

在实际项目中,可能需要多次调用命令行,但是在多次调用命令行的过程中,发现ffmpeg.c的代码会访问null属性,导致程序崩溃。经过一步一步的调试,发现很多指针都被清零了,但是它们的计数并没有被清零。不知是不是ffmpeg.c的bug修复方法如下:在ffmpeg_cleanup方法下,所有计数器都置零,包括:

nb _过滤图

nb _输出_文件

nb _输出_流

nb _输入_文件

nb _输入_流

归零后,重用ffmpeg_main方法是正常的。