目前bilibili官方的ijkplayer播放器,是只适配Android和IOS系统的。而华为接下来即将发布纯harmony系统,是否有基于harmony系统的ijkplayer可以使用呢?
鸿蒙版ijkplayer播放器是哪个,如何使用,这个问题,大家可以参考我另一个技术号的文章先行了解一下:鸿蒙版ijkplayer播放器示例工程适配运行
不过上述提到的这个被鸿蒙化的ijkplayer播放器,里面的ffmpeg库是以已经编译好的ffmpeg的动态库集成进去的。对于需要修改ffmpeg代码的人来说,还需要知道如何编译适配harmony系统的ffmpeg库,从而来替代这个鸿蒙版ijkplayer中的ffmpeg库。
因此本文想要讲解的重点是,如何从之前的安卓版的ijkplayer仓库中,将ffmpeg编译出适配harmony系统的动态库。
一、基于openHarmony环境编译开源库
在本文主题正式开始之前,大家也可以通过我另一个技术号的这篇文章,需要先行了解一下如何基于openHarmony环境编译适配harmony系统的动态库:
二、编译前准备
编译之前,需要搭建的编译环境,需要下载的工具等。可以先大致参考之前安卓版本的编译环境,可从这篇文章中先行了解一下编译环境即可:ijkplayer编译流程详解
PS:其中与安卓相关的配置可以不用做。因为对应的是需要下载鸿蒙的编译工具链和文件系统等。
三、修改编译脚本
我们从上述二中的安卓版的ijkplayer仓库中,对主要编译脚本进行修改,来进行适配。
主要需要修改的就是android\contrib\tools下的三个脚本:do-compile-openssl.sh、do-compile-ffmpeg.sh和do-detect-env.sh。
在修改这3个脚本之前,根据"一"中文章所述,先提前下载好鸿蒙的交叉编译工具和文件系统,并在这3个脚本的编译前置脚本中(compile-openssl.sh和compile-ffmpeg.sh),将交叉工具链和文件系统的路径export出来,或者在全局环境变量/etc/profile配置文件export出来路径,如下:
bash
export OHOS_SYSROOT=/home/weekend/openharmony/ohos-sdk/linux/native/sysroot
export OHOS_LLVM=/home/weekend/openharmony/ohos-sdk/linux/native/llvm
OHOS_SYSROOT和OHOS_LLVM变量在后续的脚本中都是需要的。
1、修改do-detect-env.sh
do-detect-env.sh脚本主要用来检测编译环境的,在安卓版本中,会检查安卓sdk版本,ndk之类的。在鸿蒙版本中这些就都不需要了。我将这些都去掉。
然后增加鸿蒙的编译工具链和文件系统的检查,如下:
bash
if [ -z "$OHOS_LLVM" ]; then
echo "You must define OHOS_LLVM before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
if [ -z "$OHOS_SYSROOT" ]; then
echo "You must define OHOS_SYSROOT before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
实际上,我在3个脚本的开头处,都会对这个进行检查。
附上完整的修改后的 do-detect-env.sh:
bash
#! /usr/bin/env bash
#
#--------------------
set -e
UNAME_S=$(uname -s)
UNAME_SM=$(uname -sm)
echo "build on $UNAME_SM"
echo "OHOS_SYSROOT=$OHOS_SYSROOT"
echo "OHOS_LLVM=$OHOS_LLVM"
if [ -z "$OHOS_LLVM" ]; then
echo "You must define OHOS_LLVM before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
if [ -z "$OHOS_SYSROOT" ]; then
echo "You must define OHOS_SYSROOT before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
# try to detect NDK version
export IJK_GCC_VER=4.9
export IJK_GCC_64_VER=4.9
export IJK_MAKE_TOOLCHAIN_FLAGS=
export IJK_MAKE_FLAG=
case "$UNAME_S" in
Darwin)
export IJK_MAKE_FLAG=-j`sysctl -n machdep.cpu.thread_count`
;;
CYGWIN_NT-*)
IJK_WIN_TEMP="$(cygpath -am /tmp)"
export TEMPDIR=$IJK_WIN_TEMP/
echo "Cygwin temp prefix=$IJK_WIN_TEMP/"
;;
esac
2、修改do-compile-openssl.sh
do-compile-openssl.sh根据"二"中描述,主要是用于编译openssl的。根据上述"一"中的文章所述,主要是需要修改交叉编译工具链,和文件系统。
将安卓NDK和交叉编译工具链相关的去掉,FF_CROSS_PREFIX=aarch64-linux-android这个是安卓的交叉工具链头,用的gcc。修改为export CC 后面跟着鸿蒙的交叉工具链是llvm目录下的clang,然后target=aarch64-linux-ohos,指明是64位的。
bash
CLANG=$OHOS_LLVM/bin/clang
export CC="$CLANG $OHOS_CFLAGS"
export CFLAGS="$OHOS_CFLAGS --sysroot=${OHOS_SYSROOT}"
安卓的脚本中有FF_TOOLCHAIN_TOUCH,主要是安卓的ndk中提供的用于交叉编译的一些工具包。在鸿蒙的编译中,这一块就不需要了,直接去掉。就是下面这段是不需要了的:
bash
FF_MAKE_TOOLCHAIN_FLAGS=$IJK_MAKE_TOOLCHAIN_FLAGS
FF_MAKE_FLAGS=$IJK_MAKE_FLAG
FF_MAKE_TOOLCHAIN_FLAGS="$FF_MAKE_TOOLCHAIN_FLAGS --install-dir=$FF_TOOLCHAIN_PATH"
FF_TOOLCHAIN_TOUCH="$FF_TOOLCHAIN_PATH/touch"
if [ ! -f "$FF_TOOLCHAIN_TOUCH" ]; then
$ANDROID_NDK/build/tools/make-standalone-toolchain.sh \
$FF_MAKE_TOOLCHAIN_FLAGS \
--platform=$FF_ANDROID_PLATFORM \
--toolchain=$FF_TOOLCHAIN_NAME
touch $FF_TOOLCHAIN_TOUCH;
fi
只需要在后面编译的时候,指明CFLAGS=--sysroot=xxx,跟着鸿蒙的文件系统目录。
bash
export CFLAGS="$OHOS_CFLAGS --sysroot=${OHOS_SYSROOT}"
为了确保编译,可以将这些关键的编译相关的都export出来,如下:
bash
export CC="$CLANG $OHOS_CFLAGS"
export CXX="$CLANGXX $OHOS_CFLAGS"
export AR=${OHOS_AR}
export AS=${OHOS_AS}
export NM=${OHOS_NM}
export STRIP=${OHOS_STRIP}
export RANLIB=${OHOS_RANLIB}
export LD=${OHOS_LD}
export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld"
export CFLAGS="$OHOS_CFLAGS --sysroot=${OHOS_SYSROOT}"
附上完整的do-compile-openssl.sh供参考,我暂时只保留是arm的32位,64位和x86的64位这三个常用的cpu架构编译。具体如下:
bash
#! /usr/bin/env bash
#--------------------
set -e
if [ -z "$OHOS_LLVM" ]; then
echo "You must define OHOS_LLVM before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
if [ -z "$OHOS_SYSROOT" ]; then
echo "You must define OHOS_SYSROOT before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
#--------------------
# common defines
FF_ARCH=$1
if [ -z "$FF_ARCH" ]; then
echo "You must specific an architecture 'arm, armv7a, x86, ...'.\n"
exit 1
fi
FF_BUILD_ROOT=`pwd`
FF_BUILD_NAME=
FF_SOURCE=
FF_CROSS_PREFIX=
FF_CFG_FLAGS=
FF_PLATFORM_CFG_FLAGS=
FF_EXTRA_CFLAGS=
FF_EXTRA_LDFLAGS=
# compile
CLANG=$OHOS_LLVM/bin/clang
CLANGXX=$OHOS_LLVM/bin/clang++
OHOS_AR=$OHOS_LLVM/bin/llvm-ar
OHOS_AS=$OHOS_LLVM/bin/llvm-as
OHOS_NM=$OHOS_LLVM/bin/llvm-nm
OHOS_RANLIB=$OHOS_LLVM/bin/llvm-ranlib
OHOS_STRIP=$OHOS_LLVM/bin/llvm-strip
OBJDUMP=$OHOS_LLVM/bin/llvm-objdump
OHOS_LD=$OHOS_LLVM/bin/ld.lld
OHOS_LIBS="-L${OHOS_LLVM}/lib"
OHOS_INCS="-I${OHOS_LLVM}/include"
OHOS_CFLAGS=
#--------------------
echo ""
echo "--------------------"
echo "[*] do detect env"
echo "--------------------"
. ./tools/do-detect-env.sh
FF_MAKE_FLAGS=$IJK_MAKE_FLAG
#----- armv7a begin -----
if [ "$FF_ARCH" = "armv7a" ]; then
FF_BUILD_NAME=openssl-armv7a
FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME
FF_PLATFORM_CFG_FLAGS="linux-armv4"
OHOS_CFLAGS="--target=arm-linux-ohos -march=armv7-a"
elif [ "$FF_ARCH" = "arm64" ]; then
FF_BUILD_NAME=openssl-arm64
FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME
FF_PLATFORM_CFG_FLAGS="linux-aarch64"
OHOS_CFLAGS="--target=aarch64-linux-ohos"
elif [ "$FF_ARCH" = "x86_64" ]; then
FF_BUILD_NAME=openssl-x86_64
FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME
FF_PLATFORM_CFG_FLAGS="linux-x86_64"
OHOS_CFLAGS="--target=x86_64-linux-ohos"
else
echo "unknown architecture $FF_ARCH";
exit 1
fi
FF_SYSROOT=$OHOS_SYSROOT
FF_PREFIX=$FF_BUILD_ROOT/build/$FF_BUILD_NAME/output
mkdir -p $FF_PREFIX
# mkdir -p $FF_SYSROOT
#--------------------
echo ""
echo "--------------------"
echo "[*] check openssl env"
echo "--------------------"
export CC="$CLANG $OHOS_CFLAGS"
export CXX="$CLANGXX $OHOS_CFLAGS"
export AR=${OHOS_AR}
export AS=${OHOS_AS}
export NM=${OHOS_NM}
export STRIP=${OHOS_STRIP}
export RANLIB=${OHOS_RANLIB}
export LD=${OHOS_LD}
export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld"
export CFLAGS="$OHOS_CFLAGS --sysroot=${OHOS_SYSROOT}"
export COMMON_FF_CFG_FLAGS=
FF_CFG_FLAGS="$FF_CFG_FLAGS $COMMON_FF_CFG_FLAGS"
#--------------------
# Standard options:
FF_CFG_FLAGS="$FF_CFG_FLAGS zlib-dynamic"
FF_CFG_FLAGS="$FF_CFG_FLAGS no-asm"
FF_CFG_FLAGS="$FF_CFG_FLAGS no-shared"
FF_CFG_FLAGS="$FF_CFG_FLAGS -fPIC"
FF_CFG_FLAGS="$FF_CFG_FLAGS --openssldir=$FF_PREFIX"
FF_CFG_FLAGS="$FF_CFG_FLAGS $FF_PLATFORM_CFG_FLAGS"
#--------------------
echo ""
echo "--------------------"
echo "[*] configurate openssl"
echo "--------------------"
cd $FF_SOURCE
#if [ -f "./Makefile" ]; then
# echo 'reuse configure'
#else
echo "./Configure $FF_CFG_FLAGS"
./Configure $FF_CFG_FLAGS
#fi
#--------------------
echo ""
echo "--------------------"
echo "[*] compile openssl"
echo "--------------------"
make depend
make $FF_MAKE_FLAGS
make install_sw
#--------------------
echo ""
echo "--------------------"
echo "[*] link openssl"
echo "--------------------"
3、修改do-compile-ffmpeg.sh
这个脚本就是真正编译ffmpeg的了,与"2"中的openssl类似,主要是需要修改交叉编译工具链,和文件系统。
同样的与安卓相关的FF_TOOLCHAIN_TOUCH这一段可以去掉的:
bash
FF_TOOLCHAIN_TOUCH="$FF_TOOLCHAIN_PATH/touch"
if [ ! -f "$FF_TOOLCHAIN_TOUCH" ]; then
$ANDROID_NDK/build/tools/make-standalone-toolchain.sh \
$FF_MAKE_TOOLCHAIN_FLAGS \
--platform=$FF_ANDROID_PLATFORM \
--toolchain=$FF_TOOLCHAIN_NAME
touch $FF_TOOLCHAIN_TOUCH;
fi
将交叉编译工具链中提供的工具等,都export出来,这些可能有些不一定用到,但是export出来有利无害:
bash
CLANG=$OHOS_LLVM/bin/clang
CLANGXX=$OHOS_LLVM/bin/clang++
OHOS_AR=$OHOS_LLVM/bin/llvm-ar
OHOS_AS=$OHOS_LLVM/bin/llvm-as
OHOS_NM=$OHOS_LLVM/bin/llvm-nm
OHOS_RANLIB=$OHOS_LLVM/bin/llvm-ranlib
OHOS_STRIP=$OHOS_LLVM/bin/llvm-strip
OBJDUMP=$OHOS_LLVM/bin/llvm-objdump
OHOS_LD=$OHOS_LLVM/bin/ld.lld
OHOS_LIBS="-L${OHOS_LLVM}/lib"
OHOS_INCS="-I${OHOS_LLVM}/include"
同样的将安卓NDK和交叉编译工具链相关的去掉,以arm的64位为例,FF_CROSS_PREFIX=aarch64-linux-android这个是安卓的交叉工具链头,修改为export CC 后面跟着鸿蒙的交叉工具链是llvm目录下的clang,然后FF_EXTRA_CFLAGS和FF_EXTRA_LDFLAGS需要target=aarch64-linux-ohos,指明是64位的,如下:
bash
FF_EXTRA_CFLAGS="$FF_EXTRA_CFLAGS --target=x86_64-linux-ohos"
FF_EXTRA_LDFLAGS="$FF_EXTRA_LDFLAGS --target=x86_64-linux-ohos"
还需要将相关的系统所需头文件,lib库等指明,用于后续编译链接使用:
bash
OHOS_LIBS="$OHOS_LIBS -L${OHOS_SYSROOT}/usr/lib/aarch64-linux-ohos"
OHOS_INCS="$OHOS_INCS -I${OHOS_SYSROOT}/usr/include/aarch64-linux-ohos"
后续会用到CC、LD、AR、STRIP这些,需要都指明一下:
bash
export CC=${CLANG}
export LD=${OHOS_LD}
export AR=${OHOS_AR}
export STRIP=${OHOS_STRIP}
在ffmpeg的configure中,需要加上--cc,--ld,--strip,如下:
bash
if [ -f "./config.h" ]; then
echo 'reuse configure'
else
which $CC
./configure $FF_CFG_FLAGS \
--cc=${CLANG} \
--ld=${CLANG} \
--strip=${STRIP} \
--extra-cflags="$FF_CFLAGS $FF_EXTRA_CFLAGS" \
--extra-ldflags="$FF_DEP_LIBS $FF_EXTRA_LDFLAGS"
make clean
fi
然后在最后的CC编译链接成动态库中,需要将刚才的OHOS_LIBS和OHOS_INCS都加上,不然编译链接会报找不到一些系统的基本库之类。同时为了保持跟鸿蒙版ijkplayer中的ffmpeg库名字一致,将库名改为.z.so结尾。(这个貌似是无所谓的)。如下:
bash
$CC -lm -lz -shared --sysroot=$FF_SYSROOT -Wl,--no-undefined -Wl,-z,noexecstack $FF_EXTRA_LDFLAGS \
-Wl,-soname,libqfffmpeg.z.so \
$FF_C_OBJ_FILES \
$FF_ASM_OBJ_FILES \
$OHOS_LIBS \
$OHOS_INCS \
$FF_DEP_LIBS \
-o $FF_PREFIX/libqfffmpeg.z.so
另外在编译过程中发现--enable-asm和--enable-inline-asm打开的话,会编译不过,所以这2个改为disable的:
bash
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-asm"
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-inline-asm"
附上完整的do-compile-ffmpeg.sh供参考,我暂时只保留是arm的32位,64位和x86的64位这三个常用的cpu架构编译。具体如下:
bash
#! /usr/bin/env bash
#
#--------------------
echo "===================="
echo "[*] build ffmpeg and check env $1"
echo "===================="
set -e
#--------------------
# common defines
FF_ARCH=$1
FF_BUILD_OPT=$2
echo "FF_ARCH=$FF_ARCH"
echo "FF_BUILD_OPT=$FF_BUILD_OPT"
if [ -z "$FF_ARCH" ]; then
echo "You must specific an architecture 'arm, armv7a, x86, ...'."
echo ""
exit 1
fi
if [ -z "$OHOS_LLVM" ]; then
echo "You must define OHOS_LLVM before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
if [ -z "$OHOS_SYSROOT" ]; then
echo "You must define OHOS_SYSROOT before starting."
echo "sysroot and llvm is necessary.\n"
exit 1
fi
FF_BUILD_ROOT=`pwd`
FF_BUILD_NAME=
FF_SOURCE=
FF_CROSS_PREFIX=
FF_DEP_OPENSSL_INC=
FF_DEP_OPENSSL_LIB=
FF_DEP_LIBSOXR_INC=
FF_DEP_LIBSOXR_LIB=
FF_CFG_FLAGS=
FF_EXTRA_CFLAGS=
FF_EXTRA_LDFLAGS=
FF_DEP_LIBS=
FF_MODULE_DIRS="compat libavcodec libavfilter libavformat libavutil libswresample libswscale"
FF_ASSEMBLER_SUB_DIRS=
#--------------------
echo ""
echo "--------------------"
echo "[*] do detect env"
echo "--------------------"
. ./tools/do-detect-env.sh
FF_MAKE_FLAGS=$IJK_MAKE_FLAG
# compile
CLANG=$OHOS_LLVM/bin/clang
CLANGXX=$OHOS_LLVM/bin/clang++
OHOS_AR=$OHOS_LLVM/bin/llvm-ar
OHOS_AS=$OHOS_LLVM/bin/llvm-as
OHOS_NM=$OHOS_LLVM/bin/llvm-nm
OHOS_RANLIB=$OHOS_LLVM/bin/llvm-ranlib
OHOS_STRIP=$OHOS_LLVM/bin/llvm-strip
OBJDUMP=$OHOS_LLVM/bin/llvm-objdump
OHOS_LD=$OHOS_LLVM/bin/ld.lld
OHOS_LIBS="-L${OHOS_LLVM}/lib"
OHOS_INCS="-I${OHOS_LLVM}/include"
#----- armv7a begin -----
if [ "$FF_ARCH" = "armv7a" ]; then
FF_BUILD_NAME=ffmpeg-armv7a
FF_BUILD_NAME_OPENSSL=openssl-armv7a
FF_BUILD_NAME_LIBSOXR=libsoxr-armv7a
FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME
FF_CFG_FLAGS="$FF_CFG_FLAGS --arch=arm --cpu=cortex-a8"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-neon"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-thumb"
OHOS_LIBS="$OHOS_LIBS -L${OHOS_SYSROOT}/usr/lib/arm-linux-ohos"
OHOS_INCS="$OHOS_INCS -I${OHOS_SYSROOT}/usr/include/arm-linux-ohos"
FF_EXTRA_CFLAGS="$FF_EXTRA_CFLAGS -march=armv7-a -mcpu=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb --target=arm-linux-ohos"
FF_EXTRA_LDFLAGS="$FF_EXTRA_LDFLAGS -Wl,--fix-cortex-a8 --target=arm-linux-ohos"
FF_ASSEMBLER_SUB_DIRS="arm"
elif [ "$FF_ARCH" = "arm64" ]; then
FF_BUILD_NAME=ffmpeg-arm64
FF_BUILD_NAME_OPENSSL=openssl-arm64
FF_BUILD_NAME_LIBSOXR=libsoxr-arm64
FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME
FF_CFG_FLAGS="$FF_CFG_FLAGS --arch=aarch64 --enable-yasm"
OHOS_LIBS="$OHOS_LIBS -L${OHOS_SYSROOT}/usr/lib/aarch64-linux-ohos"
OHOS_INCS="$OHOS_INCS -I${OHOS_SYSROOT}/usr/include/aarch64-linux-ohos"
FF_EXTRA_CFLAGS="$FF_EXTRA_CFLAGS --target=aarch64-linux-ohos"
FF_EXTRA_LDFLAGS="$FF_EXTRA_LDFLAGS --target=aarch64-linux-ohos"
FF_ASSEMBLER_SUB_DIRS="aarch64 neon"
elif [ "$FF_ARCH" = "x86_64" ]; then
FF_BUILD_NAME=ffmpeg-x86_64
FF_BUILD_NAME_OPENSSL=openssl-x86_64
FF_BUILD_NAME_LIBSOXR=libsoxr-x86_64
FF_SOURCE=$FF_BUILD_ROOT/$FF_BUILD_NAME
FF_CFG_FLAGS="$FF_CFG_FLAGS --arch=x86_64 --enable-yasm"
OHOS_LIBS="$OHOS_LIBS -L${OHOS_SYSROOT}/usr/lib/x86_64-linux-ohos"
OHOS_INCS="$OHOS_INCS -I${OHOS_SYSROOT}/usr/include/x86_64-linux-ohos"
FF_EXTRA_CFLAGS="$FF_EXTRA_CFLAGS --target=x86_64-linux-ohos"
FF_EXTRA_LDFLAGS="$FF_EXTRA_LDFLAGS --target=x86_64-linux-ohos"
FF_ASSEMBLER_SUB_DIRS="x86"
else
echo "unknown architecture $FF_ARCH";
exit 1
fi
if [ ! -d $FF_SOURCE ]; then
echo ""
echo "!! ERROR"
echo "!! Can not find FFmpeg directory for $FF_BUILD_NAME"
echo "!! Run 'sh init-android.sh' first"
echo ""
exit 1
fi
FF_SYSROOT=$OHOS_SYSROOT
FF_PREFIX=$FF_BUILD_ROOT/build/$FF_BUILD_NAME/output
FF_DEP_OPENSSL_INC=$FF_BUILD_ROOT/build/$FF_BUILD_NAME_OPENSSL/output/include
FF_DEP_OPENSSL_LIB=$FF_BUILD_ROOT/build/$FF_BUILD_NAME_OPENSSL/output/lib
FF_DEP_LIBSOXR_INC=$FF_BUILD_ROOT/build/$FF_BUILD_NAME_LIBSOXR/output/include
FF_DEP_LIBSOXR_LIB=$FF_BUILD_ROOT/build/$FF_BUILD_NAME_LIBSOXR/output/lib
case "$UNAME_S" in
CYGWIN_NT-*)
FF_SYSROOT="$(cygpath -am $FF_SYSROOT)"
FF_PREFIX="$(cygpath -am $FF_PREFIX)"
;;
esac
mkdir -p $FF_PREFIX
# mkdir -p $FF_SYSROOT
#--------------------
echo ""
echo "--------------------"
echo "[*] check ffmpeg env"
echo "--------------------"
export CC=${CLANG}
export LD=${OHOS_LD}
export AR=${OHOS_AR}
export STRIP=${OHOS_STRIP}
FF_CFLAGS="-O3 -Wall -pipe \
-std=c99 \
-ffast-math \
-fstrict-aliasing -Werror=strict-aliasing \
-Wno-psabi -Wa,--noexecstack \
-DANDROID -DNDEBUG"
# cause av_strlcpy crash with gcc4.7, gcc4.8
# -fmodulo-sched -fmodulo-sched-allow-regmoves
# --enable-thumb is OK
#FF_CFLAGS="$FF_CFLAGS -mthumb"
# not necessary
#FF_CFLAGS="$FF_CFLAGS -finline-limit=300"
export COMMON_FF_CFG_FLAGS=
. $FF_BUILD_ROOT/config/module.sh
#--------------------
# with openssl
if [ -f "${FF_DEP_OPENSSL_LIB}/libssl.a" ]; then
echo "OpenSSL detected"
# FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-nonfree"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-openssl"
FF_CFLAGS="$FF_CFLAGS -I${FF_DEP_OPENSSL_INC}"
FF_DEP_LIBS="$FF_DEP_LIBS -L${FF_DEP_OPENSSL_LIB} -lssl -lcrypto"
fi
FF_CFG_FLAGS="$FF_CFG_FLAGS $COMMON_FF_CFG_FLAGS"
#--------------------
# Standard options:
FF_CFG_FLAGS="$FF_CFG_FLAGS --prefix=$FF_PREFIX"
# Advanced options (experts only):
FF_CFG_FLAGS="$FF_CFG_FLAGS "
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-cross-compile"
FF_CFG_FLAGS="$FF_CFG_FLAGS --target-os=linux"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-pic"
# FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-symver"
if [ "$FF_ARCH" = "x86" ]; then
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-asm"
else
# Optimization options (experts only):
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-asm"
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-inline-asm"
fi
case "$FF_BUILD_OPT" in
debug)
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-optimizations"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-debug"
FF_CFG_FLAGS="$FF_CFG_FLAGS --disable-small"
;;
*)
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-optimizations"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-debug"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-small"
;;
esac
#--------------------
echo ""
echo "--------------------"
echo "[*] configurate ffmpeg"
echo "--------------------"
cd $FF_SOURCE
if [ -f "./config.h" ]; then
echo 'reuse configure'
else
which $CC
./configure $FF_CFG_FLAGS \
--cc=${CLANG} \
--ld=${CLANG} \
--strip=${STRIP} \
--extra-cflags="$FF_CFLAGS $FF_EXTRA_CFLAGS" \
--extra-ldflags="$FF_DEP_LIBS $FF_EXTRA_LDFLAGS"
make clean
fi
#--------------------
echo ""
echo "--------------------"
echo "[*] compile ffmpeg"
echo "--------------------"
cp config.* $FF_PREFIX
make $FF_MAKE_FLAGS > /dev/null
make install
mkdir -p $FF_PREFIX/include/libffmpeg
cp -f config.h $FF_PREFIX/include/libffmpeg/config.h
#--------------------
echo ""
echo "--------------------"
echo "[*] link ffmpeg"
echo "--------------------"
echo $FF_EXTRA_LDFLAGS
FF_C_OBJ_FILES=
FF_ASM_OBJ_FILES=
for MODULE_DIR in $FF_MODULE_DIRS
do
C_OBJ_FILES="$MODULE_DIR/*.o"
if ls $C_OBJ_FILES 1> /dev/null 2>&1; then
echo "link $MODULE_DIR/*.o"
FF_C_OBJ_FILES="$FF_C_OBJ_FILES $C_OBJ_FILES"
fi
for ASM_SUB_DIR in $FF_ASSEMBLER_SUB_DIRS
do
ASM_OBJ_FILES="$MODULE_DIR/$ASM_SUB_DIR/*.o"
if ls $ASM_OBJ_FILES 1> /dev/null 2>&1; then
echo "link $MODULE_DIR/$ASM_SUB_DIR/*.o"
FF_ASM_OBJ_FILES="$FF_ASM_OBJ_FILES $ASM_OBJ_FILES"
fi
done
done
$CC -lm -lz -shared --sysroot=$FF_SYSROOT -Wl,--no-undefined -Wl,-z,noexecstack $FF_EXTRA_LDFLAGS \
-Wl,-soname,libqfffmpeg.z.so \
$FF_C_OBJ_FILES \
$FF_ASM_OBJ_FILES \
$OHOS_LIBS \
$OHOS_INCS \
$FF_DEP_LIBS \
-o $FF_PREFIX/libqfffmpeg.z.so
mysedi() {
f=$1
exp=$2
n=`basename $f`
cp $f /tmp/$n
sed $exp /tmp/$n > $f
rm /tmp/$n
}
echo ""
echo "--------------------"
echo "[*] create files for shared ffmpeg"
echo "--------------------"
rm -rf $FF_PREFIX/shared
mkdir -p $FF_PREFIX/shared/lib/pkgconfig
ln -s $FF_PREFIX/include $FF_PREFIX/shared/include
ln -s $FF_PREFIX/libqfffmpeg.z.so $FF_PREFIX/shared/lib/libqfffmpeg.z.so
cp $FF_PREFIX/lib/pkgconfig/*.pc $FF_PREFIX/shared/lib/pkgconfig
for f in $FF_PREFIX/lib/pkgconfig/*.pc; do
# in case empty dir
if [ ! -f $f ]; then
continue
fi
cp $f $FF_PREFIX/shared/lib/pkgconfig
f=$FF_PREFIX/shared/lib/pkgconfig/`basename $f`
# OSX sed doesn't have in-place(-i)
mysedi $f 's/\/output/\/output\/shared/g'
mysedi $f 's/-lavcodec/-lijkffmpeg/g'
mysedi $f 's/-lavfilter/-lijkffmpeg/g'
mysedi $f 's/-lavformat/-lijkffmpeg/g'
mysedi $f 's/-lavutil/-lijkffmpeg/g'
mysedi $f 's/-lswresample/-lijkffmpeg/g'
mysedi $f 's/-lswscale/-lijkffmpeg/g'
done
以上便是最关键的3个脚本的修改,按照上述修改后,便可编译适配纯harmony系统的ffmpeg库。大家可以将我上述附上的3个完整的脚本复制出来跟原本安卓版的脚本进行对比,可以更清晰地知道修改什么地方。
四、编译
修改脚本之后,便可跟安卓一样运行脚本编译。
先编译openssl:
bash
./compile-openssl.sh clean
./compile-openssl.sh all
然后编译ffmpeg:
bash
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
编译完成后,在contrib/build下会有对应cpu架构的ffmpeg和openssl产物文件夹。例如我编译arm64的:
在ffmpeg-arm64的output目录下,就有最终编译好的libqfffmpeg.z.so动态库:
亲测替换到鸿蒙版的ijkplayer中,可以正常运行。至此文章结束。