ios下 怎么在代码中调用ffmpeg的命令

 我来答
huanglenzhi
2015-04-01 · 知道合伙人数码行家
huanglenzhi
知道合伙人数码行家
采纳数:117538 获赞数:517195
长期从事计算机组装,维护,网络组建及管理。对计算机硬件、操作系统安装、典型网络设备具有详细认知。

向TA提问 私信TA
展开全部
  ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大。目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快; 且网上的讲解不够详细,对于初次接触FFMPEG的新手(例如我)来说确实不太好使用。为了防止忘记,这里对iOS下使用FFMPEG做一个总结。

  1. FFMPEG层次结构的简单理解
  要使用FFMPEG,首先需要理解FFMPEG的代码结构。根据志哥的提示,ffmpeg的代码是包括两部分的,一部分是library,一部分是tool。api都是在library里面,如果直接调api来操作视频的话,就需要写c或者c++了。另一部分是tool,使用的是命令行,则不需要自己去编码来实现视频操作的流程。实际上tool只不过把命令行转换为api的操作而已。

  2. 预热-在mac os下使用ffmpeg
  在mac os下使用ffmpeg比较简单,可以直接使用命令行来操作。首先安装ffmpeg,这里默认系统已经安装好brew,只需要在终端上输入:
  brew install ffmpeg
  等待安装结束即可。
  安装结束后,尝试以下命令:
  ffmpeg -i input.mp4 output.avi
  如果能顺利转换,表明安装成功

  3. 编译能在iOS下使用的FFMPEG library库
  这一步是编译1所说的library,编译好之后可以调用FFMPEG的api。网上有一些方法,但都要自己手动编译,稍显复杂而且比较陈旧。按照app store的需求,编译出来的包还必须支持arm64。我在万能的github中找到一个能够"一键编译"的脚本,地址如下:
  https://github.com/kewlbear/FFmpeg-iOS-build-script
  而且写这个脚本的歪果仁挺好人,更新很及时,已经更新到了最新的2.5.3版本。下载下来,只有一个build-ffmpeg.sh脚本文件。在终端中转至脚本的目录,执行命令:
  ./build-ffmpeg.sh
  脚本则会自动从github中把ffmpeg源码下到本地并开始编译。
  编译结束后,文件目录如下:

  其中,ffmpeg-2.5.3是源码,FFmpeg-iOS是编译出来的库,里面有我们需要的.a静态库,一共有7个。
  执行命令:
  lipo -info libavcodec.a
  查看.a包支持的架构,这几个包都支持了armv7 armv7s i386 x86_64 arm64这几个架构,这个脚本果真是业界良心啊~~~

  4.在xcode中引入FFMPEG library库
  新建工程,把上面编译好的FFmpeg-iOS拖到xcode工程中,添加一个头文件引用
  
  #include "avformat.h"
  添加一个api语句:

  av_register_all();
  添加一个空的类,把执行文件.m后缀改为.mm,开启混编模式。
  添加相应的framework,包括avfoundation和coremedia。
  运行工程,如果没有报错,则表明编译成功。

  5.在xcode项目中使用命令行
  执行到第4步,已经可以使用library库了。但是如果要对视频进行操作,还是需要手动写很多代码去调用api,工作量较大,自然不如直接写命令行方便。为了命令行能够在xcode工程中使用,还需要做以下工作:
  (1)添加源码中的tools,具体文件包括:
  

  (2)添加Header Search Paths
  在target--build setting中搜索Header Search Paths,并在Header Search Paths下面添加源码ffmpeg-2.5.3和scratch的路径。
  (3)修改ffmpeg.h和ffmpeg.c源码

  如果此时run这个工程,则会报错,原因是工程里面有2个main函数,此时处理方法为:
  在ffmpeg.h中添加一个函数声明:
  int ffmpeg_main(int argc, char **argv);
  在ffmpeg.c中找到main函数,把main函数改为ffmpeg_main。
  (4)调用命令行范例
  添加头文件:#import "ffmpeg.h"
  调用命令行
  int numberOfArgs = 16;
  char** arguments = calloc(numberOfArgs, sizeof(char*));
  
  arguments[0] = "ffmpeg";
  arguments[1] = "-i";
  arguments[2] = inputPath;
  arguments[3] = "-ss";
  arguments[4] = "0";
  arguments[5] = "-t";
  arguments[6] = durationChar;
  arguments[7] = "-vcodec";
  arguments[8] = "copy";
  arguments[9] = "-acodec";
  arguments[10] = "aac";
  arguments[11] = "-strict";
  arguments[12] = "-2";
  arguments[13] = "-b:a";
  arguments[14] = "32k";
  arguments[15] = outputPath;
  
  int result = ffmpeg_main(numberOfArgs, arguments);
  其中inputpath和outputpath是文件路径。经测试,这两个路径不支持asset-library://协议和file:// 协议,所以如果是要用相册的文件,我目前的解决办法是把它拷贝到沙盒里面。

  6. 改关闭进程为关闭线程
  如果顺利进行到了第5步,在app中是能够用命令行处理视频了,但会出现一个问题,app会退出。经肖大神提醒,发现了命令行执行完毕之后会退出进程。而iOS下只能启动一个进程,因此必须改关闭进程为关闭线程,或者直接把关闭进程的方法给注掉。

  在ffmpeg.c中可以看到,执行退出进程的方法是exit_program,定位到了cmdutils.c中执行了c语言的exit方法。这里我将它改为了pthread_exit(需要添加#include 头文件)。在xcode项目中使用时,则可以用NSThread来新开一个线程,执行完毕之后,把线程关闭了即可。再使用NSThreadWillExitNotification通知,即可监听线程退出的情况。

  7. 修复ffmpeg.c里面的一个bug
  在实际项目中,可能需要多次调用命令行,但在多次调用命令行的过程中,发现ffmpeg.c的代码中会访问空属性导致程序崩溃。逐步debug后发现,很多指针已经置空了,但它们的计数却没有置零,不知道是不是ffmpeg.c的一个bug。修复方法如下:在ffmpeg_cleanup方法下,将各个计数器置零,包括:
  nb_filtergraphs
  nb_output_files
  nb_output_streams
  nb_input_files
  nb_input_streams
  置零之后,重复使用ffmpeg_main方法一切正常。
帐号已注销
2015-09-09 · TA获得超过4.5万个赞
知道大有可为答主
回答量:1.2万
采纳率:77%
帮助的人:2196万
展开全部
调用命令:system("path/to/ffmpeg -param");
调用的前提是要保证 ffmpeg 在有执行权限的目录下才可以生效。
ffmpeg是一个多平台多媒体处理工具,拥有强大的处理视频和音频的功能。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式