Android音視頻——Linux(cygwin)配置ndk,編譯FFmpeg、RTMP

一. 準備工作

這裏簡單說下爲什麼我都是選擇用新版本,因爲NDK在r18及以上版本移除了gcc,ffmpeg最新的版本也是針對交叉編譯Android平臺庫,默認使用clang編譯,編譯方式變了,當然某些文件的路徑就變了。這就是爲啥我們使用新版本,照着網上博客的編譯腳本CV大法搞不定的原因。我這裏被坑的也是一言難盡。

  1. linux操作系統 ,你可以選擇多種方式:比如Mac,比如樹莓派,xshell連接遠程服務器等。原諒我是windows筆記本,在MinGW和cygwin倆者間我選擇了cygwin。附上cygwin下載地址,關於其繁瑣的配置操作這裏就不在贅述了,百度一搜一大把,記住把我們是準備幹什麼的,把插件下載全!!!
  2. NDK,現在網上博客普遍都是用的r17及更低的版本,原諒我這個新版本強迫症患者,我選擇有多新用多新,當前最新版本r21。NDK下載地址
  3. ffmpeg 當然是必須的,同樣的,選擇目前最新版本4.2.2;ffmpeg下載地址

二. 關於操作路徑

因爲我用的windows下的cygwin,所以我選擇偷懶,包括解壓,下載等工作我都選擇直接操作,命令行這個東西能不敲就不敲。
附上我的文件目錄以供參考:
windows下安裝目錄
如果使用cygwin操作的話,當然不能這麼直勾勾輸入這個路徑,還是需要一些其他操作。例子如下:
進入C盤 c:—— /cygdrive/c
進入D盤 d:—— /cygdrive/c

三. ffmpeg配置文件解析

原諒無比懶惰的我,直接windows下進入ffmpeg目錄,直接用記事本或者notepad++都可以,查看裏面的config文件。東西很多,只需要看show_help()這個函數裏面的內容就行了,其他的東西可以選擇性忽略。當然你也可以正了八經的使用命令行掉用幫助信息。
命令行下幫助信息
摘除一些無用信息哈,把有用的東西列出來,我們用vim創建build.sh腳本,加上註釋內容如下。

#!/bin/bash
#NDK路徑
NDK=/cygdrive/e/1Developer/cygwin/home/heima/android-ndk-r21-linux-x86_64

API=21
#編譯平臺 arm aarch64 i686 x86_64
ARCH=arm
# 指定目標cpu的架構 armv7a armv8a
PLATFORM=armv7a
#隨便定義個路徑,方便下面配
TARGET=$PLATFORM-linux-androideabi
# 設置工具鏈。三種版本的ndk均不同linux:linux-x86_64mac MAC:darwin-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
# 設置編譯產物的輸出目錄,這裏表示在當前目錄下新建Android_out目錄
PREFIX=./AndroidLib/$PLATFORM

CFLAG="-D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -Os -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm"

build_lib()
{
#執行configure腳本,用於生成makefile
./configure \
--ln_s="cp -rf" \

--prefix=$PREFIX \
# 指定交叉編譯工具
--cc=$TOOLCHAIN/$TARGET$API-clang \
--cxx=$TOOLCHAIN/$TARGET$API-clang++ \
--ld=$TOOLCHAIN/$TARGET$API-clang \
--target-os=android \
--arch=$ARCH \
--cpu=$PLATFORM \
--cross-prefix=$TOOLCHAIN/$ARCH-linux-androideabi- \
# 開啓交叉編譯
--enable-cross-compile \
--enable-shared \
--disable-static \
--enable-runtime-cpudetect \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
# 優化大小
--enable-small \
--enable-gpl \
--enable-nonfree \
--enable-version3 \
--disable-iconv \
--enable-neon \
--enable-hwaccels \
--enable-jni \
--enable-mediacodec \
# 關閉所有編碼器(播放不需要編碼)
--disable-avdevice  \
--disable-decoders \
--enable-decoder=vp9 \
--enable-decoder=h264 \
--enable-decoder=mpeg4 \
--enable-decoder=aac \
--enable-decoder=h264_mediacodec \
--disable-postproc \
# 會傳給clang的參數
--extra-cflags="$CFLAG" \
--extra-ldflags="-marm"
}
#加載函數
build_lib
#make執行腳本
make clean
make install

