自己編譯能在Android上使用的FFmpeg 製作影音處理App


FFmpeg全名是Fast Forward MPEG(Moving Picture Experts Group),為開源的影音處理軟體,支援多種音訊和視訊的格式,用來處理音訊和視訊的串流,像是轉換檔案格式、剪輯與串接影音,可使用多種外部函式庫來擴展內建函式庫不足的問題。由於FFmpegC語言的專案,因此可以使用Android NDK來編譯成函式庫(Library)或是靜態的執行檔(Executable File),在Android裝置上使用,如此以來便能實作影音處理的App

要編譯成函式庫還是靜態的執行檔?

如果您的C語言程式設計功力不錯,可以將FFmpeg和其他FFmpeg支援的外部編解碼器編譯成函式庫,使用jni實作呼叫函式庫的Java/C語言的轉換介面,直接處理檔案串流。這樣做雖然會十分複雜,但是程式流程會比較好控制。

如果您不太會寫C語言,可以跟筆者一樣將FFmpeg編譯成可以直接在Android上用Command Line執行的檔案,再用Android SDK撰寫呼叫這個檔案的程式。這樣做雖然會簡單很多,但程式流程也變得相當難處理,因為將會有多個行程(Process)。

編譯FFmpeg For Android

編譯環境

編譯FFmpeg,最好是在Linux作業系統或是Unix-like作業系統上進行,且必須要有對應平台的Android NDK,還要有FFmpeg的原始碼專案。

作業系統

推薦使用適合開發軟體的Linux Mint來編譯。

http://www.linuxmint.com/

Android NDK

參考以下網址取得Android NDK

https://magiclen.org/android-ndk/

FFmpeg 原始碼專案

FFmpeg的官網可以下載到FFmpeg的原始碼專案。

https://www.ffmpeg.org/

本篇文章的編譯環境

作業系統Linux Mint 17 MATE x86_64
Android NDKAndroid NDK32 R10 x86_64
FFmpegFFmpeg 2.3.1

開始編譯

由於使用Android NDK來編譯FFmpeg For Android需要進行許多設定,因此筆者把這些設定都整理成一個bash script檔案,檔名為「build_arm.sh」。

build_arm.sh下載:

//file.magiclen.org/index.php?file=66666d7065675f6275696c645f61726d2e73682e726172

請將下載下來的檔案解壓縮後,將「build_arm.sh」放置於FFmpeg的專案根目錄中。

自己編譯能在Android上使用的FFmpeg 製作影音處理App

接著用文字編輯軟體開啟「build_arm.sh」,修改NDK路徑、SYSROOT路徑、TOOLCHAIN路徑,使其符合您的環境。如果您的CPU的執行緒(Thread)數量並非是四個,請修改「make -j4」的數字「4」,將其改為您CPU的執行緒數量,提升編譯效率。

修改好後,將終端機的工作目錄移到FFmpeg的專案根目錄,然後輸入以下指令開始編譯:

./build_arm.sh

編譯過程可能會需要sudo權限,因此可以使用以下指令來避免編譯時因為要求sudo密碼而暫停的情形:

sudo ./build_arm.sh

自己編譯能在Android上使用的FFmpeg 製作影音處理App

編譯需要數分鐘到數十分鐘,請耐心等候。

自己編譯能在Android上使用的FFmpeg 製作影音處理App

編譯完成後,在FFmpeg的專案根目錄可以找到「android」的目錄,「android」目錄內應該要有「arm」和「arm_neon」兩個目錄,在這兩個目錄中的「bin」目錄可以找到「libffmpeg.so」,這就是我們要的執行檔案了。

也許您會覺得奇怪,為什麼執行檔案要命名成「libffmpeg.so」?.so不是函式庫嗎?這是因為我們要將ffmpeg的執行檔放置於Android專案的Lib資料夾下,讓Android在安裝App時自動區分不同ARM指令集的執行檔,所以偽裝成.so檔案。

如果您沒有成功編譯出.so檔案,可以下載筆者編譯好的。

偽libffmpeg.so下載

Android SDK中使用FFmpeg

「arm」和「arm_neon」兩個目錄中存放的「libffmpeg.so」分別是通用型執行檔以及經過neon優化使用armv7-a指令集的執行檔。將這兩個目錄下的「libffmpeg.so」分別放置到Android專案根目錄底下的「libs/armeabi」和「libs/armeabi-v7a」中,如果目錄不存在,就自行建立吧!

接著撰寫專門用來執行「libffmpeg.so」與取得執行結果的類別,程式大概可以如以下這樣寫:

如果程式只有寫到這樣,那麼將無法得知Process的執行狀況和結果到底是怎麼樣,因此可以寫個執行緒,專門用來讀取FFmpeg的output,也就是Process的InputStream(執行檔的輸出成為行程的輸入)。程式如下:

在FFmpeg的Process建立後,使用StreamGobbler來監看Process的執行情況。

當ProcessBuilder使用start方法之後,會產生新的Process出來並非同步的執行,因此如果要取得Process傳回的結果數值的話,必須使用Process的waitFor方法,並等待Process執行結束後才有傳回結果。因此這個方法應該要在主執行緒之外的執行緒中執行會比較好。以下程式可以得到Process執行結束後回傳的數值:

Android SDK操作FFmpeg的程式大致上就是這樣,可以直接使用CLI指令來操作FFmpeg,還算是蠻容易使用的。只是FFmpeg強大的轉檔功能在Android裝置上可能會因裝置硬體設備的關係而效能非常低落,如果要製作影片格式轉換格式這種App的話,還請三思啊!雖然您做起來不一定困難,但是使用者會用得十分痛苦,與其用小小的、慢吞吞的Android裝置轉換影片格式,倒不如用更大台、更快速的個人電腦來完成。

關於作者

Magic Len

各位好,我是Magic Len,是這網站的管理員。我是台灣台中大肚山上人,畢業於台中高工資訊科和台灣科技大學資訊工程系,曾在桃機航警局服役。我熱愛自然也熱愛科學,喜歡和別人分享自己的知識與經驗。如果你有興趣認識我,可以加我的Facebook,並且請註明是從MagicLen來的。

相關文章