Android开发之编译FFMPEG为动态库

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec

接下来介绍一下分别在Windows和Linux下编译出android需要的动态库文件

一、windows下编译

1、准备工具

MinGW

Android NDK r14b windows 64版本

FFmpeg 3.3.8版本

2、安装MinGW

安装MinGW比较简单,只需一步一步下去即可,如果中间出现安装失败等原因,重新安装即可。

安装完成以后打开MinGW Installation Manager界面,选择左侧的“Basic Setup”,然后选择右侧的“mingw32-gcc-data”,“msys-base”进行安装。

安装过程中可能会出现有些文件下载失败的情况,此时不用管它,等其他的安装完成后,点击叉按钮关闭时会出现提醒,此时再按照提示继续安装,直到文件全部安装完毕,MinGW Installation Manager界面会自动退出。

等到安装结束后需要配置系统环境变量,MinGW默认安装C盘根目录如:C:\MinGW。将C:\MinGW\bin配置到环境变量的Path中。一切弄完后进入到C:\MinGW\msys\1.0 双击msys.bat启动,可能会稍微需要等一会儿

3、 编写脚本文件

将下载的NDK和FFmpeg解压到文件夹下如:D:\testFFmpeg下。之后打开D:\testFFmpeg\ffmpeg-3.3.8文件夹

<1> 修改FFmpeg的configure文件内容

	    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)'

<2> 新建一个ffmpegTemp的空文件夹(不知道有什么用,但必须有)

<3> 新建一个build_android.sh的文件,内容如下:

		#!/bin/bash 
        export TMPDIR=D:/testFFmpeg/ffmpeg-3.3.8/ffmpegTemp
        NDK=D:/testFFmpeg/android-ndk-r14b
        SYSROOT=$NDK/platforms/android-19/arch-arm/
        TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64
        function build_one { 
            ./configure \
            --prefix=$PREFIX \
            --enable-shared \
            --disable-static \
            --disable-doc \
            --disable-ffmpeg \
            --disable-ffplay \
            --disable-ffprobe \
            --disable-ffserver \
            --disable-avdevice \
            --disable-doc \
            --disable-symver \
            --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
            --target-os=linux \
            --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=arm
        PREFIX=$(pwd)/android/$CPU
        ADDI_CFLAGS="-marm" 
        build_one

4、 编译脚本

启动MinGW中的C:\MinGW\msys\1.0\msys.bat批处理文件(需要等会儿),切换(cd)到D:\testFFmpeg\ffmpeg-3.3.8文件夹下。输入命令:

chmod +x build_android.sh (授予权限)
	          
./build_android.sh(编译文件。途中会有一些warning,和deprecated api,但不会影响结果)

编译完成后会在D:\testFFmpeg\ffmpeg-3.3.8文件夹下生成一个android的文件夹,打开D:\testFFmpeg\ffmpeg-3.3.8\android\arm可以看到。里面包含include和lib两个文件夹。include中包含是一些头文件,lib中包含是一些so文件。

二、Linux下编译

1、准备工具

Android NDK r14b Linux 64版本

FFmpeg 3.3.8版本

虚拟机virtualBox

Linux系统Ubuntu桌面版

2、安装virtualBox

安装virtualBox比较简单,只需一步一步下去即可。

安装完成后点击新建,创建一个Linux 64位的虚拟电脑,一步一步即可。

有些电脑没有64位的选项,是因为没有开启硬件虚拟化,这时就需要重启进入到BIOS设置界面,找到Intel ® Virtualization Technology设置为enable即可。

创建成功后启动该虚拟电脑,会让选择安装系统选择之前下载好的Ubuntu桌面版ios文件即可进行系统安装。

系统安装成功后有时候需要虚拟机和主机之前进行文件的复制黏贴,操作如下:

<1> 找到菜单栏的“设备”。点击打开看到“共享文件夹”、“共享粘贴板”、“拖放”。将“共享粘贴板”、“拖放”设置为双向, “共享文件夹”打开右边有一个添加的按钮,打开会让选择共享文件夹路径,选择一个比如: D:\share,然后将自动挂载和固定分配选上。

<2> 在菜单栏“设备”下会有一个"安装增强功能",选择安装

<3> 安装完成之后右键打开终端,输入命令:sudo mount -t vboxsf share(就是上面设置的共享文件夹) /home/cheng(虚拟电脑名称)/sharefile(自己创建的文件夹名称),回车。

这样就可以实现主机中的D:\share文件夹中和/home/cheng/sharefile文件夹中的文件相互可见,并可复制黏贴。

3、 编写脚本文件

将下载的NDK和FFmpeg通过虚拟机的共享文件夹的形式,copy到虚拟机的/home/cheng/ffmpeg文件夹下,并解压

<1> 修改FFmpeg的configure文件内容

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)'

