基於FFMPEG的跨平台播放器實現


基於FFMPEG的跨平台播放器實現

一、背景介紹

    FFmpeg是一款超級強大的開源多媒體編解碼框架,提供了錄制、轉換以及流化音視頻的完整解決方案,包含了libavcodec、libavformat等多個多媒體庫。FFmpeg是基於linux平台下開發的,同樣可以運行於android(其實也是linux,你懂得!)、windows、Mac等平台。

    FFmpeg有多重要?列舉一下我們常用的多媒體處理軟件:暴風影音、QQ影音、KMP(這個牛掰啊)、格式工廠……都使用了FFmpeg,可是他們都被FFmpeg刻上了恥辱柱:理由是把開源的東西改造成不開源的去賺錢!

    說到播放器,千萬不要把FFmpeg和播放器等同,這也是我這篇博文重點介紹的:FFmpeg處理的數據我們看不到,要想看到數據處理的結果,還需要借助另一套多媒體處理框架的幫助,這里就用surface代替吧。

 

                                                                                                            圖一

    那么在不同平台下應該如何搭配FFmpeg與surface呢?我采用如下方案實現:

    linux平台:FFmpeg + SDL。

    Android平台:FFmpeg + surface(jni注入)。

    Windows:FFmpeg + D3D。

    以上三種平台的搭配本人全部實現(代碼陸續上傳到github中,歡迎大家批評指正)。實現難度么,個人感覺Android最難,linux其次,windows較為簡單。本人是從事linux平台開發的,按道理說linux衍生出的Android不應該有太大困難的,這里強烈噴一下GFW,你把谷歌禁了也就罷了,Android相關資源也禁?Android源碼、ADT這些資源找了十天半月,浪費了博主我大把青春歲月。

    閑話少說,下面切入正題。

二、FFmpeg + surface(jni注入)

    平台資源:adt-bundle-windows-x86-20140702、android-ndk-r4b、libffmpeg、cygwin。

    具備知識:JNI、FFmpeg、Android surface。

    1、    adt-bundle-windows-x86-20140702:windows上的Android開發環境,由eclipse、Android SDk、Android模擬器組成。

    2、    android-ndk-r4b:交叉編譯器,用來在Android開發環境下編譯C系語言的交叉編譯器。

    3、    libffmpeg 經過修改的可以由android-ndk-r4b編譯的ffmpeg源碼。

    4、    JNI :JAVA調用C、C++的技術。

    5、    Android surface:android顯示技術。

    6、    Cygwin:因為交叉編譯器是在linux上才能運行的,所以需要cygwin在windows上模擬一個linux環境。

    參考網址

    http://www.cnblogs.com/bjzhanghao/archive/2012/11/14/2769409.html

   (開發資源下載,解決了android官網被牆的不便)

    http://blog.csdn.net/buleriver/article/details/26139109

   (java調用C、C++的實現方法)

    http://www.cnblogs.com/android100/p/android-surfaceView.html

   (android surface 實現方法)

    https://github.com/havlenapetr/FFMpeg

   (超級大牛,ffmpeg在android上實現的鼻祖)

    http://blog.csdn.net/conowen/article/details/7526398

   (針對鼻祖的講解)

    https://github.com/dongguadan/surfaceDraw

   (博主的DEMO)

    開發步驟

    1、搭建環境。

    初學者不建議使用原生態的eclipse加上各種復雜的配置來進行環境搭建,那只會讓你失去學習的樂趣,直接使用配套產品adt-bundle-windows-x86比較簡潔。解壓准備好adt-bundle-windows-x86、ndroid-ndk-r4b,裝好cygwin,進行工程配置,主要是配置交叉編譯器(eclipse是不能直接編譯C系的,需要外部編譯器),如圖2、3。

 

圖2

 

圖3

    2、編譯工程

    可以先使用android-ndk-r4b自帶的hello-jni,也可以使用博主根據havlenapetr裁剪的surfaceDraw(一個簡單的播放器,實現對SD卡中的視頻文件進行播放)。相比於havlenapetr,surfaceDraw功能簡潔,沒有涉及C++、java中一些復雜的技術,可以清晰的看出android調用C++封裝的ffmpeg接口的過程。

    3、創建、運行模擬器

    首先創建模擬器(必須基於API2.2的,后面會說明這樣做的原因),然后運行,導入視頻文件到SD卡,運行APP,如圖4、圖5、圖6。

 

圖4

 

 

圖5

 

 

圖6

    其實Android平台是內置多媒體處理的API的,例如MediaPlayer,只需短短的幾行代碼就可以實現上面整個工程的功能。但是讀者可以仔細想想,如果是這樣簡單的話,那么豈不是誰都可以開發一個簡潔的手機版暴風影音?另一方面,如果開發者想用播放器播放一段流媒體,這段流媒體的接收參數是一段網址(就想優酷在線觀看一樣),而不是本地視頻路徑,MediaPlayer可以么?當然不可以。所以我們需要開發一套可以滿足自己需求的API。

    這就涉及到了Android framework層的知識了。Android簡單說是運行在linux上的虛擬機,用過虛擬機的人都知道,那是相當的消耗資源,在虛擬機上在跑一個復雜的多媒體處理軟件,效率可想而知。那么如何才能提高效率呢?在linux上運行C語言的程序效率當然是最高的,業內公認。所以需要有一種方法使Android 應用繞過虛擬層直接調用linux層的接口進行處理,這就是JNI技術的精髓,也是havlenapetr、surfaceDraw的實現原理。MediaPlayer其實也是用的這種技術,但是基於MediaPlayer的多媒體處理能力、靈活性當然是無法滿足我們的需求的。

 

圖7

    唯一可惜的是目前為止的surfaceDraw只能在Android 2.X上運行,因為工程最重要的兩個庫libjniaudio.so、libjnivideo.so是基於Android2.X的源碼編譯的。基於Android4.X源碼的編譯博主尚位編譯通過,主要原因是Android4.X對編譯的環境要求比較高。后面有時間博主會提供給相關版本的libjniaudio.so、libjnivideo.so。

    Android平台上的FFMpeg移植介紹到這里,下一篇會介紹linux平台上的FFMpeg與SDL的組合應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM