前言

这是一篇ExoPlayer添加Ffmeng扩展的记录博客,我下列出我使用到版本,避免不同版本造成的编译问题

  • ExoPlayer 2.18.1
  • android-ndk-r21e
  • JDK 11
  • AndroidStudio 2021.3.1.17

我的目的是想通过编译Ffmpeg使播放器支持更多解码格式

克隆ExoPlayer项目2.18.1版

创建项目文件夹(文件夹名字随意),或者放在你觉得合适的文件夹

mkdir Projects
cd Projects

克隆ExoPlayer项目

git clone https:///google/ExoPlayer.git

注意:路径或文件夹中不能带有空格或者特殊符号


Linux安装AndroidStudio

已安装或有Android编译环境,请跳过

为什么要安装AndroidStudio呢?因为我很少用到Linux编译,我没用过命令行工具去编译Android项目,使用我首先下载安装Linux版本的AndroidStudio,这样在我打开项目时它会自动帮我下载项目依赖,避免一些麻烦。

  1. 先准备好JDK,NDK,AndroidStudio 三个Linux的压缩包

下载android-ndk-r21e

wget -c https:///android/repository/android-ndk-r21e-linux-x86_64.zip

JDK11AndroidStudio 2021.3.1.17版 要去官网下载

  1. 新建一个Android文件夹,把三个压缩包复制或者下载到这个文件夹
  2. 分别把JDK和NDK,AndroidStudio 解压到Android文件夹下

注意:如果你使用的是WSL子系统,需要安装一些包来显示Linux应用程序,已经安装过的请忽略,如何使WSL子系统中应用程序显示在Windows上?需要使用SSH方式登录WSL子系统,我这边有写一篇WSL使用SSH连接的博客和WSL将Linux应用程序显示到Windows窗口中

启动AndroidStudio

cd <path to AdnroidStudio>
./studio.sh

第一次启动AndroidStudio的时候

AndroidStudio会询问你

  • 需不需要导入偏好设置,我是直接选择不导入
  • 需不需要设置代理,选择取消
  • 配置JDK路径,这个时候因为还没配置JDK环境变量你就直接选择刚刚存放JDK的文件路径就行了(待会儿再配置环境变量)

一直下一步,直到出现,需要你接受安装AndroidSDK协议时

这个时候把下载虚拟机选项勾选去掉(又不运行要什么虚拟机,浪费存储空间),其它就按照默认就行,下面选择 “接受” ,表示接受AndroidSDK使用协议,最后点“完成”,就安装完成了


初始化ExoPlayer项目

启动AndroidStudio,选择打开项目,找到刚刚克隆的ExoPlayer项目路径,打开项目,这个时候AndroidStudio会自动下载项目依赖库及相应的AndroidSDK,等AndroidStudio把依赖和AndroidSDK之后就直接关闭就行了


配置JDK和NDK环境变量

编辑profile文件

sudo vim /etc/profile

按键盘字母 ”I“ 键进入编辑模式,在文件内容最后添加:

export JAVA_HOME=你的JDK路径/jdk-11.0.16
export NDK_PATH=你的NDK路径/ndk21e
export CLASSPATH=.:${JAVA_HOME}/lib

export PATH=${JAVA_HOME}/bin:${NDK_PATH}:$PATH

添加完成之后,关闭命令行工具,重新打开,使用echo命令查看环境变量是否生效

echo $JDK_HOME
echo $NDK_PATH
echo $PATH

确认无误之后,就继续下面的步骤

注意:Linux下千万路径避免使用左斜线,根目录第一个文件夹必须带斜线,不然编译的时候就会出现找不到文件的问题


路径不要使用左斜线"\xxx\xxxx\xxxxx\xxx",而是应该使用右斜线/xxx/xxxx/xxxxx/xxx/
根目录不要第一个文件夹不带斜线”xxx/xxxx/xxxxx/xxx/“,而是"/xxx/xxxx/xxxxx/xxx/"


编译ffmpeg扩展

1. 使用命令到ExoPlayer项目根目录下,配置ffmpeg模块路径
cd "<path to project checkout>"
FFMPEG_MODULE_PATH="$(pwd)/extensions/ffmpeg/src/main"
2. 如果没有配置NDK环境变量,这里还需要配置NDK路径
NDK_PATH="<path to Android NDK>"
3. 设置主机平台(如果是Mac使用"darwin-x86_64" ),Linux使用 “linux-x86_64”:
HOST_PLATFORM="linux-x86_64"
4. 使用命令到 ExoPlayer项目下ffmpeg扩展的jni文件夹下,使用git命令克隆ffmpeg项目,克隆完之后打开进入ffmpeg文件夹,使用git命令切换到ffmpeg 4.2的分支,并配置ffmpeg项目路径
cd ./extensions/ffmpeg/src/main/jni

git clone git://source.ffmpeg.org/ffmpeg && \
cd ffmpeg && \
git checkout release/4.2 && \
FFMPEG_PATH="$(pwd)"
5. 配置你想扩展的解码格式,ffmpeg扩展支持格式
ENABLED_DECODERS=(vorbis opus flac)
6. 在 FFmpeg 模块 jni 目录中添加指向源代码的链接。
cd "${FFMPEG_MODULE_PATH}/jni" && \
ln -s "$FFMPEG_PATH" ffmpeg
7. 执行build_ffmpeg.sh,为 armeabi-v7a、arm64-v8a、x86 和 x86_64 构建 FFmpeg。如果需要针对不同的体系结构进行构建,则可以编辑该脚本:
cd "${FFMPEG_MODULE_PATH}/jni" && \
./build_ffmpeg.sh \
"${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ENABLED_DECODERS[@]}"

执行完成之后,ffmpeg项目下会多出一个android-libs,里面是一些平台的so文件

8. 最到ExoPlayer项目根目录,通过执行gradlew生成AAR文件
cd "<path to ExoPlayer project>"
./gradlew extension-ffmpeg:assembleRelease

在/ExoPlayer/extensions/ffmpeg/buildout/output/aar路径可以找到生成的AAR文件

使用Ffmpeg扩展

项目根目录-app模块下,新建lbs文件夹,放入AAR

android exoplay默认缓存模式_Android


在app模块下的build.gradle导入AAR包

implementation files('libs/extension-ffmpeg-release.aar')

创建FfmpegRenderersFactory类

class FfmpegRenderersFactory(context: Context) : DefaultRenderersFactory(context) {

    init {
        setExtensionRendererMode(EXTENSION_RENDERER_MODE_PREFER)
    }
    
    override fun buildAudioRenderers(
        context: Context,
        extensionRendererMode: Int,
        mediaCodecSelector: MediaCodecSelector,
        enableDecoderFallback: Boolean,
        audioSink: AudioSink,
        eventHandler: Handler,
        eventListener: AudioRendererEventListener,
        out: ArrayList<Renderer>
    ) {
        super.buildAudioRenderers(
            context,
            extensionRendererMode,
            mediaCodecSelector,
            enableDecoderFallback,
            audioSink,
            eventHandler,
            eventListener,
            out
        )
        out.add(FfmpegAudioRenderer())
    }
}

实例化播放器,这样就能正常使用Ffmpeg软解码啦!

val renderersFactory = FfmpegRenderersFactory(service)
 val currentPlayer = ExoPlayer.Builder(service, renderersFactory)

如果你在编译中遇到问题可在下方留言,到此为止吧。

参考:https:///google/ExoPlayer/tree/release-v2/extensions/ffmpeg 参考: