Android之MediaPlayer一个bug
来源:互联网 发布:ubuntu安装golang1.7 编辑:程序博客网 时间:2024/06/15 10:34
本文主要记录使用Android 的MediaPlayer时遇见的一个很奇怪的bug
播放音乐时会出现调用了start,但是没有声音出来
* 测试机器:华为Honor 8, Android 7.0;
* 需求:在音乐列表界面播放音乐,音乐分为本地音乐和网络音乐
* 工具:IjkMediaPlayer在播放网络音乐时差不多有个10秒的延时,就是用户点击到播放出来差不多要10秒(网没有问题,很快),播放本地音乐没有这个问题,暂时无解,所以使用Android 提供的MediaPlayer.
* 思路:按照我的理解嘛,把网络和本地的音乐播放代码用一个,所以使用异步prepare,(注意,这里埋下了问题),因为是在列表里,音乐有很多,点击音乐A播放,再次点击A是暂停,然后再次点击A是继续播放,很简单的功能,所以加了一个判断,记录了上一次的播放的音乐地址,如果不一样,就需要重新初始化Mediaplayer, 因为要联网获取,懒得开线程,直接使用MediaPlayer的异步操作prepareAsync(),写如下出来的代码
```@Overridepublic void play(@NonNull String url) { play(url, false);}@Overridepublic void play(@NonNull String url, boolean restart) { synchronized (mPlayerLocker) { try { if (mMediaPlayer == null) { mMediaPlayer = new MediaPlayer(); } if (restart || !mLastPlayMusicUrl.equals(url)) { mMediaPlayer.reset(); mMediaPlayer.setLooping(true); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setOnPreparedListener(mMediaPrepareListener); mMediaPlayer.setVolume(0.5f, 0.5f); mMediaPlayer.setDataSource(url); mLastPlayMusicUrl = url; mMusicIsPlaying = true; mMediaPlayer.prepareAsync(); } else { mMediaPlayer.start(); } } catch (Exception e) { e.printStackTrace(); D.e("play music error : " + e.getMessage() + " path:" + url + " file exists:" + new File(url).exists()); } }}private MediaPlayer.OnPreparedListener mMediaPrepareListener = new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { synchronized (mPlayerLocker) { if (mMediaPlayer != null) { if (mMusicIsPlaying) { mMediaPlayer.start(); } else { mMediaPlayer.pause(); } } } }};```
* 正常使用,上面的代码是没有问题,但是我们的操作可能比较不正常吧,注意上面的代码play(@NonNull String url, boolean restart),第二个参数如果是true,会重新初始化播放器,对同一首音乐,播放,暂停,播放,暂停,播放(重新初始化), 暂停,播放(重新初始化), 暂停,播放(重新初始化), 暂停,播放(重新初始化)…,差不多重复10次左右吧,会出现一次播放时没有声音,但是暂停后,再播放,就又正常了,代码确实去调用了,prepare()了,也start()了。
* 很郁闷,找不到问题,然后大胆猜测是不是异步播放导致的,代码暂时换成同步的,只测试本地的音乐,测试50次,没有复现,尝试了很多其他办法,发现同步是比较好的一种方式
* 解决方案:本地的用同步的方式,网络的用异步的方式,附上测试播放的代码
```public class SlackMusicPlayer {public final static SlackMusicPlayer instance = new SlackMusicPlayer();private Thread mPrepareThread = null;private SlackMusicPlayer() { //}private MediaPlayer mMediaPlayer;private String mLastPlayMusicUrl = "";private boolean mMusicIsPlaying = false;private final Object mPlayerLocker = new Object();@Overridepublic void play(@NonNull String url) { play(url, false);}@Overridepublic void play(@NonNull String url, boolean restart) { synchronized (mPlayerLocker) { try { if (mMediaPlayer == null) { mMediaPlayer = new MediaPlayer(); } if (restart || !mLastPlayMusicUrl.equals(url)) { mMediaPlayer.reset(); mMediaPlayer.setLooping(true); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setVolume(0.5f, 0.5f); mMediaPlayer.setDataSource(url); mLastPlayMusicUrl = url; mMusicIsPlaying = true; if (mPrepareThread != null) { mPrepareThread.interrupt(); } mPrepareThread = null; if (url.startsWith("/")) {// 本地音乐文件 mMediaPlayer.setOnPreparedListener(null); mPrepareThread = new Thread(new Runnable() { @Override public void run() { try { synchronized (mPlayerLocker) { if (mMediaPlayer != null && mMusicIsPlaying) { mMediaPlayer.prepare(); mMediaPlayer.start(); } } } catch (Exception e) { e.printStackTrace(); } } }); mPrepareThread.start(); } else { mMediaPlayer.setOnPreparedListener(mMediaPrepareListener); mMediaPlayer.prepareAsync(); } } else { mMediaPlayer.start(); } } catch (Exception e) { e.printStackTrace(); D.e("play music error : " + e.getMessage() + " path:" + url + " file exists:" + new File(url).exists()); } }}@Overridepublic void setVolume(float left, float right) { synchronized (mPlayerLocker) { try { if (mMediaPlayer != null) { mMediaPlayer.setVolume(left, right); } } catch (Exception e) { e.printStackTrace(); } }}@Overridepublic void pause() { synchronized (mPlayerLocker) { try { if (mMediaPlayer != null) { mMediaPlayer.pause(); } } catch (Exception e) { e.printStackTrace(); } mMusicIsPlaying = false; }}@Overridepublic void reset() { synchronized (mPlayerLocker) { try { if (mMediaPlayer != null) { mMediaPlayer.reset(); } } catch (Exception e) { e.printStackTrace(); } mMusicIsPlaying = false; mLastPlayMusicUrl = ""; }}@Overridepublic void release() { synchronized (mPlayerLocker) { try { if (mMediaPlayer != null) { mMediaPlayer.release(); } } catch (Exception e) { e.printStackTrace(); } mMusicIsPlaying = false; mMediaPlayer = null; }}private MediaPlayer.OnPreparedListener mMediaPrepareListener = new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { synchronized (mPlayerLocker) { if (mMediaPlayer != null) { if (mMusicIsPlaying) { mMediaPlayer.start(); } else { mMediaPlayer.pause(); } } } }};
}
```
- Android之MediaPlayer一个bug
- 【Android】记录Android MediaPlayer的两个bug
- Android之MediaPlayer详解
- Android之MediaPlayer
- Android之MediaPlayer
- Android学习之MediaPlayer
- Android之MediaPlayer详解
- Android之MediaPlayer
- Android MultiMedia之MediaPlayer
- Android多媒体之MediaPlayer
- Android之MediaPlayer
- Android开发之Mediaplayer
- Android之MediaPlayer详解
- Android多媒体之MediaPlayer
- Android -多媒体之MediaPlayer
- Delphi中MediaPlayer控件的一个Bug即修复
- Android提高篇之MediaPlayer
- Android多媒体开发之MediaPlayer
- 文章标题
- 封装,继承,多态
- 命令行将APK安装到安卓模拟器
- 多实例安装
- PHP去掉二维数组中某个元素重复的一维数组
- Android之MediaPlayer一个bug
- 小知识
- 大话数据结构第三章链表十个问题及解答
- Phpstorm常用快捷键
- 在线翻译工具
- jQuery之属性操作
- Ambari LogSearch中监控新服务日志
- 利用amWiki轻松打造知识库或技术文档系统
- NOI训练行动路线图