天天看點

ffmpeg源碼編譯詳細過程與使用(含demo)

作者:音視訊流媒體技術

前言

關于ffmpeg so庫的編譯,網上存在各種教程。有些基于windows,有些基于linux~而基于linux的:一般會選擇安裝虛拟機,在其上跑ubuntu系統。其實各種方式都是可以的,隻要最後可以編譯出我們需要的so庫,就是正道。

win10開始自帶了linux的子系統,我們可以直接使用該子系統進行編譯工作,而無需安裝虛拟機等繁瑣流程。本章将詳細羅列完整流程,大緻流程會跟網上類似,但也有更新:

  • 編譯新版的ffmpeg
  • demo中會使用ffmpeg新版的api(注:網上好多教程的demo部分其實無法正常使用,部分api在新版已經廢棄)

開啟linux子系統

啟用子系統服務

打開【啟用或關閉 Windows 功能】,勾選【适用于Linux的Windows子系統】或【Windows Subsystem For Linux】

ffmpeg源碼編譯詳細過程與使用(含demo)

安裝完成後,重新開機電腦

安裝linux

打開Microsoft store,搜尋linux

ffmpeg源碼編譯詳細過程與使用(含demo)

這裡選擇安裝Ubuntu 18.04 LTS(當然,版本可以自己選擇适用的)

啟動ubuntu

安裝完成後,即可在開始菜單啟動該ubuntu子系統。該子系統純指令模式,大夥可以在編譯過程中順便熟悉下linux的指令,哈哈~

ffmpeg源碼編譯詳細過程與使用(含demo)

編譯準備

先安裝和下載下傳需要的檔案,并配置好環境

建立ffmpeg檔案夾(非必須)

隻是為了将所有資源整合到一起,統一管理,可以忽略該流程

下載下傳ffmpeg

  • wget ffmpeg.org/releases/ff…

下載下傳ndk

  • wget dl.google.com/android/rep…

安裝jdk并解壓ndk

為什麼需要這麼繁瑣,還要安裝jdk呢?本來打算安裝unzip用于解壓ndk的,但是由于檔案過大,unzip解壓會失敗,最後選擇使用jar進行解壓

  • sudo apt-get install default-jdk
  • jar xvf android.zip

安裝vim

主要用于編輯編譯腳本,當然也可以使用其他的文本編輯器進行

  • sudo apt-get install vim

相關學習資料推薦,點選下方連結免費報名,先碼住不迷路~】

【免費分享】音視訊學習資料包、大廠面試題、技術視訊和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點選加群免費領取~

ffmpeg源碼編譯詳細過程與使用(含demo)

編譯

調整configure檔案,修改生成生成以lib為字首,.so為字尾的so庫

這裡可以使用vim進行修改。vim的查找快捷鍵為:先按ESC鍵,然後再 / , 輸入需要搜尋的關鍵字

修改前:
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
修改後:
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'           

編寫編譯腳本:android_build.sh

#!/bin/bash
NDK_DIR=/home/king/ffmpeg/android-ndk-r16b
SYSROOT=${NDK_DIR}/platforms/android-19/arch-arm/
TOOLCHAIN=${NDK_DIR}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
function android_build
{
./configure \
--prefix=$PREFIX \
--disable-doc \
--enable-shared \
--disable-static \
--disable-symver \
--enable-gpl \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver
--cross-prefix=${TOOLCHAIN}/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--enable-cross-compile \
--sysroot=${SYSROOT} \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}

CPU=armv7-a
PREFIX=./android/$CPU
ADDI_CFLAGS="-marm"
android_build           

給編譯腳本增權重限

  • sudo chmod -R 777 android_build.sh

開始編譯

  • ./android_build.sh

完成

編譯完成後,會在目前目錄/android/armv7-a/目錄下看到生成的so庫

so庫的使用

使用新版的android studio可以很友善的給現有項目增加c++,直接在對應的module右鍵,選擇Add C++ to Module,即可生成需要的檔案。這裡不使用這種便捷方式,而是使用最原始的流程,一步一步的建構整個流程。

建立FFmpegUtil類并聲明本地方法

public class FFmpegUtil {

    static {
        System.loadLibrary("ffmpegdemo");
    }
    //JNI
    public native String avformatinfo();
    public native String avcodecinfo();
    public native String protocols();
    public native String bsf();
}           

使用javac編譯源檔案FFmpegUtil.java,生成FFmpegUtil.class

執行javac FFmpegUtil.java即可(該步驟在所在源檔案目錄執行)

使用javah -jni生成C頭檔案

javah用法: 
  javah [options] <classes>
其中, [options] 包括:
  -o <file>                輸出檔案 (隻能使用 -d 或 -o 之一)
  -d <dir>                 輸出目錄
  -v  -verbose             啟用詳細輸出
  -h  --help  -?           輸出此消息
  -version                 輸出版本資訊
  -jni                     生成 JNI 樣式的标頭檔案 (預設值)
  -force                   始終寫入輸出檔案
  -classpath <path>        從中加載類的路徑
  -cp <path>               從中加載類的路徑
  -bootclasspath <path>    從中加載引導類的路徑
<classes> 是使用其全限定名稱指定的
(例如, java.lang.Object)。

根據說明,執行的指令應該為:
javah -jni com.example.ffmpegdemo.FFmpegUtil           

這裡有一點需要注意的是,執行目錄不是在FFmpegUtil.class所在的路徑,而應該是在app\src\main\java\路徑下

執行成功後,可以在該目錄下看到生成了com_example_ffmpegdemo_FFmpegUtil.h檔案

用C代碼或CPP代碼寫函數原型的實作

  1. 在app\src\main\下增加cpp檔案夾
  2. 建立可以在該目錄下看到生成了com_example_ffmpegdemo_FFmpegUtil.cpp檔案,實作具體的函數

添加ffmpeg so庫的引用

  1. 在app\路徑下添加libs檔案夾
  2. 将幾個平台的so庫添加到libs目錄下
  3. 将相應的頭檔案添加到libs目錄下,統一放在include下
  4. 在module的build.gradle配置相關資訊
android {
    
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                abiFilters "armeabi-v7a"
            }
        }
        ndk {
            //我們隻有armeabi-v7a就隻配置這個就行了
            abiFilters  'armeabi-v7a'
        }
    }
}           

編寫CMakeLists.txt檔案

CMake檔案的編寫,官方有詳細的教程:配置CMake。主要工作就是配置引用的so庫和相應的頭檔案等消息,具體内容可看demo。

在module的build.gradle配置CMakeLists.txt

android {
    ...
    externalNativeBuild {
        cmake {
            // 要注意相對路徑,我這裡直接放在app\路徑下
            path file('CMakeLists.txt')
        }
    }
}           

使用

基本配置完成,可以正常的在module中使用FFmpegUtil提供的native方法啦~上圖兩張:

ffmpeg源碼編譯詳細過程與使用(含demo)
ffmpeg源碼編譯詳細過程與使用(含demo)

總結

總的流程下來,主要包含兩方面:

  1. 如何不安裝虛拟機編譯新版ffmpeg的so庫
  2. 如何使用編譯出來的so庫,即一般ndk的開發流程 當然,就像上邊提及的,android studio對于ndk開發支援越來越好,也越來越簡便。那為什麼上邊沒有使用簡便的方法呢?有時候你需要自己一步一步進行開發才能了解ADT在背後為我們做了哪些事情,假如脫離ADT我們可以怎麼去完成相應的事情。

最後附上demo位址:gitee-demo

原文 ffmpeg源碼編譯詳細過程與使用(含demo) - 掘金