在CSDN上的這一段日子,接觸到了不少同行業的人,尤爲是使用FFMPEG進行視音頻編解碼的人,有的已是有多年經驗的「大神」,有的是剛開始學習的初學者。在和你們探討的過程當中,我突然發現了一個問題:在「大神」和初學者之間好像有一個不可逾越的鴻溝。「大神」們水平高超,探討着深奧的問題;而初學者們還停留在入門階段。到底是什麼緣由形成的這種「兩極分化」呢?最後,我發現了問題的關鍵:FFMPEG難度比較大,卻沒有一個按部就班,由簡單到複雜的教程。如今網上的有關FFMPEG的教程多半難度比較大,不太適合剛接觸FFMPEG的人學習;並且不少的例子程序編譯通不過,極大地打消了學習的積極性。我本身在剛開始學習FFMPEG的時候也遇到了很大的困難。爲了幫助更多的人快速成爲「大神」,我想總結一個學習FFMPEG的方法,方便你們按部就班的學習FFMPEG。linux
0. 背景知識編程
本章主要介紹一下FFMPEG都用在了哪裏(在這裏僅列幾個我所知的,其實遠比這個多)。說白了就是爲了說明:FFMPEG是很是重要的。windows
使用FFMPEG做爲內核視頻播放器:架構
Mplayer,ffplay,射手播放器,暴風影音,KMPlayer,QQ影音...ide
使用FFMPEG做爲內核的Directshow Filter:函數
ffdshow,lav filters...工具
使用FFMPEG做爲內核的轉碼工具:學習
ffmpeg,格式工廠...測試
事實上,FFMPEG的視音頻編解碼功能確實太強大了,幾乎囊括了現存全部的視音頻編碼標準,所以只要作視音頻開發,幾乎離不開它。
本章主要介紹一下ffmpeg工程包含的三個exe的使用方法。
ffmpeg的官方網站是:http://ffmpeg.org/
編譯好的windows可用版本的下載地址(官網中能夠鏈接到這個網站,和官方網站保持同步): http://ffmpeg.zeranoe.com/builds/
該網站中的FFMPEG分爲3個版本:Static,Shared,Dev。
前兩個版本能夠直接在命令行中使用,他們的區別在於:Static裏面只有3個應用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe,每一個exe的體積都很大,相關的Dll已經被編譯到exe裏面去了。Shared裏面除了3個應用程序:ffmpeg.exe,ffplay.exe,ffprobe.exe以外,還有一些Dll,好比說avcodec-54.dll之類的。Shared裏面的exe體積很小,他們在運行的時候,到相應的Dll中調用功能。
Dev版本是用於開發的,裏面包含了庫文件xxx.lib以及頭文件xxx.h,這個版本不包含exe文件。
打開系統命令行接面,切換到ffmpeg所在的目錄,就可使用這3個應用程序了。
ffmpeg是用於轉碼的應用程序。
一個簡單的轉碼命令能夠這樣寫:
將input.avi轉碼成output.ts,並設置視頻的碼率爲640kbps
詳細的使用說明(英文):http://ffmpeg.org/ffmpeg.html
ffplay是用於播放的應用程序。
一個簡單的播放命令能夠這樣寫:
播放test.avi
詳細的使用說明(英文):http://ffmpeg.org/ffplay.html
ffprobe是用於查看文件格式的應用程序。
這個就很少介紹了。
詳細的使用說明(英文):http://ffmpeg.org/ffprobe.html
本章開始介紹使用ffmpeg的庫進行開發。
從http://ffmpeg.zeranoe.com/builds/網站上
1.下載Dev版本,裏面包含了ffmpeg的xxx.h頭文件以及xxx.lib庫文件。
2.下載Shared版本,裏面包含了ffmpeg的dll文件。
3.將這兩部分文件拷貝到VC工程下面就能夠了
注:可能會出現問題,參見:FFMPEG 庫移植到 VC 須要的步驟
若是不想本身手動配置,能夠下載已經配置好的工程:最簡單的基於FFMPEG+SDL的視頻播放器
學習文章《100行代碼實現最簡單的基於FFMPEG+SDL的視頻播放器》中的代碼,這是ffmpeg作視頻播放器最簡單的代碼了,是我本身精簡出來的,已經不能再簡化了,每一行都很重要。
原版是基於SDL1.2的視頻播放器,後來更新了基於SDL2.0的最簡單的視頻播放器:最簡單的基於FFMPEG+SDL的視頻播放器 ver2 (採用SDL2.0)
上述播放器使用libavformat和libavcodec兩個類庫完成了視頻的解碼工做。實際上解碼工做只須要libavcodec就能夠了。所以更新了一個「純淨」的解碼器。該解碼器只使用libavcodec完成解碼工做: 最簡單的基於FFmpeg的解碼器-純淨版(不包含libavformat)
ffmpeg的函數介紹:ffmpeg函數介紹
注1:播放視頻或音頻數據的時候會用到SDL。有關SDL能夠參考:SDL介紹
SDL參考文檔:SDL GUIDE 中文譯本
注2:若是想查看解碼後的數據,須要用到 YUV播放器:YUV播放器源代碼或YUV Player Deluxe均可以
ffmpeg的結構體之間的關係參考文章:FFMPEG中最關鍵的結構體之間的關係
結構體中每一個變量的分析,參考文章:
FFMPEG結構體分析:AVFormatContext
學習文章《最簡單的基於FFMPEG+SDL的音頻播放器》 中的代碼,和最簡單的視頻播放器同樣,這是最簡單的音頻播放器,每一行代碼都很重要。
原版是基於SDL1.2的音頻播放器,後來更新了一個基於SDL2.0的最簡單的音頻播放器:最簡單的基於FFMPEG+SDL的音頻播放器 ver2 (採用SDL2.0)
注:若是想要查看解碼後的數據(PCM數據),須要用到Audition。
ffplay流程圖如文章《FFplay源代碼分析:總體流程圖》 所示。ffplay代碼比較複雜,可是其核心代碼和《100行代碼實現最簡單的基於FFMPEG+SDL的視頻播放器》 是同樣的。能夠兩個工程結合着學習。
ffplay代碼簡介資料:如何用FFmpeg編寫一個簡單播放器
ffplay使用說明:ffplay的快捷鍵以及選項
ffplay已經移植到VC下的工程:ffplay_vc2005(別人作的,質量很不錯)
ffplay移植到MFC下的工程,包含了簡單的圖形界面和一些控制按鈕:ffplay播放器移植VC的工程:ffplay for MFC
上述軟件的代碼簡介:ffplay for mfc 代碼備忘
ffplay.c函數結構簡單分析:ffplay.c函數結構簡單分析(畫圖)
ffmpeg編碼我本身研究的不是不少,能夠參考文章 :使用FFmpeg類庫實現YUV視頻序列編碼爲視頻
上面那篇文章是用的類庫比較舊,新版類庫的的使用能夠參考下面幾篇文章。
圖像的編碼能夠參考:最簡單的基於FFMPEG的圖像編碼器(YUV編碼爲JPEG)
音頻的編碼能夠參考:最簡單的基於FFMPEG的音頻編碼器(PCM編碼爲AAC)
視頻的編碼能夠參考:最簡單的基於FFMPEG的視頻編碼器(YUV編碼爲H.264)
HEVC(H.265)視頻編碼能夠參考:最簡單的基於FFmpeg的視頻編碼器-更新版(YUV編碼爲HEVC(H.265))
上述編碼器使用libavformat和libavcodec兩個類庫完成了視頻的編碼工做。實際上編碼工做只須要libavcodec就能夠了。所以更新了一個「純淨」的編碼器。該編碼器只使用libavcodec完成編碼工做: 最簡單的基於FFmpeg的編碼器-純淨版(不包含libavformat)
轉碼其實是先解碼而後編碼。
不進行轉碼,只進行封裝格式轉換的程序可參考:最簡單的基於FFMPEG的封裝格式轉換器(無編解碼)
轉碼程序可參考:最簡單的基於FFMPEG的轉碼程序
比較複雜的轉碼程序能夠參考ffmpeg.c,它移植到MFC下的工程:ffmpeg轉碼器移植VC的工程:ffmpeg for MFC
ffmpeg.c函數結構簡單分析:ffmpeg.c函數結構簡單分析(畫圖)
通曉了ffmpeg庫的使用之後,能夠看一下ffmpeg的源代碼。注意ffmpeg的源代碼只有在linux下才能編譯,在windows下可使用MinGW進行編譯。推薦使用Eclipse查看ffmpeg的源代碼。
有一個很完整的ffmpeg源代碼的分析文檔:ffdoc
FFmpeg的庫函數源代碼分析文章:
【架構圖】
【通用】
FFmpeg 源代碼簡單分析:av_register_all()
FFmpeg 源代碼簡單分析:avcodec_register_all()
FFmpeg 源代碼簡單分析:內存的分配和釋放(av_malloc()、av_free()等)
FFmpeg 源代碼簡單分析:常見結構體的初始化和銷燬(AVFormatContext,AVFrame等)
FFmpeg 源代碼簡單分析:av_find_decoder()和av_find_encoder()
FFmpeg 源代碼簡單分析:avcodec_open2()
FFmpeg 源代碼簡單分析:avcodec_close()
【解碼】
圖解FFMPEG打開媒體的函數avformat_open_input
FFmpeg 源代碼簡單分析:avformat_open_input()
FFmpeg 源代碼簡單分析:avformat_find_stream_info()
FFmpeg 源代碼簡單分析:av_read_frame()
FFmpeg 源代碼簡單分析:avcodec_decode_video2()
FFmpeg 源代碼簡單分析:avformat_close_input()
【編碼】
FFmpeg 源代碼簡單分析:avformat_alloc_output_context2()
FFmpeg 源代碼簡單分析:avformat_write_header()
FFmpeg 源代碼簡單分析:avcodec_encode_video()
FFmpeg 源代碼簡單分析:av_write_frame()
FFmpeg 源代碼簡單分析:av_write_trailer()
【其它】
FFmpeg源代碼簡單分析:日誌輸出系統(av_log()等)
FFmpeg源代碼簡單分析:結構體成員管理系統-AVClass
FFmpeg源代碼簡單分析:結構體成員管理系統-AVOption
FFmpeg源代碼簡單分析:libswscale的sws_getContext()
FFmpeg源代碼簡單分析:libswscale的sws_scale()
FFmpeg源代碼簡單分析:libavdevice的avdevice_register_all()
FFmpeg源代碼簡單分析:libavdevice的gdigrab
【腳本】
【H.264】
AVFilter能夠給視音頻添加各類濾鏡效果。有一個簡單的例子,是給視頻添加水印:
AVDevice能夠讀取電腦的多媒體設備的數據,或者輸出數據到指定的多媒體設備上。
直接使用ffmpeg.exe命令行工具的文章:FFmpeg獲取DirectShow設備數據(攝像頭,錄屏)
編程方面作了2個有關的例子:
讀取攝像頭:最簡單的基於FFmpeg的AVDevice例子(讀取攝像頭)
屏幕錄製:最簡單的基於FFmpeg的AVDevice例子(屏幕錄製)
Swscale類庫能夠轉換像素數據的格式,同時能夠拉伸圖像的大小。
libswscale的使用示例: 最簡單的基於FFmpeg的libswscale的示例(YUV轉RGB)
此外,這個示例還附帶了一個程序,用於生成測試圖片: 最簡單的基於FFmpeg的libswscale的示例附件:測試圖片生成工具
封裝格式轉換器:最簡單的基於FFMPEG的封裝格式轉換器(無編解碼)
視音頻分離器簡化版(demuxer-simple):最簡單的基於FFmpeg的封裝格式處理:視音頻分離器簡化版(demuxer-simple)
視音頻分離器(demuxer):最簡單的基於FFmpeg的封裝格式處理:視音頻分離器(demuxer)
視音頻複用器(muxer):最簡單的基於FFmpeg的封裝格式處理:視音頻複用器(muxer)
直接使用ffmpeg.exe命令行工具的文章:
編程方面作了一個例子:
基於FFmpeg的推流器:最簡單的基於FFmpeg的推流器(以推送RTMP爲例)
內存播放器:最簡單的基於FFmpeg的內存讀寫的例子:內存播放器
內存轉碼器:最簡單的基於FFmpeg的內存讀寫的例子:內存轉碼器
學習完成ffmpeg,還能夠了解一下基於ffmpeg的相關的多媒體開源工程,在這裏推薦如下幾個:
ffdshow是基於ffmpeg的解碼器類庫libavcodec的DirectShow Filter。普遍安裝在PC上。
有關ffdshow的源代碼分析文章(更新中):
ffdshow 源代碼分析1 : 總體結構
ffdshow 源代碼分析 2: 位圖覆蓋濾鏡(對話框部分Dialog)
LAV Filter是基於ffmpeg的解碼器類庫libavcodec,以及解封裝器類庫libavformat的DirectShow Filter。普遍安裝在PC上。
有關LAV Filter的源代碼分析文章:
LAV Filter 源代碼分析 2: LAV Splitter
LAV Filter 源代碼分析 3: LAV Video (1)
LAV Filter 源代碼分析 4: LAV Video (2)
Mplayer是Linux下使用最普遍的播放器,也有Windows版本的。其中使用了ffmpeg。
有關Mplayer的源代碼分析文章:
如今廣爲使用不少播放器都是構建於Media Player Classic - HC的基礎之上的。
有關Media Player Classic - HC的源代碼分析文章:
Media Player Classic - HC 源代碼分析 1:總體結構
Media Player Classic - HC 源代碼分析 2:核心類 (CMainFrame)(1)
Media Player Classic - HC 源代碼分析 3:核心類 (CMainFrame)(2)
Media Player Classic - HC 源代碼分析 4:核心類 (CMainFrame)(3)
Media Player Classic - HC 源代碼分析 5:關於對話框 (CAboutDlg)
Media Player Classic - HC 源代碼分析 6:MediaInfo選項卡 (CPPageFileMediaInfo)
Media Player Classic - HC 源代碼分析 7:詳細信息選項卡(CPPageFileInfoDetails)
XBMC是一個優秀的自由和開源的(GPL)媒體中心軟件。
有關XBMC源代碼分析文章:
XBMC源代碼分析 1:總體結構以及編譯方法XBMC源代碼分析 4:視頻播放器(dvdplayer)-解碼器(以ffmpeg爲例)
XBMC源代碼簡析 5:視頻播放器(dvdplayer)-解複用器(以ffmpeg爲例)