FFmpeg簡介
FFmpeg 有六個常用的功能模塊:
- libavformat:多媒體檔案或協議的封裝和解封裝庫,如 Mp4、Flv 等檔案封裝格式,RTMP、RTSP 等網路協議封裝格式;
- libavcodec:音視頻編解碼庫;
- libavfilter:音視頻、字幕濾鏡庫;
- libswscale:影像格式轉換庫;
- libswresample:音頻重采樣庫;
- libavutil:工具庫;
Android C開發
NDK開發流程
配置
Android NDK環境創建
Android專案,并與NDK進行關聯在
Android專案中宣告所需要呼叫的Native方法使用
Android需要互動的本地代碼 實作在Android中宣告的Native方法通過
ndk - bulid命令編譯產生.so庫檔案編譯
Android Studio工程,從而實作Android呼叫本地代碼
| Java型別 | JNI別名 | 本地型別 |
|---|---|---|
| boolean | jboolean | unsigned char |
| byte | jbyte | signed char |
| char | jchar | unsigned short |
| short | jshort | short |
| int | jint | int |
| long | jlong | long long |
| float | jfloat | float |
| double | jdouble | double |
JNI與NDK關系
- JNI是實作的目的,NDK是在Android中實作JNI的手段
FFmpg環境搭建
編譯環境
- macOS 11.0(m1 2020)
- android-ndk-r21e
- FFmpeg 4.3.1
編譯準備
- 拉取FFmpeg原始碼
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
- 進入原始碼目錄并配置專案
./configure --disable-x86asm
在原始碼目錄下創建編譯腳本build_android_arm64-v8a_clang.sh
#!/bin/bash
export NDK=/Users/comochirs/Documents/andriod_project/NDK/android-ndk-r21e
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
function build_android
{
./configure \
--prefix=$PREFIX \
--enable-neon \
--enable-hwaccels \
--enable-gpl \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"\
make -j16
make install
echo "============================ build android arm64-v8a success =========================="
}
#arm64-v8a
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
build_android
中間會出現無法確認開發者身份的情況,按照系統提示更改即可,編譯成功后會在 android 目錄下生成對應六個模塊的靜態庫和動態庫,若是編譯出錯,需要查看ffbuild/config.log,
FFmpeg 集成
配置AS的C開發環境

創建工程后提示安裝NDK,直接使用之前下載好的檔案,opt + cmd + c復制NDK路徑,粘貼至local.properties檔案下如圖:

切換至project選項,將 FFmpeg 各個模塊的靜態庫和頭檔案放置到指定目錄下

編譯成功!
環境測驗
呼叫API測驗環境配置是否成功
cmake_minimum_required(VERSION 3.10.2)
# Add FFmpeg
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(jnilibs ${CMAKE_SOURCE_DIR}/../jniLibs)
set(libname test-ffmpeg)
include_directories(
include
# ${CMAKE_SOURCE_DIR}/util
)
link_directories(
${jnilibs}/${ANDROID_ABI})
file(GLOB src-files
${CMAKE_SOURCE_DIR}/*.cpp)
add_library( # Sets the name of the library.
${libname}
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${src-files}
)
set(third-party-libs
avformat
avcodec
avfilter
swresample
swscale
avutil
)
set(native-libs
android
EGL
GLESv3
OpenSLES
log
m
z
)
target_link_libraries(
# Specifies the target library.
# FFmpeg
${libname}
# Links the target library to the log library
# included in the NDK.
#FFmpeg
${third-party-libs}
${native-libs}
${log-lib} )
呼叫如下java庫,
package com.example.ffmpegproject_20210211;
public class FFMediaPlayer {
static {
System.loadLibrary("test-ffmpeg");
}
public static String GetFFmpegVersion() {
return native_GetFFmpegVersion();
}
private static native String native_GetFFmpegVersion();
}
值得注意的是可以使用AS直接生產對應JNI函式定義,添加宏后代碼如下
#include <cstdio>
#include <cstring>
#include "jni.h"
//由于 FFmpeg 庫是 C 語言實作的,告訴編譯器按照 C 的規則進行編譯
extern "C" {
#include <libavcodec/version.h>
#include <libavcodec/avcodec.h>
#include <libavformat/version.h>
#include <libavutil/version.h>
#include <libavfilter/version.h>
#include <libswresample/version.h>
#include <libswscale/version.h>
};
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Java_com_example_ffmpegproject_120210211_FFMediaPlayer_native_1GetFFmpegVersion
* Method: native_GetFFmpegVersion
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_example_ffmpegproject_120210211_FFMediaPlayer_native_1GetFFmpegVersion(JNIEnv *env,
jclass clazz) {
// TODO: implement native_GetFFmpegVersion()
char strBuffer[1024 * 4] = {0};
strcat(strBuffer, "libavcodec : ");
strcat(strBuffer, AV_STRINGIFY(LIBAVCODEC_VERSION));
strcat(strBuffer, "\nlibavformat : ");
strcat(strBuffer, AV_STRINGIFY(LIBAVFORMAT_VERSION));
strcat(strBuffer, "\nlibavutil : ");
strcat(strBuffer, AV_STRINGIFY(LIBAVUTIL_VERSION));
strcat(strBuffer, "\nlibavfilter : ");
strcat(strBuffer, AV_STRINGIFY(LIBAVFILTER_VERSION));
strcat(strBuffer, "\nlibswresample : ");
strcat(strBuffer, AV_STRINGIFY(LIBSWRESAMPLE_VERSION));
strcat(strBuffer, "\nlibswscale : ");
strcat(strBuffer, AV_STRINGIFY(LIBSWSCALE_VERSION));
strcat(strBuffer, "\navcodec_configure : \n");
strcat(strBuffer, avcodec_configuration());
strcat(strBuffer, "\navcodec_license : ");
strcat(strBuffer, avcodec_license());
return env->NewStringUTF(strBuffer);
}
#ifdef __cplusplus
}
#endif
構建后沒有問題!成功輸出配置資訊,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/259142.html
標籤:其他
