如何在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方法是正常的。