<2> 新建一个build_android.sh的文件,内容如下:

		#!/bin/bash
        #填写你具体的ndk解压目录
        export NDK=/home/cheng/ffmpeg/android-ndk-r14b
        export SYSROOT=$NDK/platforms/android-19/arch-arm/
        export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
        export CPU=arm
        #编译后的文件会放置在 当前路径下的android/arm/下
        export PREFIX=$(pwd)/android/$CPU
        export ADDI_CFLAGS="-marm"

        #./configure 即为ffmpeg 根目录下的可执行文件configure
        #你可以在ffmpeg根目录下使用./configure --hellp 查看 ./configure后可填入的参数。

        ./configure --target-os=linux \
        --prefix=$PREFIX --arch=arm \
        --disable-doc \
        --enable-shared \
        --disable-static \
        --disable-yasm \
        --disable-symver \
        --enable-gpl \
        --disable-ffmpeg \
        --disable-ffplay \
        --disable-ffprobe \
        --disable-ffserver \
        --disable-doc \
        --disable-symver \
        --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
        --enable-cross-compile \
        --sysroot=$SYSROOT \
        --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
        --extra-ldflags="$ADDI_CFLAGS" \
        $ADDITIONAL_CONFIGURE_FLAG

4、 编译脚本

右键打开终端,切换(cd)到/home/cheng/ffmpeg/ffmpeg-3.3.8文件夹下

	输入命令:chmod +x build_android.sh (授予权限)
	          
			  ./build_android.sh(编译文件。途中会有warning,不影响)
			  
			  make clean
			  
			  make
			  
			  make install
			  
			  编译会需要一些时间

编译完成后会在/home/cheng/ffmpeg/ffmpeg-3.3.8文件夹下生成一个android的文件夹。里面包含include和lib两个文件夹。include中包含是一些头文件,lib中包含是一些so文件。将android文件夹压缩打包copy到/home/cheng/sharefile文件夹中,在D:\share文件夹中就可以看到并copy到其他地方。

那么到这儿,在Windows和Linux下编译FFmpeg动态库就完成了。但是要使用到 Android 项目中,还需要 jni

三、使用

1、新建一个Android Studio项目,勾选Include C++ support复选框。

   将so文件和头文件放在libs目录下。
   
   在libs新建一个平台名字文件夹将so文件放入,比如libs/arm64-v8a下。将头文件include文件夹直接放在libs下即可。

2、编写CMakeLists.txt脚本

   #设置CMake最小版本号
   cmake_minimum_required(VERSION 3.4.1)
   #设置最后生成so文件路径
   set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
   #添加c源文件
   add_library( # Sets the name of the library.
         native-lib

         # Sets the library as a shared library.
         SHARED

         # Provides a relative path to your source file(s).
         src/main/cpp/native-lib.cpp 
    )

    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 
    )

    #定义变量distribution_DIR
    set(distribution_DIR ../../../../libs)

	#添加FFmpeg动态库文件
    add_library( avcodec-57
                 SHARED
                 IMPORTED)
    set_target_properties( avcodec-57
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/arm64-v8a/libavcodec-57.so)
    
    add_library( avfilter-6
                 SHARED
                 IMPORTED)
    set_target_properties( avfilter-6
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/arm64-v8a/libavfilter-6.so)
    
    add_library( avformat-57
                 SHARED
                 IMPORTED)
    set_target_properties( avformat-57
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/arm64-v8a/libavformat-57.so)
    
    add_library( avutil-55
                 SHARED
                 IMPORTED)
    set_target_properties( avutil-55
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/arm64-v8a/libavutil-55.so)
    
    add_library( swresample-2
                 SHARED
                 IMPORTED)
    set_target_properties( swresample-2
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/arm64-v8a/libswresample-2.so)
    
    add_library( swscale-4
                 SHARED
                 IMPORTED)
    set_target_properties( swscale-4
                           PROPERTIES IMPORTED_LOCATION
                           ${distribution_DIR}/arm64-v8a/libswscale-4.so)
    
    #设置FFmpeg头文件路径
    include_directories(libs/include)
    #链接库文件
    target_link_libraries( # Specifies the target library.
                           native-lib
                           avcodec-57
                           avfilter-6
                           avformat-57
                           avutil-55
                           swresample-2
                           swscale-4
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} 
    )

