当前位置: 首页 > 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 :…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...