一个老项目中用 Service + MediaPlayer + 多线程实现的网络音频播放,时不时发生抽风,有时正常,有时疯狂在日志打印 Error (-38,0) ,停都停不下来...
审查代码没有任何问题,网上所说的啥原因是 prepare() 方法不能在 create(...) 创建的 MediaPlayer 后执行,纯属扯淡,以下是之前的实现代码:
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(musicUrl);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
}
});
完全没问题啊,我没用 MediaPlayer.create(...) 创建啊...(╯—﹏—)╯(┷━━━┷
想了想,干脆找个替代品来用得了...
于是上 Github 找了一圈,结果发现这个库:https://github.com/google/ExoPlayer
上来就第一句话:
ExoPlayer is an application level media player for Android. It provides an alternative to Android’s MediaPlayer API for playing audio and video both locally and over the Internet. ExoPlayer supports features not currently supported by Android’s MediaPlayer API, including DASH and SmoothStreaming adaptive playbacks. Unlike the MediaPlayer API, ExoPlayer is easy to customize and extend, and can be updated through Play Store application updates.
翻译过来大致意思就是 ExoPlayer 为在本地和互联网上播放音频和视频提供了安卓媒体播放器 API 的替代方案...
卧槽 Google 你搞笑呢?合着 Android 上的 MediaPlayer 就是逗我的?
然后看看集成代码...
implementation 'com.google.android.exoplayer:exoplayer:2.X.X'
// where 2.X.X is your preferred version.
preferred version? 我喜欢啥就写啥版本?啧......你 Google 能靠点谱么?
使用 latest.release 大法探测了下,目前最终版本是 2.9.6...行吧,就用 2.9.6。
集成完毕,开始替换 MediaPlayer:
private ExoPlayer player;
player = ExoPlayerFactory.newSimpleInstance(context,new DefaultTrackSelector());
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "Application Agent"));
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(musicUrl));
player.prepare(mediaSource);
player.addListener(new Player.EventListener() {
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState==STATE_ENDED){
//End Event
}
}
});
player.setPlayWhenReady(true);
搞定,运行测试,没任何问题。
本文案例提供了 MediaPlayer 更换 ExoPlayer 播放音频的基本方案,虽然绕了一大圈但基本算是把脑抽的 MediaPlayer 彻底解决掉了,ExoPlayer 还有视频播放功能,本文不再详细探究,如有必要后续发新文章吧...