FFmpeg
為什么選擇FFmpeg?
每個主流平台基本都有自己的音視頻開發庫(API),用以處理音視頻數據,比如:
- iOS:AVFoundation、AudioUnit等
- Android:MediaPlayer、MediaCodec等
- Windows:DirectShow等
- ...
為了讓所有平台的開發者都能夠學習到音視頻開發的通用技術,本教程主要講解跨平台的音視頻開發庫FFmpeg。其實只要你掌握了FFmpeg,也可以很快上手其他音視頻開發庫,因為底層原理都是一樣的,你最終操作的都是一樣的數據,比如MP3、MP4文件。
簡介
FFmpeg的名字由FF和mpeg組成。
- FF是Fast Forward(譯為:快進、快速前進)的簡稱
- mpeg來源於Moving Picture Experts Group(簡稱:MPEG,譯為:動態影像專家小組)
- MPEG是源自ISO與IEC等國際組織的工作小組
- MPEG的其中一項工作是:制定音視頻相關的標准(比如壓縮標准)
有很多知名項目都采用了FFmpeg,比如:
- Google Chrome:瀏覽器
- Firefox:瀏覽器
- VLC:跨平台播放器
- MPlayer
- ijkplayer:bilibili團隊開發的Android/iOS播放器框架
- Perian:Apple公司的QuickTime組件
下載
網上已經有編譯好的FFmpeg,目前最新的Release版本是4.3.2,可以直接下載到項目中進行開發使用。
- Windows版本下載:ffmpeg-4.3.2-2021-02-27-full_build-shared.7z
- 源碼下載:ffmpeg-4.3.2.tar.xz
- 網上編譯好的FFmpeg一般是完整版,體積比較大
- 日后我們可以根據實際需要,對FFmpeg的源碼進行裁剪后再進行重新編譯
解壓ffmpeg-4.3.2-2021-02-27-full_build-shared.7z文件后,目錄結構如下所示:
- bin
- 有編譯好的可執行程序:ffmpeg.exe、ffplay.exe、ffprobe.exe,可以直接在命令行上使用,比如
- ffplay xx.mp4:可以直接播放某個視頻
- ffmpeg -version:可以查看FFmpeg的版本號
- 有運行時需要用到的動態庫文件(*.dll)
- 有編譯好的可執行程序:ffmpeg.exe、ffplay.exe、ffprobe.exe,可以直接在命令行上使用,比如
- doc:FFmpeg的使用文檔
- include:開發時需要包含的頭文件
- lib:鏈接時需要用到的庫文件
Qt
如果要想開發一個播放器,肯定得編寫界面,同樣為了保證跨平台開發,這里采用的GUI庫是Qt,官方的開發工具QtCreator是跨平台的(支持Windows、Mac、Linux)。Qt開發采用的編程語言是C++。
下載
本教程中選擇5.14.2版本(從5.15版本開始是收費版本)。
- 下載地址:https://download.qt.io/archive/qt/5.14/5.14.2/
- Windows系統選擇下載:qt-opensource-windows-x86-5.14.2.exe
安裝
需要先注冊,再進行登錄。
勾選MinGW 64bit編譯器(我電腦的系統是64bit)。
如果后期想閱讀Qt源碼,就選擇勾選Qt源碼。
默認已經勾選了QtCreator。
解決控制台中文亂碼
工具 -> 選項。
文本編輯器 -> 行為 -> 文本編碼 -> 默認編碼。
開發初探
第一個Qt項目
打開QtCreator,文件 -> 新建文件或項目。
Application -> Qt Widgets Application。
設置項目名稱和項目的存放路徑。
QtCreator默認會創建一個MainWindow類(主窗口)。
勾選MinGW編譯器。
雙擊打開mainwindow.ui文件,可以往右邊的主窗口中添加一些界面元素(比如按鈕)。
點擊左下角的運行按鈕(綠色三角形),即可看到一個窗口界面,這個就是QtCreator默認創建的主窗口(MainWindow對象)。
消除警告
每次運行Qt程序,你的控制台可能都會出現以下警告信息:QT_DEVICE_PIXEL_RATIO已經過期。
Warning: QT_DEVICE_PIXEL_RATIO is deprecated. Instead use:
QT_AUTO_SCREEN_SCALE_FACTOR to enable platform plugin controlled per-screen factors.
QT_SCREEN_SCALE_FACTORS to set per-screen DPI.
QT_SCALE_FACTOR to set the application global scale factor.
解決方案:設置環境變量QT_SCALE_FACTOR為1即可。
#include "mainwindow.h"
#include <QApplication>
// 導入頭文件【也可以不導入,因為<QApplication>中已經包含了<QByteArray>】
// #include <QByteArray>
int main(int argc, char *argv[]) {
// 通過qputenv函數設置QT_SCALE_FACTOR為1
qputenv("QT_SCALE_FACTOR", QByteArray("1"));
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
集成FFmpeg到Qt項目中
在Windows中,我們最終是通過調用FFmpeg動態庫(dll)中的函數來操作音視頻數據,使用dll的其中一種方式是需要用到3種文件:
- .h:頭文件(Header File)
- 包含了函數的聲明
- 通過#include去導入相應的頭文件
- .dll:動態鏈接庫(Dynamic Link Library)
- 包含了函數的具體實現代碼
- Windows程序會在運行過程中,動態調用dll中的函數
- .lib或.dll.a:(動態鏈接庫的)導入庫(Import Library)
- .lib:用於MSVC編譯器中
- .dll.a:用於MinGW編譯器中
- 包含了dll中函數的入口,用於輔助找到並調用dll中的函數
- 最終需要鏈接到Windows程序中(比如合並到exe文件中)
值得一提的是,在Windows中,靜態鏈接庫(Static Link Library)的擴展名也是.lib、.dll.a。靜態鏈接庫和導入庫的區別是:
- 靜態鏈接庫:包含了函數的具體實現代碼
- 導入庫:不包含函數的具體實現代碼(函數的具體實現代碼存儲在dll中)
修改.pro文件
# 設置頭文件的目錄,以便編譯器能夠找到頭文件
INCLUDEPATH += %FFMPEG_HOME%/include
# 設置導入庫的目錄和需要鏈接的導入庫
LIBS += -L%FFMPEG_HOME%/lib \
-lavcodec \
-lavdevice \
-lavfilter \
-lavformat \
-lavutil \
-lpostproc \
-lswscale \
-lswresample
- #號后面的內容是注釋
- %FFMPEG_HOME%表示ffmpeg-4.3.2-2021-02-27-full_build-shared.7z解壓后的目錄
- 需要根據你的實際情況修改為真實的路徑
- -L:設置導入庫的目錄,以便編譯器能夠找到導入庫
- -l:設置需要鏈接的導入庫名稱
- 導入庫名稱需要去掉文件名前面的lib,比如libavcodec.dll.a就寫成avcodec
調用函數
在main.cpp中調用av_version_info函數,獲取FFmpeg的版本信息。
#include "mainwindow.h"
#include <QApplication>
// 為了使用qDebug函數
#include <QDebug>
// FFmpeg是C語言庫
// 有了extern "C",才能在C++中導入C語言函數
extern "C" {
#include <libavcodec/avcodec.h>
}
int main(int argc, char *argv[]) {
// 打印版本信息
qDebug() << av_version_info();
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
拷貝dll文件
Qt程序編譯成功后,會生成一個exe文件
- exe是Windows中的一種可執行文件
- 我們編寫的程序代碼最終都存在了exe文件中
為了保證exe在運行時能成功調用FFmpeg的函數,那么就得讓exe能夠找到FFmpeg的dll文件(動態庫文件)。可以將%FFMPEG_HOME%/bin目錄中的所有dll文件拷貝到exe文件所在的目錄中,exe在運行的時候,能自動找到跟它同一目錄下的dll文件。
可以通過查看構建目錄得知exe文件所在的目錄。
運行程序后,如果能在控制台看到4.3.2字樣的輸出信息,說明FFmpeg已經集成成功。
dll的搜索順序
exe在尋找dll文件時,大概按照以下優先級順序去查找(這里只列出了大概的搜索路徑,並沒有寫全):
-
exe所在的目錄
-
Windows的System目錄
- C:/Windows/System
- C:/Windows/System32
-
Windows目錄
- C:/Windows
-
環境變量Path中的路徑
- 所以可以考慮將%FFMPEG_HOME%/bin目錄配置到Path變量中
- 置於如何配置Windows的環境變量Path,這是基本開發常識了,就不再講解了
第1種方式需要在每一個Qt程序中都拷貝一份FFmpeg的dll文件,第2~4種方式可以讓多個Qt程序共用同一份FFmpeg的dll文件。
.pro文件
.pro文件是Qt項目的主配置文件。
# 包含了core、gui兩個模塊
QT += core gui
# 高於4版本,就包含widgets模塊
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# 源代碼
SOURCES += \
main.cpp \
mainwindow.cpp
# 頭文件
HEADERS += \
mainwindow.h
# ui文件
FORMS += \
mainwindow.ui
常用快捷鍵
- 字體縮放:Ctrl + 鼠標滾輪
- 幫助文檔:F1
- 注釋:Ctrl + /
- 同名的.h、.cpp文件之間切換:F4