一.FFmpeg简介
- 这里对FFmpeg只做个最简单的简介。
- Ffmpeg是一个音视频处理的库。在使用MediaCodeC进行编码的时候,大量的手机是不支持B帧的编码。根据手机的官方的一些文档,小米10,高通655、885这些芯片是支持B帧的编码。一般的手机不支持B帧的编码,所以,如果要对视频进行压缩的话,最好是CPU通过使用FFmpeg来做。
- FFmpeg用来做播放的话性能还是可以的但是用来做编码,会时不时的发热一下。
二.FFmpeg编译
- Linux环境即可(NDK和Ffmpeg版本最好统一)
1.环境
- Linxu系统(阿里云服务)
2.下载资源
- 使用xshell链接云服务器
- Android DNK官网
- Ffmpeg官网
- 版本千万不要下错了
- 命令(这种是错误的,千万不要使用,被坑的很惨):wget http://ffmpeg.org/releases/ffmpeg-4.4.tar.xz
- 命令(正确的方式):wget https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
- 下载后的内容如下
- 解压操作,解压zip文件和tar.gz文件,需要安装zip命令,云服务安装zip命令为:yum install unzip
- 在opt文件夹中,执行命令:unzip android-ndk-r23-linux.zip和tar -xvf ffmpeg-4.4.tar.xz,解压后的目录如下
3.配置NDK环境变量
-
NDK是有多个位置可以配置环境变量的,我们选择修改~/.bashrc即可
-
执行命令:vim ~/.bashrc,添加如下信息(添加完成通过wq进行保存,需要对vim有一点点了解):
# 在文件末尾添加 ndk环境变量(/root/opt/android-ndk-r23根据pwd命令查看)
export NDKROOT=/root/opt/android-ndk-r23
export PATH=$NDKROOT:$PATH
- 执行命令:source ~/.bashrc
- 接着通过ndk-build检测环境变量是否配置成功
[root@izwz9d72bh8t54kkfk5m0mz ~]# ndk-build
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
/root/opt/android-ndk-r23/build/core/build-local.mk:151: *** Android NDK: Aborting . Stop.
4.修改configure文件
- configure位于/root/opt/ffmpeg-4.4中,将文件复制下来,再修改,然后替换
- 由于编译出来的动态库文件名的版本号在.so之后(例如“libavcodec.so.5.100.1”),而Android平台不能识别这样的文件名,所以需要修改这种文件名。
- 修改的信息如下
- configure的文件内容比较多,通过notepad++搜索# build settings,大概是3000多行的位置
# 将ffmpeg-4.4目录中configure文件中的:
#SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
#LIB_INSTALL_EXTRA_CMD='$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' #4.3.1这里会有点区别
#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)'
5.编写编译脚本
- 如取名为build_android.sh,将一下内容复制进去即可,将文件放到ffmpeg-4.4目录中
- 注意
- ndk版本是23,20-23好像都可以公用,自行去验证路径即可确定
- 一共可以编译4个平台的,需要编译几个平台,自行设置。
- 注意
#!/bin/bash
NDK=/root/opt/android-ndk-r23
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
API=29
function build_android
{
echo "Compiling FFmpeg for $CPU"
./configure \
#设置安装路径
--prefix=$PREFIX \
--disable-neon \
--disable-hwaccels \
--disable-gpl \
--disable-postproc \
--enable-shared \
--enable-jni \
--disable-mediacodec \
--disable-decoder=h264_mediacodec \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$CROSS_PREFIX \
#要编译的目标系统是Android
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
#配置c编译器
--cc=$CC
--cxx=$CXX
#允许是一个交叉编译
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
echo "The Compilation of FFmpeg for $CPU is completed"
}
#armv8-a
ARCH=arm64
CPU=armv8-a
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"
build_android
#armv7-a
#ARCH=arm
#CPU=armv7-a
#CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
#CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
#SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
#CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
#PREFIX=$(pwd)/android/$CPU
#OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
#build_android
#x86
#ARCH=x86
#CPU=x86
#CC=$TOOLCHAIN/bin/i686-linux-android$API-clang
#CXX=$TOOLCHAIN/bin/i686-linux-android$API-clang++
#SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
#CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android-
#PREFIX=$(pwd)/android/$CPU
#OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
#build_android
#x86_64
#ARCH=x86_64
#CPU=x86-64
#CC=$TOOLCHAIN/bin/x86_64-linux-android$API-clang
#CXX=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++
#SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
#CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android-
#PREFIX=$(pwd)/android/$CPU
#OPTIMIZE_CFLAGS="-march=$CPU -msse4.2 -mpopcnt -m64 -mtune=intel"
#build_android
- 设置编译脚本的权限
- 命令:chmod 777 build_android.sh
6.测试交叉编译效果
- 执行命令:./build_android.sh
6.1.出现报错
nasm/yasm not found or too old. Use --disable-x86asm for a crippled build
-
处理方式
- 需要安装yasm的汇编编译器,执行命令:yum install yasm -y,然后重新执行编译脚本
-
编译成功,但是有点不理想,没有生成在指定的文件夹,这一次我使用Ubuntn虚拟机来重新操作。
-
Ubuntu编译更不理想,直接报错。重新尝试降低ndk和ffmpeg的版本;
6.2.换种方式
- 被折腾的有点惨
- 重新下载ffmpeg,使用git命令:git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
- 按照上面重新再来,编译成功;
6.3.补充细节
-
在linux虚拟机上最终是成功编译的,但是云服务器还不确定
-
通过命令:wget https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2,下载的文件需要解压,使用命令:tar -jxvpf ffmpeg-snapshot.tar.bz2,提示报错:
tar (child): lbzip2: Cannot exec: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
- 处理办法,使用命令:yum -y install bzip2,继续操作命令:tar -jxvpf ffmpeg-snapshot.tar.bz2,解压成功;
6.4.可能的报错
-
-bash: ./build.sh: /bin/bash^M: 解释器错误: 没有那个文件或目录
-
nasm/yasm not found or too old. Use --disable-x86asm for a crippled build
- 如果通过命令安装的方式不能成功,就手动的方式进行安装,下载安装包,解压,执行三个命令,执行完后再返回到ffmpeg目录下继续执行./build_android.sh
//进入解压后的目录执行
./configure
make
make install
三.总结
- 按照上面的操作来,注意下细节,会比较顺利。
评论区