完整音频播放器

yangchong211 / 文 发表于2018-03-01 16:17 次阅读

目录介绍

  • 0.关于项目介绍
  • 0.1 本案例关联博客[共14篇,系统性介绍,全面展开]
  • 0.2 本案例其他说明
  • 0.3 全面系统化学习音视频播放器
  • 1.关于音频播放器基本功能
  • 1.1 基本实现的功能
  • 1.2 音频的缓存,下载,播放权限等功能
  • 1.3 音频后台播放功能
    • 1.3.1 音频播放可以支持后台播放
    • 1.3.2 Android系统有自动回收内存机制
  • 1.4 需要注意的问题
    • 1.4.1 一般播放音频APP具有的功能
    • 1.4.2 注意的问题有哪些呢?[共11条,持续找问题中]
  • 1.5 待实现功能
  • 2.关于音频播放器高级功能
  • 2.1 能够自由扫描本地音频[掌握]
    • 2.1.1 在activity中扫描还是在service扫描
    • 2.1.2 扫描音乐的逻辑
  • 2.2 锁屏联动媒体播放器[重点]
    • 2.2.1 什么是锁屏联动媒体播放器
    • 2.2.2 如何实现,逻辑思路
    • 2.2.3 注意要点分析
  • 2.3 捕获/丢弃音乐焦点处理[重点]
    • 2.3.1 发现有趣的焦点问题
    • 2.3.2 为什么要处理音频焦点问题
    • 2.3.3 具体的代码逻辑
    • 2.3.4 当焦点变化时,我的处理逻辑
  • 2.4 耳机拔出时暂停播放[理解]
    • 2.4.1 拔出耳机自动暂停 , 插入耳机自动恢复播放
    • 2.4.2 实现的原理分析
    • 2.4.3 蓝牙耳机又是如何实现[求赐教]
  • 2.5 耳机线控,耳机控制声音[理解]
    • 2.5.1 耳机按键也可以控制音量调节
    • 2.5.2 5.0之前和5.0之后比较
    • 2.5.3 实现的逻辑分析
  • 2.6 滑动通知栏可以关闭程序[掌握]
  • 2.7 外放,耳机,听筒之间的切换[掌握]
  • 3.关于项目架构的技术堆栈
  • 3.1 该项目App整体架构
  • 3.2 主要的技术要点
  • 3.3 日志打印,选择数据库
  • 3.4 主要的开源框架介绍
  • 3.5 项目代码规范,UI说明
  • 3.6 技术难点
  • 4.关于音频编码解码
  • 4.0 认识音频基础属性
  • 4.1 音频编码
  • 4.2 音频解码
  • 5.关于音频其他知识点
  • 5.1 如何给音频加密
  • 5.2 Android提供3套音频播放的API,如何选择
  • 5.3 如何设置音视频播放速率
  • 5.4 关于通知栏控制音频播放逻辑处理
  • 6.参考案例和博客链接
  • 6.1 参考的项目
  • 6.2 参考的博客
  • 6.3 参考的市面上App
  • 7.关于此项目更新日志
  • 8.关于其他介绍

0.关于项目介绍

0.1 本案例关联博客[共13篇]

1.关于音频基础博客

0.2 本案例其他说明

  • 持续更新中,看了网上许多博客,许多写的很好,但是没有对应的案例感觉有时难以下手。于是拿来主义,一边写案例,一边写笔记,也算是相结合吧。可能会存在一些问题,欢迎指出,谢谢!
  • 该项目对应的地址链接:https://github.com/yangchong211/YCAudioPlayer
  • 直接看该案例中音乐模块,其他部分还没有完善,音频播放这块大都完成。
  • 感谢大神前辈们的开源项目,尤其是remusic,StylishMusicPlayer,Music-Player,ListenerMusicPlayer,PonyMusic等案例。
  • 对于remusic等项目,大神之作,但是代码文档少,注释少,要向入门感觉有些困难。但是对于我这个播放器,注释详细,还有配套文档博客,方便初期看,要向更上一层楼,还是看大神之作。结合实际情况阅读代码很重要!!!
  • 如果可以,欢迎star!!

