1. 程式人生 > >從零開始學習音視訊程式設計技術(四) FFMPEG的使用

從零開始學習音視訊程式設計技術(四) FFMPEG的使用

零開始學習音視訊程式設計技術(四) FFMPEG的使用

 音視訊開發中最常做的就是編解碼的操作了,以H.264為例:如果想要自己實現編碼h.264,需要對H.264非常的瞭解,首先需要檢視H.264的文件,這個文件好像說是三百多頁(本人並沒有看過)。 想到這,你還寫的下去麼。 算了吧!   好在H264的編碼器,有人已經寫好了,而且還提供了原始碼。主流的h264編碼器有 x264 t264等。 

    因為我們不做研究,也不會去寫編碼器,因此完全沒有必要去看H.264的手冊。我們要做的只需要知道有這麼個東西,在需要的時候 稍微瞭解一下h264的資料格式。最後當然是直接使用別人寫好的編碼器來編碼了。 一個好的程式猿就要做到儘量使用現成的東西做開發,減少精力,減少時間,甚至提高穩定性。

    前面提到的t264和x264都是編解碼h.264用的庫。本人通常是使用x264來做。但對於新手來說,由於對h.264不是很瞭解,因此在使用x264上有點困難,出了問題通常不知道如何解決。並且這些庫都只能編碼一種格式,所以一開始不推薦使用。 而是推薦使用FFMPEG。

    FFMPEG是一個集成了各種編解碼器的庫,可以說是一個全能型的工具,從視訊採集、視訊編碼到視訊傳輸(包括RTP、RTCP、RTMP、RTSP等等協議)都可以直接使用FFMPEG來完成,更重要的一點FFMPEG是跨平臺的,Windows、Linux、Aandroid、IOS這些主流系統通吃。因此初期強烈建議直接使用FFMPEG。

好了,下面進入正題,開始使用FFMPEG吧。

一、FFMPEG獲取:

這裡以Windows版為例,我們前期的例子都是直接在Windows上進行的,因此直接下載Windows版本的,其他系統的先不管他。

下載地址:

開啟後可看到如下介面:

其中 Static 顧名思義就是靜態庫版本了。

Shared則是動態庫版本。

Dev則是提供給開發者用的Lib檔案。

FFMPEG最新版已經是3了。

不過我們用的還是2.5的,當然也可以用其他的,如2.8。基本上版本2的API都是沒差的,因此對開發沒有影響。

找到2.5版本的 點選下載:

二、在工程中引用FFMPEG

開啟我們前面搭建好的Qt Creator。新建一個工程,隨便都行,就選純C++工程吧:

切記:名字和路徑一定不能有中文。

我的工程是放在 :E:MyProjectsVideoDevelop 目錄下

解壓出剛才下載的ffmpeg,解壓後的目錄名字是ffmpeg-2.5.2-win32-dev

改名成ffmpeg,並且只留下include和lib這2個資料夾,其他都刪了。

將ffmpeg直接複製到我們的工程目錄下:

Qt Creator中修改工程配置檔案 testFFmpeg.pro:

在裡面加入:

INCLUDEPATH += $$PWD/ffmpeg/include

LIBS += $$PWD/ffmpeg/lib/avcodec.lib
        $$PWD/ffmpeg/lib/avdevice.lib
        $$PWD/ffmpeg/lib/avfilter.lib
        $$PWD/ffmpeg/lib/avformat.lib
        $$PWD/ffmpeg/lib/avutil.lib
        $$PWD/ffmpeg/lib/postproc.lib
        $$PWD/ffmpeg/lib/swresample.lib
        $$PWD/ffmpeg/lib/swscale.lib

這就是引用ffmpeg的標頭檔案和庫的意思,如下所示:

mian.cpp寫成如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#include <iostream>

using namespace std;

extern "C"

{

#include "libavcodec/avcodec.h"

#include "libavformat/avformat.h"

#include "libswscale/swscale.h"

#include "libavdevice/avdevice.h"

}

///由於我們建立的是C++的工程

///編譯的時候使用的C++的編譯器編譯

///而FFMPEG是C的庫

///因此這裡需要加上extern "C"

///否則會提示各種未定義

int main()

{

//這裡簡單的輸出一個版本號

cout << "Hello FFmpeg!" << endl;

av_register_all();

unsigned version = avcodec_version(); 

cout << "version is:" << version;

return 0;

}

好了點選左下角的綠色按鈕編譯吧:

不一會兒便看到了二個錯誤:

看到錯誤的時候,莫方,2個而已嘛,不防先看看是啥錯誤吧。

先雙擊第一個錯誤:

跳到了common.h:

#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C)

#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
#endif

看不懂什麼鬼意思,總之他的意思就是什麼東西沒定義了,那就按他的要求定義一下吧:

修改main.cpp 

在包含ffmpeg標頭檔案的前面加上:

#define __STDC_CONSTANT_MACROS

如下圖所示:

當然也可以直接在common.h的開頭處加上#define __STDC_CONSTANT_MACROS

我習慣的是後者,這樣改完以後就直接複製改好的檔案就行了,一勞永逸。

好了繼續編譯,這時候錯誤變成一個了,繼續雙擊錯誤。

還是跳到了common.h。

這個檔案還真是多事。

提示UINT64_C未宣告,那就給他宣告一下吧:

在common.h檔案開頭處加入

1

2

3

4

#ifndef INT64_C

#define INT64_C(c) (c ## LL)

#define UINT64_C(c) (c ## ULL)

#endif

修改後的完整檔案如下:

別忘了按CTRL+S.

好了,再次編譯執行吧。

本以為結束了。

執行發現問題又來了:

只有一個黑框,我們上面寫的那些資訊並沒有打印出來。

首先開啟工程目錄,會發現同目錄下多了一個資料夾:build-testFFmpeg-Qt_4_8_2_mingw-Debug

開啟它,我們生成的exe檔案就在build-testFFmpeg-Qt_4_8_2_mingw-Debug/debug/testFFmpeg.exe

直接雙擊執行看看到底是什麼情況。

雙擊執行之後就有提示了,提示缺少dll檔案:

原來忘記把ffmpeg的dll檔案放到裡面了。

我們剛剛只是下載了Dev包,這裡面只有LIB檔案,Lib檔案是編譯連線的時候需要用到的。

而執行的時候需要DLL,因此繼續下載FFMPEG的Shared版本

找到2.5的,下載下來。

一定要和剛才下載的版本一致,否則是沒法執行的:

解壓出 ffmpeg-2.5.2-win32-shared.7z

開啟會看到一個bin目錄,裡面都是dll檔案,這些就是執行時需要的動態庫,

將這些dll複製到,剛才我們生成exe的目錄下(要和exe放在一起)

現在重新開啟Qt Creator,執行,這次終於對了,出現了版本資訊:

至此,就成功了引用了FFMPEG了。