当前位置: 首页 > news >正文

最新版本Exoplayer扩展FFmpeg音频软解码保姆级教程

ExoPlayer 是一个开源的 Android 媒体播放库,由 Google 开发和维护,用于替代 Android 系统自带的 MediaPlayer。它提供了更强大的功能、更好的性能和更高的灵活性,适用于各种复杂的媒体播放场景。所以被广泛用于各种播放器场景。

最近项目中也使用了Exoplayer进行歌曲播放,但遇到报错:

02-14 18:26:05.078  2194  3425 I ACodec  : codec does not support config operating rate (err -2147483648)                                                                                              
02-14 18:26:05.085  1958  3430 E SoftMP3 : mp3 decoder returned error 1                                                                                                                                
02-14 18:26:05.085  2194  3425 E ACodec  : [OMX.google.mp3.decoder] ERROR(0x80001001)                                                                                                                  
02-14 18:26:05.085  2194  3425 E ACodec  : signalError(omxError 0x80001001, internalError -2147483648)                                                                                                 
02-14 18:26:05.085  2194  3425 E MediaCodec: Codec reported err 0x80001001, actionCode 0, while in state 6                                                                                             
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer: Audio codec error                                                                                                                            
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:   java.lang.IllegalStateException                                                                                                            
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at android.media.MediaCodec.native_dequeueInputBuffer(Native Method)                                                                   
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at android.media.MediaCodec.dequeueInputBuffer(MediaCodec.java:2505)                                                                   
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at androidx.media3.exoplayer.mediacodec.SynchronousMediaCodecAdapter.dequeueInputBufferIndex(SynchronousMediaCodecAdapter.java:101)    
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:1224)                               
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:818)                                         
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at androidx.media3.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1047)                                         
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:522)                                       
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at android.os.Handler.dispatchMessage(Handler.java:98)                                                                                 
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at android.os.Looper.loop(Looper.java:154)                                                                                             
02-14 18:26:05.086  2194  2290 E MediaCodecAudioRenderer:       at android.os.HandlerThread.run(HandlerThread.java:61)                                                                                 
02-14 18:26:05.088  2194  2290 E ExoPlayerImplInternal: Playback error

android设备系统自带的mp3解码器报错[OMX.google.mp3.decoder],在不同的平台上测试结果都报一样的错, 硬解码不行那就只能想办法进行软解了。查资料得知Exoplayer是支持通过扩展FFmpeg进行音频软解码的,官方扩展模块说明文档为decoder_ffmpeg,那么接下来就是按照官方文档进行集成扩展了。

decoder_ffmpeg模块最终会被编译打包成aar文件供Android调用,由于依赖FFmpeg,先要下载FFmpeg源码进行编译得到所依赖的库才能成功打包aar。下面详细介绍整个流程:参考该文章ExoPlayer(AndroidX Media3) 扩展ffmpeg实现音频软解码

环境准备:
1.Ubuntu 20.04.4 LTS
2.AndroidNDK版本r26C
3.AndroidStudio 2023.1.1(配置好SDK和JDK 17.0.10)
4.ffmpeg6.0源码
5.ExoPlayer源码,AndroidX Media release分支版本

 由于一般都是在Windows上进行安卓开发,所以还需要先安装虚拟机,然后在虚拟机上安装Ubuntu,通过linux系统完成整个编译过程。

一、安装虚拟机

Wmware下载看这里WM秘钥

安装教程看这里WM安装教程

破解秘钥:

秘钥许可证
4A4RR-813DK-M81A9-4U35H-06KNDNZ4RR-FTK5H-H81C1-Q30QH-1V2LAJU090-6039P-08409-8J0QH-2YR7F4Y09U-AJK97-089Z0-A3054-83KLA4C21U-2KK9Q-M8130-4V2QH-CF810MC60H-DWHD5-H80U9-6V85M-8280DZA30U-DXF84-4850Q-UMMXZ-W6K8FAC590-2XW97-48EFZ-TZPQE-MYHEAYF39K-DLFE5-H856Z-6NWZE-XQ2XDAC15R-FNZ16-H8DWQ-WFPNV-M28E2CZ1J8-A0D82-489LZ-ZMZQT-P3KX6YA11K-6YE8H-H89ZZ-EXM59-Y6AR0

 二、安装虚Ubuntu

