編譯IOS ffmpeg庫
準備條件
- 先下載文件:https://github.com/libav/gas-preprocessor,
- 復制gas-preprocessor.pl到/usr/sbin下,(這個應該是復制到/usr/local/bin)
- 修改文件權限:chmod 777 /usr/local/bin/gas-preprocessor.pl
- 安裝yasm
具體步驟
解壓,找到文件 build-ffmpeg.sh
執行服本文件:./build-ffmpeg.sh, 由于本人沒有事先安裝Yasm 執行腳本文件會出錯,按提示操作就可以了。
編譯完成后,終端進入FFmpeg-iOS-build-script目錄,然后輸入./build-ffmpeg.sh lipo,這個命令是講.a文件合并成一個 (可執行可不執行)
把ffmpeg-iOS文件加入到工程中
添加一個頭文件引用 #include "avformat.h"添加一個api語句:av_register_all();給一個類文件.m后綴改為.mm,開啟混編模式。運行工程,如果沒有報錯,則表明編譯成功
其他注意細節 編譯的時候報錯: 'libavcodec/avcodec.h' file not found ,修改Header search paths 里的路徑:$(PROJECT_DIR)/FFmpeg-iOS/include
最最最重要的 弄了幾天加入 External libraries: libz.dylib libbz2.dylib libiconv.dylib VideoToolbox.framework CoreMedia.framework CoreVideo.framework (少了后面三個 也會報錯。 )
在IOS項目中用命令調用ffmpeg
按照上面步驟 編譯IOS FFmpeg庫。
-
添加使用的C++文件到項目中
cmdutils_common_opts.h
cmdutils.c
cmdutils.h
config.h
ffmpeg_filter.c
ffmpeg_opt.c
ffmpeg_videotoolbox.c
ffmpeg.c
ffmpeg.h重要的重要的重要的 是加這些文件的時候,會提示缺少引用的頭文件,對應的頭文件請到源碼中找到,然后添加到上一步驟的include文件夾中是加這些文件的時候,會提示缺少引用的頭文件,對應的頭文件請到源碼中找到,然后添加到上一步驟的include文件夾中
- 添加完C++文件后,需要將程序中后需要進行C++混編, 只需要將原本的任意一個.m文件改名為.mm文件后編譯器自 動就會將工程混編
- 編譯會報錯,因為ffmpeg.c文件中包含main函數,請將該函數重命名為ffmpeg_main并在ffmpeg.h中添加ffmpeg_main函數的聲明.
- ffmpeg任務完成后會結束進程,而iOS設備都是單進程多線程任務,所以需要將cmdutils.c文件中的exit_program方法中的exit(ret) ;改為結束線程
//需要引入
#include <pthread.h>
//exit(ret) 改為
pthread_exit(NULL);
- 在工程中如何使用
- FFmpeg使用命令行調用
- 如ffmpeg -i /temp.mp3 -y /test.aac 這條指令就是調用ffmpeg,輸入源(-i)是/temp.mp3文件,輸出到/test.aac,其中-y參數是若存在則直接覆蓋
- ffmpeg -i /temp.mp4 -f flv -y /temp.flv 這條指令是輸入一個視頻文件,將文件轉碼為h264編碼格式的flv文件,-f參數是指定目標格式
- 具體FFmpeg能使用哪些指令可以參考官方文檔或如下博客:http://www.cnblogs.com/wainiwann/p/4128154.html
- PS.這里文件的輸入和輸出不支持assist協議,所以相冊的視頻/圖片需要先拷貝到沙盒中再運行
- iOS如何調用:引入庫 #include "ffmpeg.h", 然后調用函數ffmpeg_main(argc,argv); 第一個參數是參數是int型參數個數,第二個參數為char**類型參數內容,可用如下代碼進行轉換
- FFmpeg使用命令行調用
//將OC對象轉換為對應的C++對象,argv_array為NSArray數組,每個對象為一個指令
int argc=(int)argv_array.count;
char** argv=(char**)malloc(sizeof(char*)*argc);
for(int i=0;i<argc;i++)
{
argv[i]=(char*)malloc(sizeof(char)*1024);
strcpy(argv[i],[[argv_array objectAtIndex:i] UTF8String]);
}
//執行指令
ffmpeg_main(argc,argv);
其他
- 如果想調用C里面函數 需要 寫一個橋接類
- 創建任意一個Cocoa Touch Class
- 點h文件中所有東西都刪除掉 點M鐘留下頭文件
- 點h 中可聲明c函數 在點m中調用 就能完成C和OC之間的通信
轉碼進度條
- 轉換格式
轉換音頻:ffmpeg -i 源文件路徑 -y 輸出路徑
轉換視頻:ffmpeg -ss 00:00:00 -t 00:00:10 -i 源文件路徑 -b:v 1200K -y 輸出路徑 - 參數詳解
-i 輸入源
-y 覆蓋輸出文件
-ss 指定開始時間,hh:mm:ss[.xxx]格式的記錄時間也支持
-t 指定長度,hh:mm:ss[.xxx]格式的記錄時間也支持
-b bitrate 設置比特率,缺省200kb/s,可以后加參數a/v來指定音/視頻流
其它詳細參數可以參考這個blog: http://blog.csdn.net/l_yangliu/article/details/7274968 - 獲得進度
- 首先先監控開始和完成狀態,在C++函數中調用OC方法,來傳遞狀態信息,結束線程前調用stopRuning()結束方法
- 然后獲取視頻文件總時間長度,ffmpeg_opt.c的open_input_file方法中會有時長信息ic->duration,為long long int類型數據
- 定時獲取當前進度時間,ffmpeg.c的print_report方法中會輸出Log,從log中獲取當前的進度信息,為char info[1024]類型數據
- 制作進度條,轉換百分比為當前進度除以總時長
注意事項:更改進度條的時候,是在非主線程,所以無法更改UI,需要在主線程執行更改UI操作