目录介绍
- 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.关于其他介绍
好消息
- 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong211/YCBlogs
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!
0.关于项目介绍
0.1 本案例关联博客[共13篇]
1.关于音频基础博客
- 0.0.1 如何扫描本地音频或者视频
- 0.0.2 深入学习酷狗,混沌大学那种锁屏页面原理
- 0.0.3 为什么要捕获/丢弃音频焦点详细讲解
- 0.0.4 耳机声控,以及耳机拔出或者插入控制播放暂停
- 0.0.5 音视频编码解码深入分析总结
- 0.0.6 实现音视频1.5倍,2倍播放速率
- 0.0.7 音频的加密与解密案例实践深入总结
- 0.0.8 音频基础知识和概念的介绍
- 0.0.9 [音视频混合案例介绍]后期更新
- 0.1.0 如何构建知识图谱,重点
- 0.1.1 完整视频播放器案例总结与分析
- 0.1.2 关于博客笔记大汇总
- 0.1.3 Android编码规范
- 0.1.4 Notification通知控制播放
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 参考的项目
- 注意:如果是带着问题去看项目,去直接瞄准某个功能,感觉学习效率更高一些。先实现功能,后再思考原理或技巧。
- https://github.com/ocwvar/DarkPurple
- https://github.com/andremion/Music-Player
- https://github.com/googlesamples/android-UniversalMusicPlayer
- https://github.com/DuanJiaNing/Musicoco
- https://github.com/ryanhoo/StylishMusicPlayer
- https://github.com/hefuyicoder/ListenerMusicPlayer
- https://github.com/cpacm/MoeMusic
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音乐,混沌大学,等等。这些都是十分牛的项目,当然许多功能都在模仿与不断修正中
- 关于主要页面的示意图
-
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 个人博客
- github: https://github.com/yangchong211
- 知乎: https://www.zhihu.com/people/yang-chong-69-24/pins/posts
- 简书: http://www.jianshu.com/u/b7b2c6ed9284
- csdn: http://my.csdn.net/m0_37700275
- 喜马拉雅听书: http://www.ximalaya.com/zhubo/71989305/
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100239.headeruserinfo.3.dT4bcV