這個東西呢,我估計你直接粘貼運行會報錯,因爲有幾個坑。

  1. 因爲拼接命令行裏面的的註釋也會被拼進去影響編譯,這個坑我已經踩過了,直接把build_lib()裏面所有的註釋刪掉再執行。

  2. 編碼格式的問題,因爲我是windows下直接用notepad++編譯的,所以會出些莫名其妙的錯誤,比如換行符一類的。建議直接vim命令創建文本,粘貼進去就好。
    錯誤圖示

  3. 不幸的是仍然會有錯誤,ffmpeg爲了提高編譯速度,引入了yasm,需要安裝yasm的彙編編譯器。當然也可以選擇不安裝,直接按照提示輸入./configure --disable-x86asm,也不知道啥子個原因,我家裏這檯筆記本輸入命令後一直卡在這裏。等吧。。。。

在這裏插入圖片描述
最終成功關閉掉了,如下圖所示。
在這裏插入圖片描述

  1. 繼續運行安裝寫好的build.sh腳本,會經過漫長的等待。。。建議還是下載個yasm。。。相信我,我敲這句話時候已經等了半個小時了。

四. 關於優化

1.我實在忍受不了本地cygwin環境的烏龜速度了,恩,雲服務器,真香~
2.關於make腳本的執行,看了看資料,其實可以開啓多線程的。

make clean
make -j4
make install

五 RTMP編譯

我們可以理解爲FFmpeg只是一個編解碼的庫,如果需要視頻源,就需要引入rtmp。作爲一個實時傳輸協議(萬物皆協議),他用來拉取我們的音視頻流,然後才能用ffmpeg處理他。
在librtmp的根目錄編寫一個build_rtmp.sh,網上隨便抄寫一個。

#!/bin/bash

NDK_ROOT=/home/android-ndk/android-ndk-r21
CPU=arm-linux-androideabi
TOOLCHAIN=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64
export XCFLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=$API"
export XLDFLAGS="--sysroot=${NDK_ROOT}/platforms/android-$API/arch-arm "
export CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-

make install SYS=android prefix=`pwd`/result CRYPTO= SHARED=  XDEF=-DNO_SSL

執行腳本不出意外會報錯:

sh build_rtmp.sh

在這裏插入圖片描述
看下報錯信息,.o鏈接不出來,-gcc: Command not found其中gcc編譯鏈找不到。如果是自己認真編譯過ffmpeg,並且用的是ndk-r17以上版本的一定會熟悉這個錯誤,新版本的ndk不支持gcc編譯鏈,默認爲clang。
理下思路,我們需要找到rtmp編譯文件裏面設置編譯路徑的地方。查看rtmp文件夾下的makefile,其中有2行:

CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
AR=$(CROSS_COMPILE)ar

問題原因就在這裏,make執行的時候默認去找gcc了。我們依照ffmeg的用到的方式,自己在腳本中添加編譯鏈的路徑。添加如下文件之後,發現還是報錯,絕望了。

export CC=$TOOLCHAIN/$TARGET$API-clang
export LD=$TOOLCHAIN/$TARGET$API-clang
export AR=$TOOLCHAIN/$TARGET$API-clang

既然不行,也就不執著了,還有2種方式可以選擇,

  1. 是換成ndkr17及以下
  2. 或者直接源碼放到AS裏面編譯吧。

1. Android Studio編譯

因爲我本地有現成的編譯so庫的工程,並且本地windows環境也便於操作。
簡單說,就是copy /home/rtmp/librtmp/librtmp(就是你下載的rtmp路徑/librtmp)路徑下所有的c/h,自己通過編譯器編譯。Android編譯庫文件

cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on)
set(NAME rtmpdump)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
#預編譯宏
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO"  )
file(GLOB rtmp_source src/*.c)
add_library(${NAME} SHARED ${rtmp_source})

set_target_properties(${NAME}
        PROPERTIES
        LIBRARY_OUTPUT_DIRECTORY
        "${CMAKE_CURRENT_SOURCE_DIR}/lib/${ANDROID_ABI}")

camke執行,最終就會生成需要的so
在這裏插入圖片描述

2. 低版本ndk(r17c)編譯

先吐槽一句啊,xshell/xftp超級難用。
因爲上面我們發現了新版本(17以上)的ndk移除了gcc,默認clang,我又解決不了,所以我也湊合一下用下老版本的ndk吧。
編譯腳本如下

#!/bin/bash

NDK_ROOT=/home/ndk/android-ndk-r17c

CPU=arm-linux-androideabi

TOOLCHAIN=$NDK_ROOT/toolchains/$CPU-4.9/prebuilt/linux-x86_64

export XCFLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=17"
export XLDFLAGS="--sysroot=${NDK_ROOT}/platforms/android-17/arch-arm "
export CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-

make install SYS=android prefix=`pwd`/result CRYPTO= SHARED=  XDEF=-DNO_SSL
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章