(iOS) FFmpeg學習筆記

編譯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

具體步驟

  1. 下載腳本:https://github.com/kewlbear/FFmpeg-iOS-build-script

  2. 解壓,找到文件 build-ffmpeg.sh

  3. 執行服本文件:./build-ffmpeg.sh, 由于本人沒有事先安裝Yasm 執行腳本文件會出錯,按提示操作就可以了。

  4. 編譯完成后,終端進入FFmpeg-iOS-build-script目錄,然后輸入./build-ffmpeg.sh lipo,這個命令是講.a文件合并成一個 (可執行可不執行)

  5. 把ffmpeg-iOS文件加入到工程中

  6. 添加一個頭文件引用 #include "avformat.h"添加一個api語句:av_register_all();給一個類文件.m后綴改為.mm,開啟混編模式。運行工程,如果沒有報錯,則表明編譯成功

  7. 其他注意細節 編譯的時候報錯: 'libavcodec/avcodec.h' file not found ,修改Header search paths 里的路徑:$(PROJECT_DIR)/FFmpeg-iOS/include

  8. 最最最重要的 弄了幾天加入 External libraries: libz.dylib libbz2.dylib libiconv.dylib VideoToolbox.framework CoreMedia.framework CoreVideo.framework (少了后面三個 也會報錯。 )

在IOS項目中用命令調用ffmpeg

  1. 按照上面步驟 編譯IOS FFmpeg庫。

  2. 添加使用的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文件夾中

    1. 添加完C++文件后,需要將程序中后需要進行C++混編, 只需要將原本的任意一個.m文件改名為.mm文件后編譯器自 動就會將工程混編
    2. 編譯會報錯,因為ffmpeg.c文件中包含main函數,請將該函數重命名為ffmpeg_main并在ffmpeg.h中添加ffmpeg_main函數的聲明.
    3. ffmpeg任務完成后會結束進程,而iOS設備都是單進程多線程任務,所以需要將cmdutils.c文件中的exit_program方法中的exit(ret) ;改為結束線程
      //需要引入 
     #include <pthread.h>
     //exit(ret)  改為
        pthread_exit(NULL);
  1. 在工程中如何使用
    1. 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協議,所以相冊的視頻/圖片需要先拷貝到沙盒中再運行
    2. iOS如何調用:引入庫 #include "ffmpeg.h", 然后調用函數ffmpeg_main(argc,argv); 第一個參數是參數是int型參數個數,第二個參數為char**類型參數內容,可用如下代碼進行轉換
//將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);

其他

  1. 如果想調用C里面函數 需要 寫一個橋接類
    1. 創建任意一個Cocoa Touch Class
    2. 點h文件中所有東西都刪除掉 點M鐘留下頭文件
    3. 點h 中可聲明c函數 在點m中調用 就能完成C和OC之間的通信

轉碼進度條

  1. 轉換格式
    轉換音頻:ffmpeg -i 源文件路徑 -y 輸出路徑
    轉換視頻:ffmpeg -ss 00:00:00 -t 00:00:10 -i 源文件路徑 -b:v 1200K -y 輸出路徑
  2. 參數詳解
    -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
  3. 獲得進度
    1. 首先先監控開始和完成狀態,在C++函數中調用OC方法,來傳遞狀態信息,結束線程前調用stopRuning()結束方法
    2. 然后獲取視頻文件總時間長度,ffmpeg_opt.c的open_input_file方法中會有時長信息ic->duration,為long long int類型數據
    3. 定時獲取當前進度時間,ffmpeg.c的print_report方法中會輸出Log,從log中獲取當前的進度信息,為char info[1024]類型數據
    4. 制作進度條,轉換百分比為當前進度除以總時長
      注意事項:更改進度條的時候,是在非主線程,所以無法更改UI,需要在主線程執行更改UI操作
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 在學習FFmpeg之前,查閱了很多資料包括官方的、國外的、國內的,相信還是雷霄驊資料最適合初學者,在這里哀悼下大神...
    風與鸞閱讀 1,470評論 2 8
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,284評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,232評論 4 61
  • 每個人從生命中來一段日子,教會些東西,然后就走了。誰也無法陪伴我們一輩子。來來往往,既然都是過客,早早的結束反而幸...
    向陽花1993閱讀 117評論 0 0
  • 古長珍/文 九七年仲秋,我有幸來到青島,于是細細游賞一遍嶗山。 嶗山是山東半島的主要山脈。古稱牢山、鱉山。最...
    文心苑閱讀 361評論 2 2