参考Ubuntu下载安装教程 

Ubuntu与Windows共享文件夹和复制粘贴

三、下载Exoplayer和FFmpeg最新源码

目前官方已废弃Exopler2,代码已经迁移到AndroidX Media,下载完成设置FFMPEG_MODULE_PATH变量

在Ubuntu的File根目录创建Android/Project目录存放各种资源,根据自己实际放任意创建位置即可

打开ubuntu终端窗口,进入到上面新建的目录下:

cd Android/Project
git clone https://github.com/androidx/media
cd media && FFMPEG_MODULE_PATH="$(pwd)/libraries/decoder_ffmpeg/src/main"echo $FFMPEG_MODULE_PATH /home/xxx/Android/Project/media/libraries/decoder_ffmpeg/src/main

没有安装git的话根据提示进行安装即可。

四、下载NDK并配置NDK环境

1.官网下载NDK,根据官方说明,需要选择NDK版本ndk-linux-r26d.zip,虚拟机下载较慢,可在windows上先下好拷贝到虚拟机Ubuntu上,并解压到/Android/Project/目录下

2.下载完成后解压,设置NDK_PATH变量

cd Android/Project
unzip android-ndk-r26d-linux.zip
cd android-ndk-r26c && NDK_PATH="$(pwd)"echo $NDK_PATH /home/xxx/Android/Project/android-ndk-r26d

3.在当前NDK目录下,执行设置编译环境指令

//设置编译平台Lunux为
HOST_PLATFORM="linux-x86_64"//设置最小支持Android版本,通常为项目设置的minSDK版本,NDKr26最小支持SDK为21
ANDROID_ABI=21

 五、下载FFmpeg源码并配置环境变量

进入Android/Project目录进行ffmpeg源码下载,MediaX中的Exoplayer要求FFmpeg版本6.0

git clone git://source.ffmpeg.org/ffmpeg 
cd ffmpeg 
//拉取与最新Exoplayer匹配的版本
git checkout release/6.0 
//配置环境变量
FFMPEG_PATH="$(pwd)"echo $FFMPEG_PATH /home/xxx/Android/Project/ffmpeg

六、配置所需要支持的音频解码器类型

ffmpeg所支持音频格式官方说明点击这里查看 

//在ffmpeg目录下执行
ENABLED_DECODERS=(aac ac3 mp3 flac)

七、Exoplayer源码关联FFmpeg源码

将ExoPlayer源码中ffmpeg模块jni与ffmpeg源码关联,关联成功后会在jni目录中生成一个快捷方式指向ffmpeg源码目录

//在ffmpeg目录下执行关联指令cd "${FFMPEG_MODULE_PATH}/jni"
ln -s "$FFMPEG_PATH" ffmpeg 

八、编译FFmpeg

Exoplayer源码中已经帮我们配好了编译脚本build_ffmpeg.sh,执行即可,带上之前配置的环境变量

//在Exoplayer源码decoder_ffmpeg模块,jni目录下执行编译./build_ffmpeg.sh \ "${FFMPEG_MODULE_PATH}" "${NDK_PATH}" "${HOST_PLATFORM}" "${ANDROID_ABI}" "${ENABLED_DECODERS[@]}"

编译过程可能报错,基本根据报错信息处理就可以了,我碰到的问题是关联的ffmpeg目录找不到,实际上是关联成功了的,脚本中直接把关联路径改成绝对路径就可以了,报错的位置如下:

 编译成功后,会在ffmepg目录下生成一个android-libs目录 

 里面有各个不同架构平台的库,默认生成的是.a静态库文件,android上要用动态so库文件,修改一下编译脚本重新编译即可:

结果如下:

 九、编译decoder_ffmpge模块打包成aar文件供android调用

进入到Exoplayer源码更目录执行编译打包指令

./gradlew lib-decoder-ffmpeg:assembleRelease

报错的话更近提示进行处理即可,大概率就是JDK和SDK没有安装或者环境没有配置对

Ubuntu安装android sdk教程

Ubuntu安装JDK教程

编译成功后会在\libraries\decoder_ffmpeg\buildout\outputs\aar\目录生成aar包 

十、Android项目中使用aar实现音频软解码 

