Mac编译ExoPlayer的ffmpeg拓展库

1,458 阅读2分钟

英文好的同学可以看官方文档

ExoPlayer的项目下有一个extensions/ffmpeg目录,其中包含了音频解码的相关内容,可以编译相关的拓展库以解码系统所不支持的音频编码

1.编写shell脚本,保存为build_ffmpeg.sh

FFMPEG_EXT_PATH=/Users/sansecy/ExoPlayer/extensions/ffmpeg/src/main
NDK_PATH=/Users/sansecy/Library/Android/sdk/ndk/21.0.6113669
HOST_PLATFORM=darwin-x86_64
ENABLED_DECODERS=(vorbis opus flac mp3 aac ac3 eac3 dca)
JOBS=$(nproc 2> /dev/null || sysctl -n hw.ncpu 2> /dev/null || echo 4)
echo "Using $JOBS jobs for make"
COMMON_OPTIONS="
    --target-os=android
    --enable-static
    --disable-shared
    --disable-doc
    --disable-programs
    --disable-everything
    --disable-avdevice
    --disable-avformat
    --disable-swscale
    --disable-postproc
    --disable-avfilter
    --disable-symver
    --disable-avresample
    --enable-swresample
    --extra-ldexeflags=-pie
    "
TOOLCHAIN_PREFIX="${NDK_PATH}/toolchains/llvm/prebuilt/${HOST_PLATFORM}/bin"

for decoder in "${ENABLED_DECODERS[@]}"
do
        COMMON_OPTIONS="${COMMON_OPTIONS} --enable-decoder=${decoder}"
done
echo $COMMON_OPTIONS

make clean
./configure \
   --libdir=android-libs/armeabi-v7a \
   --arch=arm \
   --cpu=armv7-a \
   --cross-prefix="${TOOLCHAIN_PREFIX}/armv7a-linux-androideabi16-" \
   --nm="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-nm" \
   --ar="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-ar" \
   --ranlib="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-ranlib" \
   --strip="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-strip" \
   --extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
   --extra-ldflags="-Wl,--fix-cortex-a8" \
   ${COMMON_OPTIONS}
make -j$JOBS
make install-libs
make clean
./configure \
    --libdir=android-libs/arm64-v8a \
    --arch=aarch64 \
    --cpu=armv8-a \
    --cross-prefix="${TOOLCHAIN_PREFIX}/aarch64-linux-android21-" \
    --nm="${TOOLCHAIN_PREFIX}/aarch64-linux-android-nm" \
    --ar="${TOOLCHAIN_PREFIX}/aarch64-linux-android-ar" \
    --ranlib="${TOOLCHAIN_PREFIX}/aarch64-linux-android-ranlib" \
    --strip="${TOOLCHAIN_PREFIX}/aarch64-linux-android-strip" \
    ${COMMON_OPTIONS}
make -j$JOBS
make install-libs
make clean
./configure \
   --libdir=android-libs/x86 \
   --arch=x86 \
   --cpu=i686 \
   --cross-prefix="${TOOLCHAIN_PREFIX}/i686-linux-android16-" \
   --nm="${TOOLCHAIN_PREFIX}/i686-linux-android-nm" \
   --ar="${TOOLCHAIN_PREFIX}/i686-linux-android-ar" \
   --ranlib="${TOOLCHAIN_PREFIX}/i686-linux-android-ranlib" \
   --strip="${TOOLCHAIN_PREFIX}/i686-linux-android-strip" \
   --disable-asm \
   ${COMMON_OPTIONS}
make -j$JOBS
make install-libs
make clean
./configure \
   --libdir=android-libs/x86_64 \
   --arch=x86_64 \
   --cpu=x86_64 \
   --cross-prefix="${TOOLCHAIN_PREFIX}/x86_64-linux-android21-" \
   --nm="${TOOLCHAIN_PREFIX}/x86_64-linux-android-nm" \
   --ar="${TOOLCHAIN_PREFIX}/x86_64-linux-android-ar" \
   --ranlib="${TOOLCHAIN_PREFIX}/x86_64-linux-android-ranlib" \
   --strip="${TOOLCHAIN_PREFIX}/x86_64-linux-android-strip" \
   --disable-asm \
   ${COMMON_OPTIONS}
make -j$JOBS
make install-libs
make clean

以下是需要作的修改

  • 修改FFMPEG_EXT_PATH为项目ffmpeg模块的目录
  • 修改NDK_PATH为NDK路径
  • 修改HOST_PLATFORM为系统的类型,Mac为darwin-x86_64
  • 修改ENABLED_DECODERS为你需要的编码格式

2.下载ffmpeg库
官方推荐ffmpeg4.2

git clone git://source.ffmpeg.org/ffmpeg
cd ffmpeg
git checkout release/4.2

3.复制build_ffmepg.sh到ffmpeg仓库目录
4.执行脚本./build_ffmpeg.sh,生成android-libs目录,其中包含各个abi的.a后缀文件
5.为ffmpeg仓库文件夹创建快捷方式到ExoPlayer的ffmpeg拓展库模块的jni目录下

例如

cd /Users/sansecy/ExoPlayer/extensions/ffmpeg/src/main/jni
ln -s /Users/sansecy/Downloads/ffmpeg ffmpeg #创建快捷方式为ffmpeg

image.png 6.打开侧边栏的gradle任务列表,在extension-ffmpeg->Task->other中找到assembleRelease,双击执行,即可在extensions->ffmpeg->buildout->outputs->aar->extension-ffmpeg-release.aar找到生成的aar

image.png 双击aar在窗口中查看包含的so库

image.png

7.使用
设置DefaultRenderersFactory的拓展渲染模式为DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER

player = new SimpleExoPlayer.Builder(context, ExoPlayerUtil.buildRenderersFactory(context))
        .setTrackSelector(mTrackSelector)
        .setMediaSourceFactory(mMediaSourceFactory)
        .build();

public class ExoPlayerUtil {
    public static RenderersFactory buildRenderersFactory(
            Context context) {
        return new DefaultRenderersFactory(context.getApplicationContext())
                .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER);
    }
}

7.为ExoPlayer添加日志验证ffmpeg音频渲染

player.addAnalyticsListener(new EventLogger(mTrackSelector));

image.png 如图所示,ExoPlayer使用FfmpegAudioRenderer进行音频渲染,而不是系统的MediaCodecAudioRenderer