FFmpeg是一套可以用來記錄哆姻、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序。它提供了錄制然评、轉(zhuǎn)換以及流化音視頻的完整解決方案
ffmpeg的代碼是包括兩部分的却音,一部分是library庶柿,一部分是tool看铆。api都是在library里面,如果直接調(diào)api來操作視頻的話剩彬,就需要寫c或者c++了酷麦。另一部分是tool,使用的是命令行喉恋,則不需要自己去編碼來實(shí)現(xiàn)視頻操作的流程沃饶。
從編譯FFmpeg ——> 到使用FFmpeg ——> 注意事項(xiàng)
一母廷、編譯FFmpeg
- 編譯FFmpeg所需的腳本文件gas-preprocessor
- 下載之后,將 gas-preprocessor.pl 文件復(fù)制到 /usr/sbin/ 目錄下糊肤,如果該目錄無法修改琴昆,那么可將文件復(fù)制到 /usr/local/bin/ 目錄下。
- 為 gas-preprocessor.pl 文件開啟可執(zhí)行權(quán)限馆揉,在終端中進(jìn)行如下命令:
chmod 777 /usr/sbin/gas-preprocessor.pl
或者
chmod 777 /usr/local/bin/gas-preprocessor.pl
- yasm 1.2.0 yasm 是一個完全重寫的 NASM 匯編业舍。它支持x86和AMD64指令集。
可以使用homebrew來安裝升酣,如果沒有install yasm舷暮,在執(zhí)行./build-ffmpeg.sh命令的時候,會自動檢測并安裝噩茄。
brew install yasm
- 編譯腳本FFmpeg-iOS-build-script
在這個文件中下面,我們可以對要進(jìn)行編譯的FFmpeg進(jìn)行一系列的設(shè)置。
- 設(shè)置FFmpeg的版本
FF_VERSION="4.0.3"
- 設(shè)置所要支持的架構(gòu)
ARCHS="arm64 armv7 x86_64 i386"
- 設(shè)置所需要的FFmpeg功能配置
禁用一些不必要的功能绩聘,可以有效地減小最終庫文件的大小
CONFIGURE_FLAGS="--enable-cross-compile --disable-debug --disable-programs \
--disable-doc --enable-pic"
其中 --disable-cross-compile 禁止交叉編譯
其中 --enable-cross-compile 支持交叉編譯
- 進(jìn)入腳本所在文件夾目錄沥割,執(zhí)行腳本
./build-ffmpeg.sh
執(zhí)行結(jié)果二、將FFmpeg導(dǎo)入到項(xiàng)目中
將FFmpeg-iOS添加到項(xiàng)目中- 添加依賴庫
libz.tbd
libbz2.tbd
libiconv.tbd
AudioToolbox.framework
CoreMedia.framework
VideoToolbox.framework
三凿菩、FFmpeg命令行功能
相關(guān)的命令行網(wǎng)絡(luò)比較多机杜,這里搜集整理了一些,整理備用蓄髓,同時感謝共享
ffmpeg 命令集舉例
- 獲取視頻的信息
ffmpeg -i video.avi
- 將圖片序列合成視頻
ffmpeg -f image2 -i image%d.jpg video.mpg
上面的命令會把當(dāng)前目錄下的圖片(名字如:image1.jpg. image2.jpg. 等…)合并成video.mpg
- 將視頻分解成圖片序列
ffmpeg -i video.mpg image%d.jpg
上面的命令會生成image1.jpg. image2.jpg. …
支持的圖片格式有:PGM. PPM. PAM. PGMYUV. JPEG. GIF. PNG. TIFF. SGI
- 為視頻重新編碼以適合在iPod/iPhone上播放
ffmpeg -i source_video.avi input -acodec aac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv+trell -aic 2 -cmp 2 -subcmp 2 -s 320x180 -title X final_video.mp4
說明:
- 源視頻:source_video.avi
- 音頻編碼:aac
- 音頻位率:128kb/s
- 視頻編碼:mpeg4
- 視頻位率:1200kb/s
- 視頻尺寸:320 X 180
- 生成的視頻:final_video.mp4
- 為視頻重新編碼以適合在PSP上播放
ffmpeg -i source_video.avi -b 300 -s 320x240 -vcodec xvid -ab 32 -ar 24000 -acodec aac final_video.mp4
說明:
- 源視頻:source_video.avi
- 音頻編碼:aac
- 音頻位率:32kb/s
- 視頻編碼:xvid
- 視頻位率:1200kb/s
- 視頻尺寸:320 X 180
- 生成的視頻:final_video.mp4
- 從視頻抽出聲音.并存為Mp3
ffmpeg -i source_video.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 sound.mp3
說明:
- 源視頻:source_video.avi
- 音頻位率:192kb/s
- 輸出格式:mp3
- 生成的聲音:sound.mp3
- 將wav文件轉(zhuǎn)成Mp3
ffmpeg -i son_origine.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 son_final.mp3
- 將.avi視頻轉(zhuǎn)成.mpg
ffmpeg -i video_origine.avi video_finale.mpg
- 將.mpg轉(zhuǎn)成.avi
ffmpeg -i video_origine.mpg video_finale.avi
- 將.avi轉(zhuǎn)成gif動畫(未壓縮)
ffmpeg -i video_origine.avi gif_anime.gif
- 合成視頻和音頻
ffmpeg -i son.wav -i video_origine.avi video_finale.mpg
- 將.avi轉(zhuǎn)成.flv
ffmpeg -i video_origine.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv video_finale.flv
- 將.avi轉(zhuǎn)成dv
ffmpeg -i video_origine.avi -s pal -r pal -aspect 4:3 -ar 48000 -ac 2 video_finale.dv
或者:
ffmpeg -i video_origine.avi -target pal-dv video_finale.dv
- 將.avi壓縮成divx
ffmpeg -i video_origine.avi -s 320x240 -vcodec msmpeg4v2 video_finale.avi
- 將Ogg Theora壓縮成Mpeg dvd
ffmpeg -i film_sortie_cinelerra.ogm -s 720x576 -vcodec mpeg2video -acodec mp3 film_terminate.mpg
- 將.avi壓縮成SVCD mpeg2
NTSC格式:
ffmpeg -i video_origine.avi -target ntsc-svcd video_finale.mpg
PAL格式:
ffmpeg -i video_origine.avi -target pal-svcd video_finale.mpg
- 將.avi壓縮成VCD mpeg2
NTSC格式:
ffmpeg -i video_origine.avi -target ntsc-vcd video_finale.mpg
PAL格式:
ffmpeg -i video_origine.avi -target pal-vcd video_finale.mpg
- 多通道編碼
ffmpeg -i fichierentree -pass 2 -passlogfile ffmpeg2pass fichiersortie-2
- 從flv提取mp3
ffmpeg -i source.flv -ab 128k dest.mp3
常用點(diǎn):
對視頻進(jìn)行調(diào)速
ffmpeg -t 3.0 -i /Users/mdm/Desktop/water.mp4 -an -r 25 -filter:v setpts=0.5*PTS -t 6.0 -b:v 1024k -y /Users/mdm/Desktop/newWater.mp4
- 注意:
該方法中叉庐,假設(shè)調(diào)為x倍速舒帮,則setpts=1.0 / x*PTS会喝。
該調(diào)速方法,最多支持在[0.25, 4]區(qū)間內(nèi)調(diào)整玩郊。
其中肢执,一些常見的參數(shù)配置如下:
-f 強(qiáng)制指定編碼格式
-i 輸出源
-t 指定輸入輸出時長
-r 指定幀率,即1S內(nèi)的幀數(shù)
-threads 指定線程數(shù)
-c:v 指定視頻的編碼格式
-ss 指定持續(xù)時長
-b:v 指定比特率
-s 指定分辨率
-y 覆蓋輸出
-filter 指定過濾器
-vf 指定視頻過濾器
-an 指定去除對音頻的影響
四译红、FFmpeg在iOS開發(fā)上的使用
- 將Appdelegate.m后綴改為.mm预茄,開啟混編模式。
command+B侦厚,如果沒有報(bào)錯耻陕,則表明編譯成功。 - 要對視頻進(jìn)行操作刨沦,還是需要手動寫很多代碼去調(diào)用api诗宣,工作量較大,自然不如直接寫命令行方便想诅。這時候就要添加源碼中的添加源碼中的tools:
在iOS上集成FFmpeg的命令行工具fftools是個繁瑣的過程召庞,各個版本之間還有差異岛心,需要導(dǎo)入的文件不一樣.
-
從 ffmpeg-4.0.3 中找到以下文件:
從 scratch 文件夾中找到
config.h
- 修改以下文件:
cmdutils.c 文件中,注釋
#include "compat/va_copy.h"
#include "libavdevice/avdevice.h"
#include "libavresample/avresample.h"
#include "libpostproc/postprocess.h"
#include "libavutil/libm.h"
PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
ffmpeg_filter.c 文件中篮灼,注釋
#include "libavresample/avresample.h"
ffmpeg.c 文件中忘古,注釋
#include "libavdevice/avdevice.h"
#include "libavutil/internal.h"
#include "libavutil/libm.h"
#include "libavformat/os_support.h"
ff_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
ost->forced_keyframes_expr_const_values[FKF_N],
ost->forced_keyframes_expr_const_values[FKF_N_FORCED],
ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],
ost->forced_keyframes_expr_const_values[FKF_T],
ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T],
res);
ffmpeg_opt.c 文件中,注釋
{ "videotoolbox_pixfmt", HAS_ARG | OPT_STRING | OPT_EXPERT, { &videotoolbox_pixfmt}, "" },
為了避免兩個main函數(shù)問題:
ffmpeg.h 文件下增加函數(shù)聲明:
int ffmpeg_main(int argc, char **argv);
ffmpeg.c 文件中:
main函數(shù)修改為ffmpeg_main诅诱;主要是為了避免兩個main函數(shù)存在
修改執(zhí)行一次 ffmpeg_main 方法后 App 退出問題:
cmdutils.h 中,將void exit_program(int ret) av_noreturn;改為void exit_program(int ret);
cmdutils.c 中髓堪,
int exit_program(int ret)
{
if (program_exit)
program_exit(ret);
// exit(ret);
return ret;
}
修改多次調(diào)用 ffmpeg_main 時,訪問空指針的問題:
ffmpeg.c 中
在 ffmpeg_cleanup 方法中
term_exit();
改為:
nb_filtergraphs = 0;
nb_output_files = 0;
nb_output_streams = 0;
nb_input_files = 0;
nb_input_streams = 0;
term_exit();
然后剩下的缺什么.h文件娘荡,就在 ffmpeg-4.0.3找到什么文件旦袋,然后加到include文件夾下對應(yīng)的路徑
command+B,編譯成功它改!
- iOS調(diào)用命令行將視頻轉(zhuǎn)換為一組圖片
添加頭文件:#import "ffmpeg.h"
調(diào)用命令行
- (IBAction)converterBtnAction:(id)sender {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *moviePath = [[NSBundle mainBundle] pathForResource:@"movie" ofType:@"mp4"];
NSString *imageName = @"image%d.jpg";
NSString *imagesPath = [NSString stringWithFormat:@"%@/%@", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject], imageName];
int numberOfArgs = 6;
char** arguments = calloc(numberOfArgs, sizeof(char*));
arguments[0] = "ffmpeg";
arguments[1] = "-i";
arguments[2] = (char *)[moviePath UTF8String];
arguments[3] = "-r";
arguments[4] = "20";
arguments[5] = (char *)[imagesPath UTF8String];
int result = ffmpeg_main(numberOfArgs, arguments);
NSLog(@"----------- %d", result);
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:[[ResultViewController alloc] init] animated:YES completion:^{
}];
});
});
}
-
運(yùn)行效果
- 編譯報(bào)錯(過程中遇到的兩個報(bào)錯的地方疤孕,及解決辦法)
'libavcodec/avcodec.h' file not found
解決辦法加入ffmpeg_hw.c文件!
五央拖、注意事項(xiàng)
- ffmpeg 是需要對實(shí)體文件進(jìn)行處理的祭阀,所以無論是輸入源還是輸出源,都必須對應(yīng)實(shí)體文件鲜戒,同時在 ffmpeg 的命令中专控,需指定路徑。對于輸出源來說遏餐,如果不指定 -y伦腐,即覆蓋輸出,那么如果輸出源文件已經(jīng)存在失都,ffmpeg 命令會執(zhí)行失敗柏蘑。
- ffmpeg 命令需要阻塞線程來處理,所以為了避免主線程的阻塞粹庞,建議放入子線程進(jìn)行處理咳焚。
- ffmpeg 的輸入和輸出需要知道明確的編碼格式:輸入編碼可以通過解碼來獲取到,但是輸入編碼如果指定的話庞溜,就必須與實(shí)體文件編碼一致革半,否則解碼會出錯;輸出源同樣需要指定編碼格式流码,如果沒有明確指定輸出的編碼格式又官,那么需要在輸出路徑中指定后綴,否則會出現(xiàn)編碼出錯漫试。
- 如果需要對 GIF 進(jìn)行調(diào)速的話六敬,直接通過指定 GIF 的 -r 來生成新的 GIF 是不合適的,因?yàn)?GIF 的幀間隔可以不一致商虐,而通過設(shè)置 -r觉阅,就將所有幀間隔設(shè)置為一致崖疤,這樣生成的效果與理想效果不一致〉溆拢可通過將 GIF 轉(zhuǎn)為視頻劫哼,然后調(diào)整視頻的速度生成新的視頻,進(jìn)而再生成新 GIF 來達(dá)到目的割笙。
- 由于 ffmpeg 的命令行工具中权烧,有許多參數(shù)為全局變量,所以為了保證使用的正確伤溉,我們需要保證在一個時間點(diǎn)般码,只有一次 ffmpeg_main() 方法的調(diào)用。
- 在使用全局調(diào)色板的時候乱顾,需要注意與水印的搭配處理板祝。如果全局調(diào)色板是在添加水印之前就已經(jīng)生成,那么添加水印之后走净,使用該全局調(diào)色板生成 GIF券时,水印會被全局調(diào)色板校正,從而在 GIF 上顯示不出來伏伯。
六橘洞、各模塊的功能
libavformat:用于各種音視頻封裝格式的生成和解析;
libavcodec:用于各種類型聲音说搅、圖像編解碼炸枣;
libavutil:包含一些公共的工具函數(shù);
libswscale:用于視頻場景比例縮放弄唧、色彩映射轉(zhuǎn)換适肠;
libpostproc:用于后期效果處理;
ffmpeg:該項(xiàng)目提供的一個工具套才,可用于格式轉(zhuǎn)換迂猴、解碼或電視卡即時編碼等慕淡;
ffsever:一個 HTTP 多媒體即時廣播串流服務(wù)器背伴;
ffplay:是一個簡單的播放器,使用ffmpeg 庫解析和解碼峰髓,通過SDL顯示傻寂;
相關(guān)鏈接
iOS開發(fā)中集成FFmpeg以及相關(guān)注意事項(xiàng)
IOS FFMPEG的使用
??附上demo,如果幫到你了請給個??
GitHub