點(diǎn)擊下載 Demo
一、FFmpeg簡(jiǎn)介
FFmpeg是一個(gè)開源免費(fèi)跨平臺(tái)的視頻和音頻流方案,屬于自由軟件,采用LGPL或GPL許可證(依據(jù)你選擇的組件)。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫(kù)libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多codec都是從頭開發(fā)的。
FFmpeg的名稱來自MPEG視頻編碼標(biāo)準(zhǔn),前面的“FF”代表“Fast Forward”,F(xiàn)Fmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序??梢暂p易地實(shí)現(xiàn)多種視頻格式之間的相互轉(zhuǎn)換。
FFmpeg的用戶有Google,F(xiàn)acebook,Youtube,優(yōu)酷,愛奇藝,土豆等。
二、Mac配置FFmpeg環(huán)境
1、安裝homebrew
"homebrew"是Mac平臺(tái)的一個(gè)包管理工具,提供了許多Mac下沒有的Linux工具等,而且安裝過程很簡(jiǎn)單。
如果已安裝則忽略此步驟
打開終端輸入以下命令行:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2、安裝FFmpeg
1)利用上面的homebrew安裝FFmpeg:
brew install ffmpeg
2)當(dāng)命令結(jié)束之后,輸入以下命令(查看你的安裝ffmpeg的信息):
brew info ffmpeg
詳情請(qǐng)參考:Mac 配置FFmpeg環(huán)境
三、iOS集成FFmpeg
1、下載腳本FFmpeg腳本地址
這里使用的是 ffmpeg-3.0 版本
2、編譯FFmpeg-iOS-build-script,獲得FFmpeg靜態(tài)庫(kù)文件
打開腳本文件,然后使用終端運(yùn)行:
./build-ffmpeg.sh
編譯的時(shí)間略長(zhǎng),請(qǐng)耐心等待。在Xcode9中可能出會(huì)出現(xiàn)先以下編譯錯(cuò)誤,如沒問題,請(qǐng)忽略
xcrun -sdk iphoneos clang is unable to create an executable file.
C compiler test failed.
If you think configure made a mistake, make sure you are using the latest
version from Git. If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.log" produced by configure as this will help
solve the problem.
這時(shí)只需執(zhí)行以下命令即可,問題鏈接:https://github.com/kewlbear/FFmpeg-iOS-build-script/issues/119
sudo xcode-select --switch /Applications/Xcode.app
3、iOS項(xiàng)目集成FFmpeg
1)上步操作執(zhí)行成功后,會(huì)生成FFmpeg-iOS文件,將該文件直接拖到項(xiàng)目中
2)配置頭文件搜索路徑:在工程文件->Bulid Setting->Search Paths->Header Search Paths添加$(SRCROOT)/$(PRODUCT_NAME)/FFmpeg-iOS/include,(請(qǐng)根據(jù)自己實(shí)際路徑更改)
3)在工程中新建ffmpeg文件夾,并從ffmpeg-3.0的文件中添加如下文件:
cmdutils_common_opts.h
cmdutils.h及cmdutils.c
config.h在scratch目錄下取個(gè)對(duì)應(yīng)平臺(tái)的
ffmpeg_filter.c
ffmpeg_opt.c
ffmpeg_videotoolbox.c
ffmpeg.h及ffmpeg.c
除了config.h文件外,別的文件均在ffmpeg-3.0源碼目錄中
4)編譯后會(huì)報(bào)錯(cuò),然后根據(jù)提示挨個(gè)修復(fù),還需要導(dǎo)入相應(yīng)的依賴庫(kù)。
這步比較繁瑣,可以參考demo進(jìn)行修改,也可以引入demo中的FFmpeg-iOS文件
四、使用FFmpeg轉(zhuǎn)碼
1、FFmpeg使用命令行調(diào)用
1) 如ffmpeg -i /temp.mp3 -y /test.aac 這條指令就是調(diào)用ffmpeg,輸入源(-i)是/temp.mp3文件,輸出到/test.aac,其中-y參數(shù)是若存在則直接覆蓋
2)ffmpeg -i /temp.mp4 -f flv -y /temp.flv 這條指令是輸入一個(gè)視頻文件,將文件轉(zhuǎn)碼為h264編碼格式的flv文件,-f參數(shù)是指定目標(biāo)格式
3)具體FFmpeg能使用哪些指令可以參考官方文檔或如下博客:http://www.cnblogs.com/wainiwann/p/4128154.html
這里舉一個(gè)通過FFmpeg將視頻轉(zhuǎn)碼的例子。
/**
轉(zhuǎn)換視頻
@param inputPath 輸入視頻路徑
@param outpath 輸出視頻路徑
@param processBlock 進(jìn)度回調(diào)
@param completionBlock 結(jié)束回調(diào)
*/
- (void)converWithInputPath:(NSString *)inputPath
outputPath:(NSString *)outpath
processBlock:(void (^)(float process))processBlock
completionBlock:(void (^)(NSError *error))completionBlock {
self.processBlock = processBlock;
self.completionBlock = completionBlock;
self.isBegin = NO;
// ffmpeg語法,可根據(jù)需求自行更改
// !#$ 為分割標(biāo)記符,也可以使用空格代替
NSString *commandStr = [NSString stringWithFormat:@"ffmpeg!#$-ss!#$00:00:00!#$-i!#$%@!#$-b:v!#$2000K!#$-y!#$%@", inputPath, outpath];
// 放在子線程運(yùn)行
[[[NSThread alloc] initWithTarget:self selector:@selector(runCmd:) object:commandStr] start];
}
// 執(zhí)行指令
- (void)runCmd:(NSString *)commandStr{
// 判斷轉(zhuǎn)換狀態(tài)
if (self.isRuning) {
NSLog(@"正在轉(zhuǎn)換,稍后重試");
}
self.isRuning = YES;
// 根據(jù) !#$ 將指令分割為指令數(shù)組
NSArray *argv_array = [commandStr componentsSeparatedByString:(@"!#$")];
// 將OC對(duì)象轉(zhuǎn)換為對(duì)應(yīng)的C對(duì)象
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]);
}
// 打印日志
NSString *finalCommand = @"運(yùn)行參數(shù):";
for (NSString *temp in argv_array) {
finalCommand = [finalCommand stringByAppendingFormat:@"%@",temp];
}
NSLog(@"%@",finalCommand);
// 傳入指令數(shù)及指令數(shù)組
ffmpeg_main(argc,argv);
// 線程已殺死,下方的代碼不會(huì)執(zhí)行
}
2、獲取轉(zhuǎn)碼進(jìn)度條
1) 如果想調(diào)用C里面函數(shù)需要寫一個(gè)橋接類,創(chuàng)建任意一個(gè)Cocoa Touch Class,點(diǎn)h文件中所有東西都刪除掉,點(diǎn)m中留下頭文件,點(diǎn)h 中可聲明c函數(shù) 在點(diǎn)m中調(diào)用 就能完成C和OC之間的通信
監(jiān)控開始和完成狀態(tài),在C++函數(shù)中調(diào)用OC方法,來傳遞狀態(tài)信息,結(jié)束線程前調(diào)用stopRuning()結(jié)束方法
獲取視頻文件總時(shí)間長(zhǎng)度,ffmpeg_opt.c的open_input_file方法中會(huì)有時(shí)長(zhǎng)信息ic->duration,為long long int類型數(shù)據(jù)
定時(shí)獲取當(dāng)前進(jìn)度時(shí)間,ffmpeg.c的print_report方法中會(huì)輸出Log,從log中獲取當(dāng)前的進(jìn)度信息,為char info[1024]類型數(shù)據(jù)
制作進(jìn)度條,轉(zhuǎn)換百分比為當(dāng)前進(jìn)度除以總時(shí)長(zhǎng)。注意事項(xiàng):更改進(jìn)度條的時(shí)候,是在非主線程,所以無法更改UI,需要在主線程執(zhí)行更改UI操作
示例請(qǐng)參考Demo中FFmpegConverOC的使用
參考鏈接:
iOS 集成FFmpeg(通過ffmpeg.h進(jìn)行調(diào)用):http://www.itdecent.cn/p/35ba59292e70
iOS項(xiàng)目中編譯和集成FFmpeg:http://www.itdecent.cn/p/8eef655e1e7c
(iOS) FFmpeg學(xué)習(xí)筆記:http://www.itdecent.cn/p/bdc78b45354c