3、在app/build.gradle文件中添加

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
	
	如果是针对单平台CPU的库文件,还需要添加:
	
	ndk {
            abiFilters "arm64-v8a"
        }

4、编写C++代码native-lib.cpp

    //引入FFmpeg头文件
    extern "C" {
        //编码
        #include "libavcodec/avcodec.h"
        //封装格式处理
        #include "libavformat/avformat.h"
        //像素处理
        #include "libswscale/swscale.h"

        #include "libavfilter/avfilter.h"

    }
	
	extern "C"

	//循环输出AVInputFormat、AVOutputFormat信息到info中,并将信息返回
    JNIEXPORT jstring JNICALL Java_com_test_chinamobile_MainActivity_avformatinfo
        (JNIEnv *env, jobject obj)
    {
        char info[40000] = { 0 };

        av_register_all();
        
        AVInputFormat *if_temp = av_iformat_next(NULL);
        AVOutputFormat *of_temp = av_oformat_next(NULL);
        //Input
        while(if_temp!=NULL){
            sprintf(info, "%s[In ][%10s]\n", info, if_temp->name);
            if_temp=if_temp->next;
        }
        //Output
        while (of_temp != NULL){
            sprintf(info, "%s[Out][%10s]\n", info, of_temp->name);
            of_temp = of_temp->next;
        }
        //LOGE("%s", info);
        return env->NewStringUTF(info);

    }

5、调用C++代码

	//注册动态代码库
    static {
        System.loadLibrary("native-lib");
        System.loadLibrary("avcodec-57");
        System.loadLibrary("avfilter-6");
        System.loadLibrary("avformat-57");
        System.loadLibrary("avutil-55");
        System.loadLibrary("swresample-2");
        System.loadLibrary("swscale-4");
    }
	
	//声明一个本地方法
	public native String avformatinfo();
	
	//调用显示返回的信息
	textView.setText(avformatinfo());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Windows下编译FFmpeg动态库用于Android,可以按照以下步骤进行操作: 1. 下载ndk-bundle并解压。ndk-bundle是一个Android NDK开发包,包含了交叉编译FFmpeg所需的工具和库文件。 2. 下载FFmpeg源代码,并解压到您的计算机上。 3. 打开命令行窗口,进入FFmpeg源代码的根目录,运行以下命令: ``` ./configure --enable-shared --disable-static --disable-doc --disable-programs --enable-pic --disable-avdevice --disable-swresample --disable-postproc --disable-avfilter --disable-network --disable-iconv --disable-bzlib --disable-zlib --disable-encoders --disable-muxers --disable-protocols --disable-indevs --disable-outdevs --disable-filters --disable-bsfs --disable-devices --disable-parsers --disable-decoders --arch=arm --target-os=android --enable-cross-compile --sysroot=%NDK_HOME%/platforms/android-%API_VERSION%/arch-arm --cc=%NDK_HOME%/toolchains/arm-linux-androideabi-%TOOLCHAIN_VERSION%/prebuilt/windows-x86_64/bin/arm-linux-androideabi-gcc --cross-prefix=%NDK_HOME%/toolchains/arm-linux-androideabi-%TOOLCHAIN_VERSION%/prebuilt/windows-x86_64/bin/arm-linux-androideabi- --prefix=%FFMPEG_BUILD_PATH%/armeabi-v7a ``` 其中,%NDK_HOME%是您解压的ndk-bundle的路径,%API_VERSION%是您要支持的Android API版本,%TOOLCHAIN_VERSION%是您要使用的NDK编译工具链版本,%FFMPEG_BUILD_PATH%是您要生成的FFmpeg库的路径。 4. 运行make命令,等待编译完成。生成的库文件位于%FFMPEG_BUILD_PATH%/armeabi-v7a/lib目录下。 5. 将生成的库文件复制到您的Android项目的libs目录下。 6. 在您的Android项目中,使用System.loadLibrary()加载FFmpeg库。 需要注意的是,编译FFmpeg需要一定的编译知识和经验。如果您不熟悉编译过程,建议先阅读相关文档或寻求专业人士的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值