ffmpeg在音视频领域用的很多 之前都是基于linux windows 以及嵌入式linux等平台
还没有在andorid平台上试过,正好最近新买了台电脑 不用担心性能是 硬盘空间不足的问题
我个人非常不喜欢andorid studio这个 不管咋弄 都要装一大堆东西 ,稍微哪里版本不对 就又给你 下一大堆乱七八糟的东西。网速快还好 我们公司网速最大400k 对于动不动以G为单位的下载量 非常不喜欢 ,不像windows 或者linux 要什么 下下来就可以 。东西比较明确
android 真的要下载很多东西 。特别是刚开始的时候 那个gradle 我特别讨厌
(PS:接触andorid studio 的初步感受 ,也许以后会改变吧 )但是没办法 只有这个一个可以用没办法。我花了整整一天时间 才把第一个例子跑起来 大多数时间都是gradle正在配置啥东西...
而且很多东西都是在外网 ,所以做如下更改将服务器改成国内的。这样快一些
更改项目的build.gradle 内容如下:
buildscript {
repositories {
// maven{ url 'http://maven.aliyun.com/nexus/content/repositories/central/'}
// maven()
maven {
allowInsecureProtocol = true
url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven {
allowInsecureProtocol = true
url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
plugins {
id 'com.android.application' version '7.1.3' apply false
id 'com.android.library' version '7.1.3' apply false
}
allprojects {
repositories {
// maven{ url 'http://maven.aliyun.com/nexus/content/repositories/central/'}
// maven()
maven {
allowInsecureProtocol = true
url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven {
allowInsecureProtocol = true
url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
settings.gradle内容如下:
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
rootProject.name = "nativec"
include ':app'
进入正题,对于不用平台 使用的编译工具不一样,对于andord需要下载NDK 也就是android平台的交叉编译工具。我这里下的是 NDK21e版本 linux-64版本
需要修改下configure文件更改编译程程的so的命名方式 如下图 绿色的是原来的 注释掉
改成下面的方式
下载完之后放到 ubutun 解压 然后配置编译脚本 如下:
#!/bin/bash
API=21
#arm64 x86 x86_64 <----> aarch64 i686 x86_64
ARCH=arm64
ARCH2=aarch64
PREFIX=./android
#此处路径替换为当前NDK路径
TOOLCHAIN=/home/QMCY/ndk/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64
build()
{
#配置各个文件开关及NDK路径等
./configure \
--prefix=$PREFIX \
--disable-static \
--enable-shared \
--enable-small \
--enable-gpl \
--enable-postproc \
--disable-doc \
--disable-programs \
--disable-avdevice \
--enable-cross-compile \
--target-os=android \
--arch=$ARCH \
--cc=$TOOLCHAIN/bin/$ARCH2-linux-android$API-clang \
--cross-prefix=$TOOLCHAIN/bin/$ARCH2-linux-android-
#清除上次编译
make clean
make -j4
make install
}
#开始编译
build
根据实际情况更改成自己的路劲即可
正常编译完安装完之后会在目录下生成一个android目录里面 包括了需要的 include 头文件和so库
如下图
然后 新建一个c++ project 如下图:
之后 在cpp目录下新建文件夹 将include 和so 拷到 对应 目录下
我的实际目录 如下图:
然后 需要在cmakelists.txt中添加库路径 这里的目录关系一定要找对 不然 会找不多对应的库
我的如下:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.18.1)
# Declares and names the project.
project("nativec")
include_directories(${CMAKE_SOURCE_DIR}/qmcyinc/ffmpeg/include)
set(DIR ${CMAKE_SOURCE_DIR}/qmcylibs/ffmpeg/lib)
MESSAGE("default path:"+${PROJECT_SOURCE_DIR})
MESSAGE("Cmake path:"+${CMAKE_SOURCE_DIR}/qmcyinc)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
nativec
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp)
add_library(avcodec
SHARED
IMPORTED)
set_target_properties(
avcodec
PROPERTIES IMPORTED_LOCATION
${DIR}/libavcodec.so)
add_library(avfilter
SHARED
IMPORTED)
set_target_properties(
avfilter
PROPERTIES IMPORTED_LOCATION
${DIR}/libavfilter.so)
add_library(avformat
SHARED
IMPORTED)
set_target_properties(
avformat
PROPERTIES IMPORTED_LOCATION
${DIR}/libavformat.so)
add_library(avutil
SHARED
IMPORTED)
set_target_properties(
avutil
PROPERTIES IMPORTED_LOCATION
${DIR}/libavutil.so)
add_library(swresample
SHARED
IMPORTED)
set_target_properties(
swresample
PROPERTIES IMPORTED_LOCATION
${DIR}/libswresample.so)
add_library(swscale
SHARED
IMPORTED)
set_target_properties(
swscale
PROPERTIES IMPORTED_LOCATION
${DIR}/libswscale.so)
add_library(postproc
SHARED
IMPORTED)
set_target_properties(
postproc
PROPERTIES IMPORTED_LOCATION
${DIR}/libpostproc.so)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
nativec
avcodec
avfilter
avformat
avutil
swresample
swscale
postproc
# Links the target library to the log library
# included in the NDK.
${log-lib})
之后在 那个cpp文件中添加测试 函数
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_nativec_MainActivity_GetVersion(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from QMCY";
return env->NewStringUTF(avcodec_configuration());
}
java中添加声明:
public native String GetVersion();
然后放到实际的设备上就可以测试了
最后 有一个很重要的要注意的地方就是 我们编出来的so 是只能在真实设备上测试用的
如果我在电脑上运行的时候选择的不是真实的设备的话 会编译报错的 提示找不到ffmpeg的函数
运行的设备那里一定要选择真机设备。。。刚开始在在这困惑了许久