好消息,寫了第一個使用了ffmpeg的庫的小程序。
看起來就是這么簡單的一個消息,但是you have no idea how much work that I did before it works...
?
廢話少說,總結記錄之。。。
一、安裝好Linux的虛擬機。
? ? 我用的是FEDORA-16,當然別的也許能行,不過沒親測。什么叫安裝好,大概定義一下:1、安裝能進入系統,安裝的時候用FEDORA-DVD.ISO比較好,不推薦用LIVE-CD。因為DVD可以自帶更多的軟件,并且在安裝的時候可以選擇“軟件開發”這個選項,這樣的話,就會默認安裝好很多軟件以及其依賴的庫,那樣之后的工作會簡單很多。
? ? 待虛擬機安裝好之后,
二、更新系統軟件
? ? 執行“sudo yum update”,可使得很多軟件更新完畢,當然,耗時有點長,取決于機器性能和網絡環境。
三、安裝git,并且拉取最新ffmpeg源代碼
? ? 因為ffmpeg是用git來維護整個項目的,所以我們必須安裝好git,然后用git去拉去最新的源代碼。
? ? 執行“sudo yum install git”,來安裝git。
? ? 執行“git clone git://source.ffmpeg.org/ffmpeg.git”,完畢后會發現當前目錄下會有一個ffmpeg目錄,這就是最新的源代碼了。
四、編譯ffmpeg
? ? 進入ffmpeg文件夾,三部曲,”./configure“,”make“,”sudo make install“。
? ? 在執行./configure的時候,可能會提示沒有安裝yasm,那么執行”sudo yum install yasm“即可。
? ? 在執行make,就是編譯整個ffmpeg項目了,會生成一些二進制文件,例如:ffplay、ffserver、ffmpeg、ffprobe。
? ? 在執行sudo make install時候,會把編譯生成的.a歸檔復制到/usr/local/lib下,下面看結果
[michael@localhost?/]$ ll /usr/local/lib
total 69676
-rw-r--r--. 1 root root 51473968 May ?9 16:48 libavcodec.a
-rw-r--r--. 1 root root ? 582964 May ?9 16:48 libavdevice.a
-rw-r--r--. 1 root root ?1855462 May ?9 16:48 libavfilter.a
-rw-r--r--. 1 root root 15274554 May ?9 16:48 libavformat.a
-rw-r--r--. 1 root root ? 219562 May ?9 16:48 libavresample.a
-rw-r--r--. 1 root root ? 576360 May ?9 16:48 libavutil.a
-rw-r--r--. 1 root root ? 189182 May ?9 16:48 libswresample.a
-rw-r--r--. 1 root root ?1157418 May ?9 16:48 libswscale.a
drwxr-xr-x. 2 root root ? ? 4096 May ?9 16:48 pkgconfig
[michael@localhost?/]$?
? ?還會把ffmpeg的一些.h的頭文件復制到/usr/local/include下,看結果:
[michael@localhost?/]$ ll /usr/local/include/
total 32
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libavcodec
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libavdevice
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libavfilter
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libavformat
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libavresample
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libavutil
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libswresample
drwxr-xr-x. 2 root root 4096 May ?9 16:48 libswscale
[michael@localhost?/]$?
? ? 注意,你可以看到上面這幾個都是目錄,不然進入libavformat看看,看結果:
[michael@localhost?/]$ ll /usr/local/include/libavformat/
total 92
-rw-r--r--. 1 root root 71469 May ?9 16:48 avformat.h
-rw-r--r--. 1 root root 16168 May ?9 16:48 avio.h
-rw-r--r--. 1 root root ?2858 May ?9 16:48 version.h
[michael@localhost?/]$?
? ? 可見真正的頭文件都在對應名字的目錄內,那么我們在程序中引用頭文件的時候,應該這樣寫”#include libavformat/avformat.h“,而不是這樣寫”#include avformat.h“,為什么呢?因為你不指定路徑的情況下,gcc會去/usr/local;/usr下找avformat.h,當然找不到(因為avformat.h在/usr/local/libavformat目錄下,而不是在/usr/local下)。所以往往有人編譯的時候報錯,找不到頭文件,就是這個原因。五、寫一個調用了ffmpeg庫的小程序 ? ?既然ffmpeg安裝完畢,那么就自己編一個小程序,在程序里面調用ffmpeg的API吧。
? ? 源代碼如下所示:(應該是非常簡短的了)
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
#include "stdio.h"
int main(int argc, char* argv[])
{
? ? ? ? printf("going to av_register_all\n");
? ? ? ? av_register_all();
? ? ? ? return 0;
}
? ? 編譯命令如下所示:
gcc -o test ./shortest.c -lavformat -lavcodec -lavutil -lz -lm -lpthread -lbz2
? ? 說一下,為什么使用這個編譯命令。
? ? 首先,av_register_all()函數里面嵌套了更多的函數,他們的聲明在avcodec.h、avformat.h、avutil.h中,所以需要包含這三個頭文件,這一步做好了,可保證編譯不出錯;其次,鏈接階段,需要去找這些被聲明的函數的定義部分,所以需要鏈接這些庫,libavformat.a、libavcodec.a、libavutil.a、z庫、m庫(數學庫)、pthread庫(線程庫)、bz2庫。所以必須-l鏈接這些歸檔庫,最后生成test二進制文件,試著運行吧。
六、總結
? ? 寫起來很簡單,就這五個步驟。但是我自己摸索著,一步一步走過來,理解了不少,可以看到,我之前做了很多準備工作(之前有幾篇blog就是做這些準備工作的記錄,比如編譯,庫的理解)。
? ? 有句話叫一通百通,真的弄懂這個了,不管遇到什么庫,什么API,只要真心搞懂了一種,其他的也是相似的。
? ? 接下來,就是一個基于ffmpeg的轉碼工具的設計實現了,為什么不直接做播放器呢?因為播放器需要SDL的相關知識,暫時我不會,而且播放也只是把解碼后的數據再進一步通過SDL庫來展現,所以轉碼工具就是基礎了,那么從基礎做起總沒壞處。