0.3 全面系统化学习音视频播放器

1.全面介绍的好处

  • 0.3.1 构建自己的知识框架
  • 0.3.2 案例与博客相互结合,以解决问题为目的地学习或者阅读更加有利于提高自己的实战技能

1.关于音频播放器基本功能

1.1 基本实现的功能

A基础功能

  • 1.1.1 基础的音频播放功能有:播放,暂停,下一首,上一首
  • 1.1.2 播放监听,播放完了自动下一首;滑动监听,拖动SeekBar可以控制播放进度,进度条显示播放进度功能
  • 1.1.3 设置音量控制监听,手机上音量滑动监听,手机按键控制音量,还有耳机控制音量。注意要同步!
  • 1.1.4 播放类型:顺序循环播放,随机循环播放,单曲循环播放等等
  • 1.1.5 播放进度快慢设置:参考混沌大学,播放速度可以设置为1.0x,1.5x,2.0x
  • 1.1.6 播放快进快退,参考混沌大学,间隔时间是15秒
  • 1.1.7 可通过媒体按钮和 Notification 通知栏来控制媒体播放
  • 1.1.8 停止播放后,可通过滑动移除 Notification 来关闭应用,这个是参考喜马拉雅APP,因为平时玩的比较多,所以个人感觉这个功能还是不错的。我的喜马拉雅:http://www.ximalaya.com/71989305/profile/

1.2 音频的缓存,下载,播放权限等功能

B其他功能

  • 1.2.1 音频可以边播放变缓存
  • 1.2.2 支持下载到本地,如果有付费音频,还需要转码加密
  • 1.2.3 支持设置播放权限

1.3 音频后台播放功能

C其他功能

  • 1.3.1 音频播放可以支持后台播放
  • 当切换到后台时,显示通知栏,可以通过通知栏来控制上一首,下一首,播放暂停功能,主要需要保证播放进度和音频属性数据信息同步
  • 1.3.2 Android系统有自动回收内存机制
  • 如果系统内存紧张,就会触发该机制,应用就有可能被回收,不过Android提供了前台机制,比如当音频播放器切换到后台时,这个时候可以通过通知栏中按钮,点击切换音乐,那么当播放时启动前台机制,而暂停时取消前台机制。保证内存不足时也不会回收该应用

1.4 需要注意的问题

D注意问题

  • 1.4.1 一般播放音频APP具有的功能:
  • 播放、暂停、切换歌曲、进度调节、切换播放模式、专辑封面显示、音频列表、音频管理,添加收藏,下载等功能。(由于国产手机大多都是修改过的Android系统,因此系统自带播放器功能也不一样,这里以Android原生播放器为参考,同时结合了喜马拉雅,混沌大学,得到等音频付费APP)
  • 1.4.2 注意的问题有哪些呢?
  • a.如手机来电时,音频需要自动暂停播放
  • b.耳机拔出时,同样需要暂停
  • c.Android有些手机耳机有音控键,有些没有,但还是要支持耳机线控
  • d.当在播放音频的时候,又去打开别的视频软件,这个时候音频声音会变小,有的是暂停。等到关闭其他音视频软件时,点击播放,声音如何调整
  • e.对于付费的音频,如何加密播放了?两种情况:1,如果没有下载则可以通过返回接口字段控制权限;2.如果下载了,那么如何才能实现只有自己的播放器才能播放音频,而其他的不能呢?
  • f.参考了混沌大学,对于音频列表,有的显示是下载完成,有的是未下载,有的是下载中,要区分好状态。
  • g.参考了喜马拉雅,不管是否有网络,都可以直接扫描本地喜马拉雅音频文件。那么对于音频,有十几种格式,如何区别咱们APP音频与其他音频。
  • h.我看到比如喜马拉雅下载的音频中还有排序的功能,比如根据文件大小,或者根据文件名首字母排序。该如何实现呢?
  • 还在探索中
  • 详细更多内容可以看我的笔记:关于博客笔记大汇总

