iOS 中集成 FFmpeg

ffmpeg

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

  1. 編譯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
  1. yasm 1.2.0 yasm 是一個完全重寫的 NASM 匯編业舍。它支持x86和AMD64指令集。
    可以使用homebrew來安裝升酣,如果沒有install yasm舷暮,在執(zhí)行./build-ffmpeg.sh命令的時候,會自動檢測并安裝噩茄。
brew install yasm
  1. 編譯腳本FFmpeg-iOS-build-script
    在這個文件中下面,我們可以對要進(jìn)行編譯的FFmpeg進(jìn)行一系列的設(shè)置。
    FFmpeg-iOS-build-script
  • 設(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é)果
執(zhí)行結(jié)果

二、將FFmpeg導(dǎo)入到項(xiàng)目中

將FFmpeg-iOS添加到項(xiàng)目中
FFmpeg-iOS lib文件
  • 添加依賴庫

libz.tbd
libbz2.tbd
libiconv.tbd
AudioToolbox.framework
CoreMedia.framework
VideoToolbox.framework

三凿菩、FFmpeg命令行功能

相關(guān)的命令行網(wǎng)絡(luò)比較多机杜,這里搜集整理了一些,整理備用蓄髓,同時感謝共享

ffmpeg 命令集舉例

  1. 獲取視頻的信息
ffmpeg -i video.avi 
  1. 將圖片序列合成視頻
ffmpeg -f image2 -i image%d.jpg video.mpg 

上面的命令會把當(dāng)前目錄下的圖片(名字如:image1.jpg. image2.jpg. 等…)合并成video.mpg

  1. 將視頻分解成圖片序列
ffmpeg -i video.mpg image%d.jpg 

上面的命令會生成image1.jpg. image2.jpg. …
支持的圖片格式有:PGM. PPM. PAM. PGMYUV. JPEG. GIF. PNG. TIFF. SGI

  1. 為視頻重新編碼以適合在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
  1. 為視頻重新編碼以適合在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
  1. 從視頻抽出聲音.并存為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
  1. 將wav文件轉(zhuǎn)成Mp3
ffmpeg -i son_origine.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 son_final.mp3 
  1. 將.avi視頻轉(zhuǎn)成.mpg
ffmpeg -i video_origine.avi video_finale.mpg 
  1. 將.mpg轉(zhuǎn)成.avi
ffmpeg -i video_origine.mpg video_finale.avi 
  1. 將.avi轉(zhuǎn)成gif動畫(未壓縮)
ffmpeg -i video_origine.avi gif_anime.gif 
  1. 合成視頻和音頻
ffmpeg -i son.wav -i video_origine.avi video_finale.mpg 
  1. 將.avi轉(zhuǎn)成.flv
ffmpeg -i video_origine.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv video_finale.flv 
  1. 將.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 
  1. 將.avi壓縮成divx
ffmpeg -i video_origine.avi -s 320x240 -vcodec msmpeg4v2 video_finale.avi 
  1. 將Ogg Theora壓縮成Mpeg dvd
ffmpeg -i film_sortie_cinelerra.ogm -s 720x576 -vcodec mpeg2video -acodec mp3 film_terminate.mpg 
  1. 將.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 
  1. 將.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 
  1. 多通道編碼
ffmpeg -i fichierentree -pass 2 -passlogfile ffmpeg2pass fichiersortie-2 
  1. 從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ā)上的使用

  1. 將Appdelegate.m后綴改為.mm预茄,開啟混編模式。
    command+B侦厚,如果沒有報(bào)錯耻陕,則表明編譯成功。
  2. 要對視頻進(jìn)行操作刨沦,還是需要手動寫很多代碼去調(diào)用api诗宣,工作量較大,自然不如直接寫命令行方便想诅。這時候就要添加源碼中的添加源碼中的tools:
    在iOS上集成FFmpeg的命令行工具fftools是個繁瑣的過程召庞,各個版本之間還有差異岛心,需要導(dǎo)入的文件不一樣.
  • 從 ffmpeg-4.0.3 中找到以下文件:


    fftools文件
  • 從 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,編譯成功它改!

  1. 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:^{
                
            }];
        });
        
    });
    
}
  1. 運(yùn)行效果


    2019-01-14 13_38_42.gif
運(yùn)行效果
  1. 編譯報(bào)錯(過程中遇到的兩個報(bào)錯的地方疤孕,及解決辦法)
'libavcodec/avcodec.h' file not found

解決辦法
添加header search paths
屏幕快照 2019-01-11 下午5.05.33.png

加入ffmpeg_hw.c文件!

