【ffmpeg】ffmpeg編譯iOS

目標(biāo)

前段時(shí)間編譯了iOS平臺(tái)的ffmepg,這里記錄一下過(guò)程。
首先是明確目標(biāo):編譯的是x264 + fdk-aac + ffmpeg的iOS庫(kù)

環(huán)境準(zhǔn)備

安裝yasm,brew install yasm

1、編譯x264

1、下載x264的源碼 https://www.videolan.org/developers/x264.html
2、下載github的編譯腳本 https://github.com/kewlbear/x264-ios,根據(jù)自己的架構(gòu)需要,修改腳本
編譯成功后,會(huì)有一個(gè)x264-iOS的文件夾

build-x264.sh
x264的源碼目錄
x264-iOS
  - include
  - lib

2、編譯fdk-aac

1、下載fdk-aac源碼 https://www.linuxfromscratch.org/blfs/view/svn/multimedia/fdk-aac.html
2、下載github的編譯腳本 https://github.com/kewlbear/fdk-aac-build-script-for-iOS根據(jù)自己的架構(gòu)需要,修改腳本
編譯成功后,會(huì)有一個(gè)fdk-aac-ios的文件夾

build-fdk-aac.sh
fdk-aac-2.0.2的源碼目錄
fdk-aac-ios
  - include
  - lib

3、編譯ffmpeg

1、下載ffmpeg源碼,https://ffmpeg.org/download.html
2、下載github的編譯腳本 https://github.com/kewlbear/FFmpeg-iOS-build-script
3、修改腳本的x264-iOS,fdk-aac-ios路徑以及ffmpeg版本號(hào)

# directories
FF_VERSION="4.3.2" # 這里改為你下載的sdk版本
#FF_VERSION="snapshot-git"
if [[ $FFMPEG_VERSION != "" ]]; then
  FF_VERSION=$FFMPEG_VERSION
fi
SOURCE="ffmpeg-$FF_VERSION"
FAT="FFmpeg-iOS" 

SCRATCH="scratch"
# must be an absolute path
THIN=`pwd`/"thin"

# absolute path to x264 library
X264=`pwd`/"x264-iOS" # x264的lib目錄

FDK_AAC=`pwd`/"fdk-aac-ios" # fdk的lib目錄
...

總體的文件目錄是這樣的

build-ffmpeg.sh
x264-ios # x264的lib文件夾
fdk-aac-ios # fdk的lib文件夾
ffmpeg-4.3.2 # ffmpeg的源碼文件夾
FFmpeg-iOS # ffmpeg-iOS編譯產(chǎn)物
  -include
  -lib

demo驗(yàn)證

xcode新建一個(gè)工程,將x264-iOS, fdk-aac-ios, FFmpeg-iOS ,還有ffmpeg源碼目錄的的fftools的以下文件拖入都工程中:

cmdutils.c            ffmpeg.h              ffmpeg_videotoolbox.c
cmdutils.h            ffmpeg_filter.c       mathops.h
config.h              ffmpeg_hw.c
ffmpeg.c              ffmpeg_opt.c

config.h會(huì)根據(jù)configure的執(zhí)行生成,跟fftool同層
mathops.h在源碼的libavcodec目錄下

根據(jù)編譯提示,注釋這些頭文件

#include "libavutil/thread.h
#include "libswresample/swresample.h"
#include "compat/va_copy.h"
#include "libavutil/libm.h"
...

一個(gè)工程只能有一個(gè)main入口,所以需要修改ffmpeg.cmain函數(shù)為int ffmpeg_main,并且在ffmpeg.h文件聲明一下

// ffmpeg.h
int ffmpeg_main(int argc, char **argv);

編譯通過(guò)后,我們就可以通過(guò)xcode來(lái)執(zhí)行ffmpeg的指令,將mp4生成一個(gè)gif

ffmpeg -i out.mp4 out.gif

對(duì)應(yīng)的iOS代碼,引入ffmpeg.h頭文件,以下路徑是在模擬器跑的,真機(jī)需要修改一下輸出路徑

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"out.mp4" ofType:nil];
    NSString *outPath = @"/Users/maple/Desktop/out.gif";
    int argc = 4;
    char **arguments = (char **)calloc(argc, sizeof(char *));
    if(arguments != NULL) {
        arguments[0] = "ffmpeg";
        arguments[1] = "-i";
        arguments[2] = (char *)[filePath UTF8String];
        arguments[3] = (char *)[outPath UTF8String];
        NSLog(@"rescode=%d", ffmpeg_main(argc, arguments));
    }
  ffmpeg_main(argc, arguments);

或者通過(guò)這種方式調(diào)用,比較簡(jiǎn)練

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"out.mp4" ofType:nil];
    NSString *outPath = @"/Users/maple/Desktop/out.gif";
    NSString *cmmondStr = [NSString stringWithFormat:@"ffmpeg -i %@ %@", filePath, outPath];
    NSMutableArray *argv_arr = [cmmondStr componentsSeparatedByString:@" "].mutableCopy;
    int argc = (int)argv_arr.count;
    char **arguments = (char **)calloc(argc, sizeof(char *));
    for(int i = 0; i < argc; i++) {
        NSString *str = argv_arr[i];
        arguments[i] = (char *)[str UTF8String];
    }
    ffmpeg_main(argc, arguments);

為了不讓ffmpeg_main執(zhí)行完后退出程序,這里注釋了ffmpeg_main函數(shù)的最后一行

exit_program(received_nb_signals ? 255 : main_return_code);

demo地址

https://github.com/maple1994/ffmpeg-ios-demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容