1.5 待实现功能

  • 1.5.1 在应用被销毁后,可以通过耳机线控来重新启动
  • 1.5.2 如何自定义均衡器配置,部分有该功能,可参考喜马拉雅
  • 1.5.3 参考混沌大学,将视频内容分离成视频和音频两个部分,当播放音频时可以切换成播放视频,当播放视频时可以切换成音频,还能够记录播放位置。这个如何实现了?思考???欢迎同行给出建议,注意接口返回的音频和视频是不同的接口,只是内容一样而已。
  • 1.5.4 外放,耳机,听筒之间的切换。关于这块内容可以直接看本篇博客:

2.关于音频播放器高级功能

2.1 能够自由扫描本地音频

  • 2.1.1在activity中扫描还是在service扫描
  • 写音频案例之前,我也参考了部分小的音频播放器案例,我发现有些直接写在activity中,当然这个最后结果是也能正常展示扫描的音频。如果音频少,那么没什么影响;如果音频多,几百首,那么activity中直接处理有点不妥当了,会卡顿。所以我最后还是想在service中处理扫描逻辑
  • 2.1.2 扫描音乐的逻辑
  • 一般音频APP中会有我的下载或缓冲页面,那么扫描本地音频。而扫描一般通过ContentProvider配合Media相关类查询系统数据库,获得媒体库中的歌曲信息。
  • 通过阅读扫描音乐代码可知,是在服务中扫描音乐。但是有个问题,如果是又下载了新的音频,怎样才能做到及时更新呢?还是直接重新扫描?
  • 这个可以直接参考我的案例代码:util包--musicUtils--FileScanManager中的代码
  • 关于扫描本地音乐的逻辑,可以看这篇博客:如何扫描本地音频或者视频

2.2 联动系统媒体播放器

  • 2.2.1 什么是锁屏联动媒体播放器
  • 播放器除了播放了音乐之外什么都没做,就可以分别在任务管理、锁屏、负一屏控制播放器。
  • 也可以这样通俗的解释,这个举例子说一个应用场景,我使用混沌大学听音频,然后我关闭了屏幕(屏幕灭了),当我再次打开的时候,屏幕的锁屏页面或者顶层页面便会出现一层音频播放器控制的页面,那么即使我不用解锁屏幕,也照样可以控制音频播放器的基本播放操作。如果你细心观察一下,也会发现有些APP正式这样操作的。目前我发现QQ音乐,混沌大学等是这样的
  • 2.2.2 如何实现,逻辑思路
  • 第一步:在服务中注册屏幕熄灭广播
  • 第二步:处理逻辑,发现屏幕熄灭就开启锁屏页面,再次点亮屏幕时就可以看到锁屏页面
  • 第三步:点击锁屏页面上的按钮,比如上一首,下一首,播放暂停可以与主程序同步信息。
  • 第四步:滑动锁屏页面,锁屏页面被销毁,进入程序主界面。