五央拖、注意事項(xiàng)

  1. ffmpeg 是需要對實(shí)體文件進(jìn)行處理的祭阀,所以無論是輸入源還是輸出源,都必須對應(yīng)實(shí)體文件鲜戒,同時在 ffmpeg 的命令中专控,需指定路徑。對于輸出源來說遏餐,如果不指定 -y伦腐,即覆蓋輸出,那么如果輸出源文件已經(jīng)存在失都,ffmpeg 命令會執(zhí)行失敗柏蘑。
  2. ffmpeg 命令需要阻塞線程來處理,所以為了避免主線程的阻塞粹庞,建議放入子線程進(jìn)行處理咳焚。
  3. ffmpeg 的輸入和輸出需要知道明確的編碼格式:輸入編碼可以通過解碼來獲取到,但是輸入編碼如果指定的話庞溜,就必須與實(shí)體文件編碼一致革半,否則解碼會出錯;輸出源同樣需要指定編碼格式流码,如果沒有明確指定輸出的編碼格式又官,那么需要在輸出路徑中指定后綴,否則會出現(xiàn)編碼出錯漫试。
  4. 如果需要對 GIF 進(jìn)行調(diào)速的話六敬,直接通過指定 GIF 的 -r 來生成新的 GIF 是不合適的,因?yàn)?GIF 的幀間隔可以不一致商虐,而通過設(shè)置 -r觉阅,就將所有幀間隔設(shè)置為一致崖疤,這樣生成的效果與理想效果不一致〉溆拢可通過將 GIF 轉(zhuǎn)為視頻劫哼,然后調(diào)整視頻的速度生成新的視頻,進(jìn)而再生成新 GIF 來達(dá)到目的割笙。
  5. 由于 ffmpeg 的命令行工具中权烧,有許多參數(shù)為全局變量,所以為了保證使用的正確伤溉,我們需要保證在一個時間點(diǎn)般码,只有一次 ffmpeg_main() 方法的調(diào)用。
  6. 在使用全局調(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末携兵,一起剝皮案震驚了整個濱河市疾掰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徐紧,老刑警劉巖静檬,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炭懊,死亡現(xiàn)場離奇詭異,居然都是意外死亡拂檩,警方通過查閱死者的電腦和手機(jī)侮腹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稻励,“玉大人父阻,你說我怎么就攤上這事⊥椋” “怎么了加矛?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長煤篙。 經(jīng)常有香客問我斟览,道長,這世上最難降的妖魔是什么辑奈? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任趣惠,我火速辦了婚禮,結(jié)果婚禮上身害,老公的妹妹穿的比我還像新娘味悄。我一直安慰自己,他們只是感情好塌鸯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布侍瑟。 她就那樣靜靜地躺著,像睡著了一般丙猬。 火紅的嫁衣襯著肌膚如雪涨颜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天茧球,我揣著相機(jī)與錄音庭瑰,去河邊找鬼。 笑死抢埋,一個胖子當(dāng)著我的面吹牛弹灭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揪垄,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼穷吮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了饥努?” 一聲冷哼從身側(cè)響起捡鱼,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酷愧,沒想到半個月后驾诈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缠诅,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年乍迄,在試婚紗的時候發(fā)現(xiàn)自己被綠了滴铅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡就乓,死狀恐怖汉匙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情生蚁,我是刑警寧澤噩翠,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站邦投,受9級特大地震影響伤锚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜志衣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一屯援、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧念脯,春花似錦狞洋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至假勿,卻和暖如春借嗽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背转培。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工恶导, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浸须。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓惨寿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親羽戒。 傳聞我的和親對象是個殘疾皇子缤沦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 0 概述 FFmpeg是一套領(lǐng)先的音視頻多媒體處理開源框架,采用LGPL或GPL許可證易稠。它提供了對音視頻的采集、編...
    但行耕者閱讀 6,790評論 0 19
  • 前言 如此強(qiáng)大的FFmpeg包蓝,能夠?qū)崿F(xiàn)視頻采集驶社、視頻格式轉(zhuǎn)化企量、視頻截圖、視頻添加水印亡电、視頻切片届巩、視頻錄制、視頻推流...
    sillen閱讀 5,368評論 2 45
  • 前言 如此強(qiáng)大的FFmpeg份乒,能夠?qū)崿F(xiàn)視頻采集恕汇、視頻格式轉(zhuǎn)化、視頻截圖或辖、視頻添加水印瘾英、視頻切片、視頻錄制颂暇、視頻推流...
    騷之哈塞給閱讀 25,703評論 6 39
  • 前言 如此強(qiáng)大的FFmpeg缺谴,能夠?qū)崿F(xiàn)視頻采集、視頻格式轉(zhuǎn)化耳鸯、視頻截圖湿蛔、視頻添加水印、視頻切片县爬、視頻錄制阳啥、視頻推流...
    RichyLeo閱讀 17,362評論 1 22
  • 蘑菇閱讀APP肥子嘯收稿啦!好吃又有毒祝高! 長篇投稿一經(jīng)通過審核栗弟,將在作者完稿后,發(fā)放4000-40000元不等稿酬...
    蘑菇閱讀小編閱讀 1,245評論 0 1