利用MediaPlayer实现在线音频的播放(支持进度条拖动快进快退)
Posted 夜尽天明89
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用MediaPlayer实现在线音频的播放(支持进度条拖动快进快退)相关的知识,希望对你有一定的参考价值。
效果图:
https://github.com/chenjianqiang1016/MyNewAudioDemo
下载项目后,运行起来,会发现音频无法播放,是因为,我项目中读音的链接是
audioUrl = "https://...test.mp3"
之前调试的音频存放链接,指向公司的服务器,写demo的时候,只能隐去
写在前面:本项目的缺点是 没有对网络情况进行处理
我找了一首4分40秒的歌曲(4.5M),打开界面后,大约停留1-2秒,就开始播放了,然后我中断网络,发现可以顺利播放到结尾。说明在网络良好的情况下,问题不大。当然,这是理想状态,如果开头网络不好、网卡、网慢、播放到中间断网了、断网后又重连了。。。这些情况,本项目都没做处理。如果是播放本地文件,网络情况就无所谓了
更新记录:
说明中的第4点,更新于 2020-10-27 晚上8点
说明:(代码中可能不好理解的地方)
1、拖动线的宽高,留意 MySlideLineView -> onMeasure
//先于 onSizeChanged 执行
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(
widthMeasureSpec,
dp2px(mContext, 30f)
)
宽度是测量出来多宽,就是多宽。高度是固定的 30dp
2、拖动线和前后时间的间隔
如果看完代码,应该会注意到,布局中,MySlideLineView是紧挨着前后文字的,但是实际效果,是有间距的。这是因为
//先于 onDraw 执行
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int)
super.onSizeChanged(w, h, oldw, oldh)
......
lineStartX = dp2px(mContext, 15f).toFloat()
lineEndX = viewWidth - dp2px(mContext, 15f).toFloat()
......
可以看到,线绘制的起点、终点,和控件前后各 15dp。这是为了,方便手指按在线的起点、终点处
3、为什么 onTouchEvent 的 MotionEvent.ACTION_DOWN 中,有这么一句:
mySlideLinePercentageListener?.audiostart()
在实际开发中,频繁拖动的时候,mediaPlayer可能会报错,seekTo方法失效
Attempt to perform seekTo in wrong state: mPlayer=0x0, mCurrentState=1
通过查资料知道
该方法可以只可以在【 Prepared, Paused, Started,PlaybackCompleted】 状态进行调用
这里有2个处理方式:1、项目要求,手指按住拖动的时候,声音继续播,就在按下的位置mediaPlayer.start() ;2、项目要求,手指按住拖动的时候,声音先暂停,手指抬起再播放,就在按下的位置 mediaPlayer.pause() 。项目中没有要求,我这里就用了第一种处理方式
4、可能有人注意到了代码中的
play_audio_title_tv?.postDelayed(......,1000)
即,延迟 1秒 后,开始处理一些逻辑。这是因为,mediaPlayer 加载音频,是阻塞的,弱网情况下,加载音频会慢,而加载完,才能拿到时长,有了时长,才能做后面的事。这就导致了,弱网时,界面无法正常展示,甚至出现黑屏(或白屏)。
所以,我这里先让界面加载,加载完了,再去加载音频,有了时长以后,再进行后续处理。
以上是关于利用MediaPlayer实现在线音频的播放(支持进度条拖动快进快退)的主要内容,如果未能解决你的问题,请参考以下文章