2.3 捕获/丢弃音频焦点处理

  • 2.3.1 这个问题细心点就会发现,很有趣。
  • 如果手机上安装了两个音频播放器,当一个正在播放的时候,打开第二个播放歌曲,有没有发现第一个自动暂停了……
  • 如果你在听音频的同时,又去打开了其它视频APP,你会发现音频APP暂停播放了……
  • 如果你正在听音频或者看视频时,来电话了,那么音视频便会暂停。挂了电话后音乐又继续播放,视频则需要点击按钮播放,是不是很奇怪
  • 当你收到消息,比如微信消息,并且有消息声音的时候,那么听音频的那一瞬间,音频的声音会变小了,然后过会儿又恢复了。是不是很有意思。
  • 别蒙圈,这个就叫做音频捕获和丢弃焦点。
  • 至于如何处理,可以看我的源码案例: https://github.com/yangchong211/YCAudioPlayer
  • 还可以看我的博客,潇湘剑雨,博客大汇总: https://www.jianshu.com/p/53017c3fc75d
  • 2.3.2 为什么要处理音频焦点问题
  • 如果不处理捕获与丢弃音频焦点的话,那么同时开几个音视频播放器,就会出现多个声音。那样会很嘈杂,一般线上的APP都会做这个处理,不过一些GitHub案例demo中一般没处理。
  • 2.3.3 具体的代码逻辑可以直接参考代码案例
  • 简单来说,就是这三步逻辑方法
  • 2.3.3.1 在service的oncreate方法中调用初始化方法
  • 2.3.3.2 在播放音频的时候开始请求捕获音频焦点
  • 2.3.3.3 在音频销毁的时候开始丢弃音频焦点
  • 2.3.4 当焦点变化时,我的处理逻辑
  • 2.3.4.1 当重新获得焦点的时候,如果通话结束,恢复播放;获取音量并且恢复音量。这个情景应该经常遇到。
  • 2.3.4.2 当永久丢失焦点,比如同时打开播放器,则停止或者暂停播放,否则出现两个声音
  • 2.3.4.3 当短暂丢失焦点,比如比如来了电话或者微信视频音频聊天等等,则暂停或者停止播放
  • 2.3.4.4 当瞬间丢失焦点,比如手机来了通知。前提是你的通知是震动或者声音时,会短暂地将音量减小一半。当然你也可以减小三分之一,哈哈!

2.4 耳机拔出时暂停播放

  • 2.4.1 拔出耳机自动暂停 , 插入耳机自动恢复播放
  • 在使用音频APP时,细心的你有没有发现,拔出耳机,暂停播放了;插上耳机又恢复播放了。是不是很神奇……
  • 如何实现这个功能了,这个我也是通过百度才知道了,但是代码还是不太懂,IntentFilter作用?后来明白,其实不用深入底层原理也没有多大关系……
  • 2.4.2 实现的原理分析
  • 其原理还是通过发广播接收者控制播放与暂停功能。首先创建一个广播接收者,然后在播放时注册,在暂停时取消,就可以实现这个功能。
  • 具体的逻辑可以直接参考代码……其实这个也是百度查的!

2.5 耳机线控,耳机控制声音

  • 2.5.1 耳机按键也可以控制音量调节
  • 不得不说Android手机需要考虑不同情况,就拿耳机来说,有的有音控,有的没有音控,有的手机支持,有的手机不支持,虽然说不太重要,但还是可以思考一下。目前参考大量的案例,只能解决大部分的正常控制声音功能。
  • 刚开始看到这个真是蒙圈了,不过有Google,不担心。对于程序员来说没有实现不了的功能,只有自己的技术过不过关,哈哈,同事说的……找到了答案
  • 2.5.2 5.0之前和5.0之后比较
  • 对于5.0以上系统的手机,激活了MediaSession,就可以不用关心耳机声控了,会自己实现。
  • 对于5.0以前系统的手机,还是需要自己手动设置相关属性的,需要自己手动实现
  • 2.5.3 实现的逻辑分析
  • 这里暂且只是讨论5.0以前的处理方法,需要自己监听耳机按键
  • 通过代码KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);获取到KeyEvent的对象,然后获取对应点击事件的code,然后再做播放暂停,上一首,下一首处理。具体代码可以参考EarphoneControlReceiver类

2.7 外放,耳机,听筒之间的切换[掌握]

3.关于项目架构的技术堆栈

3.1 该项目App介绍

  • 3.1.1 bug管理
  • 可以使用腾讯免费的bugly管理平台,便于跟踪处理bug,有数据分析
  • 3.1.2 测试部分
  • 自己测试,一般来说自己不容易发现自己的问题,哪怕有些问题指出来后很简单。就像以前读书考试,自己检查试卷,也没检查出什么问题,但就是错了许多……
  • 基本的monkey测试,可以测试app在快速点击下崩溃问题
  • 运用平台测试,基于经费,还是选择免费的平台,一般应用市场也会有测试分析,比如华为测试,腾讯测试就很不错。

