有时候Exoplayer自带的解码器不支持一些特殊的格式或者编码,此时我们可以通过给Exoplayer添加Ffmpeg扩展实现软解来支持这些编码。

  1. 系统:Ubuntu 20.04.3 LTS。
  2. Exoplayer源码:r2.18.1版本。
  3. NDK环境版本:NDK r21。
  4. Cmaker版本:3.23.3。
  5. Ffmpeg版本:4.2.2。

安装好编译环境

  1. 下载 AndroidSdk 并配置好环境,本文用的SDK版本为30。
  2. 下载 Exoplayer 2.18.1版本源码。
  3. 下载 NDK r21 ,配置好环境。
  4. 下载 CMake 3.23.3版本,配置好环境。
  5. 下载 ffmpeg 4.2.2版本,配置好环境。

二.编译FFmpeg源码

  1. 设置变量名为FFMPEG_MODULE_PATH的 shell 变量:
cd "Exoplayer工程目录"
FFMPEG_MODULE_PATH="$(pwd)/extensions/ffmpeg/src/main"
  1. 设置变量名为NDK_PATH的 shell 变量:
NDK_PATH="NDK的安装目录"
  1. 设置主机平台变量(Linux 使用linux-x86_64 对于Mac OS X 使用 darwin-x86_64 ):
HOST_PLATFORM="linux-x86_64"
  1. 设置FFMPEG_PATH的Shell变量:
cd "Ffmpeg工程目录"
FFMPEG_PATH="$(pwd)"
  1. 现在添加解码器,可以使用命令中的空格添加多个解码器。例如,我们现在将添加3个解码器:mp3,aac和ac3:
ENABLED_DECODERS=(mp3 aac ac3)
 

有关可用解码器的详细信息以及它们支持的格式,请参阅支持的格式页面

  1. 在 FFmpeg 模块目录中添加指向 FFmpeg 源代码的链接:
cd "${FFMPEG_MODULE_PATH}/jni" && \
ln -s "$FFMPEG_PATH" ffmpeg

如果报错file exists可以使用如下命令:

cd "${FFMPEG_MODULE_PATH}/jni" && \
ln -sf "$FFMPEG_PATH" ffmpeg
  1. 使用Ndk编译FFmpeg源码:
cd "${FFMPEG_MODULE_PATH}/jni" && \
./build_ffmpeg.sh \
  "${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ENABLED_DECODERS[@]}"
 

如果您需要为不同的体系结构构建脚本或者配置ffmpeg编译参数,则可以编辑构建脚本文件:build_ffmpeg.sh脚本,默认支持armeabi-v7a,arm64-v8a,x86,x86_64

  1. 等待build_ffmpeg.sh编译脚本,结束,可以在ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg目录下面生成了android-libs目录。

三.交叉编译JNI接口

在完成上述步骤以后,我们编译好的源码并不能直接在Android系统上使用,因为还未进行过交叉编译。

  1. 使用如下命令交叉编译并生成 aar 文件:
cd "Exoplayer工程目录"
./gradlew extension-ffmpeg:assembleRelease
  1. 生成成功后,可以在 ffmpeg 生成文件夹中获取 aar 并将其导入到项目中。
/ExoPlayer/extensions/ffmpeg/buildout/output/aar

使用 gradle 将 aar 库导入到项目中。

四.在自己的项目中使用编译好的aar

  1. 依赖之前编译好的aar:
implementation files('libs/extension-ffmpeg-release.aar')
  1. 新建FfmpegRenderersFactory,并打开这个扩展:
class FfmpegRenderersFactory extends DefaultRenderersFactory {
    public FfmpegRenderersFactory(Context context) {
        super(context);
        setExtensionRendererMode(EXTENSION_RENDERER_MODE_PREFER);
    @Override
    protected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {
        out.add(new FfmpegAudioRenderer());
        super.buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, eventListener, out);
  1. 播放器实例化:
ExoPlayer.Builder(MyApp.instance.applicationContext,new FfmpegRenderersFactory())
  1. 播放链接:
val url = ""
val mediaItem: MediaItem = MediaItem.fromUri(url)
player.setMediaItem(mediaItem)
player.prepare()
player.play()
				
ExoPlayer播放器不支持MP2音频格式,在播放视频为MP2音频格式的视频时,在华为悦盒E6108C系列的盒子上没有声音,为解决问题添加ExoPlayer扩展ffmpeg软解码库,历时4天终于完成 准备:参考ExoPlayer的github文档 git ExoPlayer到本地 windows安装cygwin 参考:https://blog.csdn.net/chunleixiahe/...
ExoPlayer是Google开源的Android平台媒体播放器。 它是Android的MediaPlayer API的替代品。 相比于IJKPlayer,EXOPlayer更易于拓展,功能更多,bug更少。ExoPlayer虽然不支持软解但是为开发者扩展软解预留了接口。 网上竟然搜不到ExoPlayer+软解扩展实现,那就有必要来一篇了hhh。 预先准备: 1.下载NDK(要下载NDK...
ExoPlayer是一个开源的媒体播放器库,提供了丰富的功能和灵活的扩展性。其中,FFmpeg扩展ExoPlayer中的一个重要组件。 ExoPlayer的核心功能是播放各种媒体格式的音视频文件,但是它并不直接支持所有的媒体格式。这就是为什么需要FFmpeg扩展的原因。FFmpeg是一个广泛应用于音视频处理领域的开源工具库,它提供了一套强大的功能,包括解码、编码、转码、过滤等。通过集成FFmpeg扩展ExoPlayer可以充分利用FFmpeg提供的功能来支持更多的媒体格式。 FFmpeg扩展使得ExoPlayer能够在不同的平台上运行,并能够处理各种常见或者特殊的音视频格式。它提供了跟踪最新FFmpeg版本的机制,保证ExoPlayer始终具备对新媒体格式的支持。同时,FFmpeg扩展还提供了配置和优化的选项,开发者可以根据自己的需求进行调整。 通过ExoPlayerFFmpeg扩展的结合,开发者可以快速实现一个功能强大、灵活可扩展的媒体播放器。无论是播放常见的MP3、MP4文件,还是处理特殊的FLAC、MKV等格式,ExoPlayer都能够应对自如。而且,由于ExoPlayerFFmpeg扩展是开源项目,开发者可以根据自己的需求进行二次开发,定制化自己的播放器,提供更好的用户体验。 总之,ExoPlayerFFmpeg扩展是它的一个重要组件,它为ExoPlayer提供了支持更多媒体格式的能力,使得开发者能够更加灵活地定制和扩展一个高性能的媒体播放器。