复制生成的aar包到项目libs目录,修改app下的build.gradle文件,引用aar包
implementation(files("libs/extension-ffmpeg-release.aar"))
自定义DefaultRenderersFactory,构造ExoPlayer实例时传入,日志中有ffmpeg相关信息代表加载成功。

    public class PluginRenderFactory extends DefaultRenderersFactory {/*** @param context A {@link Context}.*/public PluginRenderFactory(Context context) {super(context);}@Overrideprotected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {ffmpegAudioRenderer = new FfmpegAudioRenderer(eventHandler, eventListener, audioSink);out.add(ffmpegAudioRenderer);super.buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, eventListener, out);}}mExoPlayer = new ExoPlayer.Builder(context, renderersFactory).build();

 Android中使用可能出现编译不通过问题,大概率是Android项目使用的各种编译环境版本与编译aar时使用的不一致,Exoplayer源码使用如下配置:

建议尽量使用相同配置 ,还有就是我Ubuntu配置的JDK是17.0.14版本,所以AndroidStudio编译也要使用 相同版本JDK

至此大功告成! 

下一篇介绍Exoplayer+FFmpeg实现K歌场景中的切换原伴唱功能K歌中单双音轨实现原伴唱

相关文章:

最新版本Exoplayer扩展FFmpeg音频软解码保姆级教程

ExoPlayer 是一个开源的 Android 媒体播放库&#xff0c;由 Google 开发和维护&#xff0c;用于替代 Android 系统自带的 MediaPlayer。它提供了更强大的功能、更好的性能和更高的灵活性&#xff0c;适用于各种复杂的媒体播放场景。所以被广泛用于各种播放器场景。 最近项目中…...

面对低消费欲人群,我们如何开发其需求?

在市场增量放缓的当下&#xff0c;开发深度开发各层次的人群已经成为现实需求。低消费欲人群并非“没有需求”&#xff0c;而是更谨慎、更理性。他们可能对价格敏感&#xff0c;但对实用性、情感共鸣和生活品质的追求依然存在。就让我们从以下四个角度&#xff0c;拆解如何激发…...

《算法基础入门:最常用的算法详解与应用(持续更新实战与面试题)》

1. 排序算法 排序算法是将一组数据按特定的顺序排列起来的算法&#xff0c;常见的有&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;选择排序&#xff08;Selection Sort&#xff09;插入排序&#xff08;Insertion Sort&#xff09;归并排序&#xff08;Merge So…...

Linux设备驱动-练习

练习要求&#xff1a; 一、设备树 1、配置设备树信息&#xff1a;将3个led灯和1个风扇使用到的设备信息配置到设备树中 二、设备驱动层 1、通过of_find_node_by_name、of_get_named_gpion等内核核心层统一的api接口调用外设&#xff1b; 2、通过udev设备管理器自动注册并创建设…...

蓝桥杯核心内容

核心内容 数学 质数与筛质数&#xff0c;分解质因数 分解质因数 所有的数都可以写成有限个数相乘质数&#xff1a;可以写成1✖本身&#xff08;如131✖13&#xff09;合数&#xff1a;ab1✖...✖bn-》把乘数里面是合数的再分&#xff08;如b3是合数-》b3c1✖c2&#xff09;进…...

Spring Boot拦截器(Interceptor)详解

拦截器Interceptor 拦截器我们主要分为三个方面进行讲解&#xff1a; 介绍下什么是拦截器&#xff0c;并通过快速入门程序上手拦截器拦截器的使用细节通过拦截器Interceptor完成登录校验功能 1. 快速入门 什么是拦截器&#xff1f; 是一种动态拦截方法调用的机制&#xff…...

非常好用的ssh工具Xterminal

免安装 Xterminal - 更好用的开发工具&#xff0c;但不止于(SSH/控制台/More)...

【Python项目】基于Django的医疗领域用户问答意图识别系统

【Python项目】基于Django的医疗领域用户问答意图识别系统 技术简介&#xff1a;采用Python技术、MySQL数据库、Neo4j图形数据库、Django框架、BERTLSTMCRF模型等技术实现。 系统简介&#xff1a; 医疗领域用户问答意图识别系统是一个基于知识图谱的智能问答平台&#xff0c;旨…...

深入理解指针(六)

一、字符指针变量 1.1字符指针变量 在指针的类型中我们知道有一种指针类型为字符指针char* 一般有以下两种使用方式&#xff1a; #include<stdio.h> int main() { char ch w; char* pc &ch; *pc w; return 0; } #include<stdio.h> int main()…...