3.2 主要的技术要点

  • 3.2.1 音频播放的基础功能,播放暂停,上一首下一首,快进快退,播放状态切换,音量调节等等。
  • 3.2.2 音频播放前后台切换时,避免内存不足而回收资源问题
  • 3.2.3 支持音频下载,收藏,删除,缓存等功能。后期添加。
  • 3.2.4 支持耳机线控播放,耳机拔出自动暂停,支持耳机按钮控制音频播放音量
  • 3.2.5 支持播放详情页面,Notification通知,还有底部播放控制部分音频数据同步。本项目中采用是接口监听实现activity,fragment,service之间的通信
  • 3.2.6 支持添加类似酷狗音乐那种的锁屏页面
  • 3.2.7 支持来电或者拔出耳机时暂停播放的逻辑

3.3 日志打印,选择数据库

  • 3.3.1 日志打印,对于线上项目要规范,分为测试和正式打包日志。上线后要关掉部分打印日志
  • 3.3.2 关于数据库存储,这个看具体情况,使用原生SQLite或者Realm数据库
  • 3.3.3 由于之前开发都是使用Realm数据库,所以暂且使用它吧

3.4 主要的开源框架介绍

  • 注明:对于开源框架的选择,能够满足自己需求下,选择体量小的,并且相对成熟的的开源库
  • 3.4.1 网络请求框架
  • 3.4.2 gson解析框架
  • 3.4.3 H5网页可以用腾讯X5浏览器框架
  • 3.4.4 图片加载框架,谷歌glide,或者square/picasso
  • 3.4.5 音视频播放器底层框架ijkplayer
  • 3.4.6 下载框架FileDownloader
  • 3.4.7 自定义开源库:参考自己的GitHub项目
  • 3.5.8 自定义支持上拉加载更多,下拉刷新,可以自定义头部和底部,可以添加多个headAdapter,使用一个原生recyclerView就可以搞定复杂界面。地址:https://github.com/yangchong211/YCRefreshView
  • 3.5.9 其他库可以直接看GitHub

3.5 项目代码规范,UI说明

  • 3.5.1 项目的包名规范,分包说明,都要有文档
  • 3.5.2 关于注释,类注释,方法注释,还有常量注释可以参考阿里出版的java规范文档,通过插件可以自动检测注释规范。要求有输出文档。可以参考第三方sdk文档规范,清晰,简单而又能够让人快速看懂
  • 3.5.3 类名,方法名,常量或者变量等名称,还有布局文件xml中的各种空间id,都要采用统一的命名方式。要求见者知意……
  • 3.5.4 关于color颜色,string字符串,需要统一规范
  • 3.5.5 添加了捕获/丢弃音频焦点处理逻辑,可以监听两个以上音频播放时,暂停与播放逻辑
  • 3.5.6 关于代码规范,可以看这篇博客:Android编码规范
  • 3.5.7 或者直接看阿里出的java手册也行……写代码,不仅方便自己看懂,也要让别人看懂!

3.6 技术难点

  • 当屏幕从灭了到亮了,会出现锁屏页面,那么锁屏页面如何做到和播放器其他音乐信息同步?
  • 耳机声控,以及抢占焦点处理逻辑
  • 进度条没有正确监听,滑动到某一位置,歌曲会从头播放
  • 通知栏,音频播放详情页,主页面底部音频控制栏,还有锁屏页面音频信息同步。保持进度同步。
  • 项目中,视频播放和音频播放来回切换,不同步。
  • 其他待整理。

4.关于音频编码解码

  • 4.0 认识音频基础属性
  • 采样频率(Sample Rate):每秒采集声音的数量,它用赫兹(Hz)来表示。(采样率越高越靠近原声音的波形)
  • 采样精度(Bit Depth):指记录声音的动态范围,它以位(Bit)为单位。(声音的幅度差)
  • 声音通道(Channel):声道数。比如左声道右声道。
  • 4.1 音频编码与解码
  • 可以直接看这篇博客:音视频编码解码深入分析总结