Linux下基本指令(4)

Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的命令提示符是“#”&#xff0c;普通用户…...

vue 手写分页

【先看效果】 &#xff08;1&#xff09;内容小于2页 不展示页码 &#xff08;2&#xff09;1 < 内容页数< 限定展示页码 展示&#xff1a;页码、上下页&#xff1b;隐藏&#xff1a;首页、末页图标&#xff0c;上、下一区间码。即&#xff1a;&#xff08;页数&#…...

Spring Boot项目接收前端参数的11种方式

大家好&#xff0c;我是。在前后端项目交互中&#xff0c;前端传递的数据可以通过HTTP请求发送到后端&#xff0c; 后端在Spring Boot中如何接收各种复杂的前端数据呢&#xff1f;这篇文章总结了11种在Spring Boot中接收前端数据的方式。 1 搭建项目 1.通过Spring Initializr…...

Springboot项目:使用MockMvc测试get和post接口(含单个和多个请求参数场景)

一、引入MockMvc依赖 使用MockMvc&#xff0c;必须要引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>二、具体演示…...

OpenAI ChatGPT在心理治疗领域展现超凡同理心,通过图灵测试挑战人类专家

近期&#xff0c;一项关于OpenAI ChatGPT在心理治疗领域的研究更是引起了广泛关注。据报道&#xff0c;ChatGPT已经成功通过了治疗师领域的图灵测试&#xff0c;其表现甚至在某些方面超越了人类治疗师&#xff0c;尤其是在展现同理心方面&#xff0c;这一发现无疑为AI在心理健康…...

【HBase】HBaseJMX 接口监控信息实现钉钉告警

目录 一、JMX 简介 二、JMX监控信息钉钉告警实现 一、JMX 简介 官网&#xff1a;Apache HBase ™ Reference Guide JMX &#xff08;Java管理扩展&#xff09;提供了内置的工具&#xff0c;使您能够监视和管理Java VM。要启用远程系统的监视和管理&#xff0c;需要在启动Java…...

25旅游管理研究生复试面试问题汇总 旅游管理专业知识问题很全! 旅游管理复试全流程攻略 旅游管理考研复试真题汇总

旅游管理复试很难&#xff1f;&#xff01; 别怕&#xff01;经验超丰富的老学姐来给你们出谋划策啦&#xff01; 最近是不是被旅游管理考研复试折磨得够呛&#xff1f;莫慌&#xff01;我这有着丰富复试指导经验的老学姐来帮你们排雷&#xff0c;助力大家顺利上岸&#xff01…...

深入解析C++26 Execution Domain:设计原理与实战应用

一、Domain设计目标与核心价值 Domain是C26执行模型的策略载体&#xff0c;其核心解决两个问题&#xff1a; 执行策略泛化&#xff1a;将线程池、CUDA流等异构调度逻辑抽象为统一接口策略组合安全&#xff1a;通过类型隔离避免不同执行域的策略污染 // Domain类型定义示例&a…...

Linux命令基础

【Linux路径写法】 相对路径与绝对路径&#xff1a; 绝对路径&#xff1a;以根目录为起点&#xff0c;描述路径的一种写法&#xff0c;路径描述以 / 开头 相对路径&#xff1a;以当前目录为起点&#xff0c;描述路径的一种写法&#xff0c;路径描述无需以/开头 特殊路径符&…...

什么是超越编程(逾编程)(元编程?)

超越编程(逾编程)(元编程&#xff1f;)(meta-programming) 目录 1. meta- 的词源 2. 逾编程(meta-programming) 的直实含义 2.1 定义 2.2 说明 3. 翻译成“元编程”应该是一种错误 1. meta- 的词源 这是一个源自希腊语的构词元素&#xff0c;其有三种含义&#xff…...

netcore libreoffice word转pdf中文乱码

一、效果 解决&#xff1a; cd /usr/share/fonts/ mkdir zhFont cd zhFont #windows系统C:\Windows\Fonts 中复制/usr/share/fonts/zhFont sudo apt update sudo apt install xfonts-utils mkfontscale mkfontdir #刷新字体缓存 fc-cache -fv #查看已安装的字体列表 fc-list :…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...