5.关于音频其他知识点

5.1 如何给音频加密解密

  • 还在探索中
  • 业务场景分析:当用户下载了我们的视频,或者音频,那么在下载完成后需要对下载的文件进行加密。以避免使用其它播放器软件直接可以观看或者听下载的音视频……
  • 仅仅改变音视频的格式,或者不用后缀名的办法不可取。目前从咱们APP下载的视频,虽然没有后缀名,但是使用同类型的视频播放器照样可以打开。

5.2 Android提供3套音频播放的API,如何选择

  • Android提供3套音频播放的API,分别是:MediaPlayer,SoundPool,AudioTrack
  • MediaPlayer 更加适合在后台长时间播放本地音乐文件或者在线的流式资源;
  • SoundPool 则适合播放比较短的音频片段,比如游戏声音、按键声、铃声片段等等,并且文件的大小限制在1M左右,可支持多个文件同时播放。SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。调用pause并不会立即停止,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
  • AudioTrack 则更接近底层,提供了非常强大的控制能力,支持低延迟播放,适合流媒体和VoIP语音电话等场景。
  • 所以MediaPlayer是更加适合于第三方的播放器的,但是如果某些播放器用的并不是MediaPlayer那我也没有办法了,不在考虑的范围内。而本项目也是使用MediaPlayer的……

5.4 关于通知栏控制音频播放逻辑处理

  • 我们可以发现许多音频类的APP都会有通知栏控制播放逻辑这个功能,那么本案例也有该功能。具体可以看代码!
  • 关于这块更详细的内容,可以直接看这篇博客: Notification通知控制播放

6.参考案例和博客链接

6.1 参考的项目

6.2 参考的博客

  • 博客链接如下所示:
  • FFmpeg的库函数源代码分析文章列表:http://blog.csdn.net/leixiaohua1020/article/details/12677129
  • 多媒体编解码基础知识:http://zzqhost.github.io/hostwiki/%E5%A4%9A%E5%AA%92%E4%BD%93%E7%9B%B8%E5%85%B3_%E5%A4%9A%E5%AA%92%E4%BD%93%E7%BC%96%E8%A7%A3%E7%A0%81%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.html#toc_1.1.2
  • Android 注册媒体按键监听:https://www.jianshu.com/p/b52754c50f89
  • Android 多媒体控制 来电监听-耳机插拔监听-耳机按钮监听:http://blog.csdn.net/ocwvar/article/details/53107005
  • Android音频焦点详解:https://www.jianshu.com/p/e5785dcba952
  • Android 音频技术开发总结:https://yq.aliyun.com/articles/8637
  • [译]Android音频: 如何使用AudioTrack播放一个WAV格式文件?:http://blog.csdn.net/langwang2/article/details/50189977
  • 利用MediaExtractor和MediaCodec实现音频编解码和混音:http://yedaxia.me/Android-MediaExtractor-And-MediaCodec/
  • Android中播放音频的几种方式:http://blog.csdn.net/u013366008/article/details/76577372/

  • 6.2.3 关于锁屏页面的博客
  • 直接参考锁屏页面这篇博客:深入学习酷狗,混沌大学那种锁屏页面原理

6.3 参考的市面上App

  • 喜马拉雅,得到,QQ音乐,混沌大学,等等。这些都是十分牛的项目,当然许多功能都在模仿与不断修正中
  • 关于主要页面的示意图
  • image image image image

7.关于此项目更新日志

  • 7.1 v1.0.0 更新于2017年11月5日
  • 7.2 v1.1.0 更新于2018年1月29日
  • 7.3 v1.1.1 更新于2018年1月30日
  • 7.4 v1.2.0 更新于2018年3月5日

8.关于其他介绍

8.1 个人博客

收藏 赞 (3) 踩 (0)