我该从哪里开始?!我花了很多时间试图调试这个,但没有用.我打了一个deadend,真的很感激一些帮助.
我的场景:我正在尝试为Android制作一个能够交叉淡化每首歌曲的媒体播放器.我创建了2个MediaPlayer对象(playerA和playerB),其中playerA是播放"第一首歌"的播放器.理想的情况是,如果用户通过MediaPlayerController点击下一个按钮或者歌曲距离结束还有10秒 - 播放器A开始逐渐淡出OUT,同时播放器B加载一首歌曲,开始播放它,并淡化音量 - 给出你的交叉渐变效果.
虽然我已经让这个工作,但我必须说,我有随机的失败.我将失败定义为:下一首歌曲(通过"其他"播放器播放)你将听不到任何声音.我已经检查了失败/安静播放器的实际状态,同时它表现出这种行为,并且.isPlayer()= true和playerA.getDuration() - playerA.getCurrentPosition()正在计算,所以MediaPlayer认为它实际上正在播放 - 但是你又一次听不到任何声音.
我已经尝试了一百万种不同的方式,但是再一次,不能随意"破解"它.我尝试做"重复代码"以使其淡出和进入的方式是通过一个单独的线程使用位于服务启动方法中的UI句柄,我尝试使用TimerTask,我尝试使用postDelayed处理程序有许多不同的延迟(handler_crossfadeA.postDelayed(runnable_crossfadeA,500);)
一些技术细节:我通过一个扩展MediaPlayer的单例创建了每个playerA和playerB(其中包括一百万个其他内容)因此我只获得了1个实例,我的主要活动绑定到播放声音的MusicService,我正在使用Android L/5 API,我正在测试Nexus 5
所以我通过极大地减少我的代码来跟踪它,这导致问题(再次,它是随机的 - 但通常发生在5首歌曲中,但我确实得到一些代码可以持续多达20首歌曲):给定播放器A应用程序首次启动时开始,然后将下一首歌曲转换为playerB,然后播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放器播放设 最终我能够通过在playerB开始停止播放器A(消除所有音量输入和输出调整等)后500ms设置postDelayed处理程序来轻松地重现这一点.我甚至尝试将我的stop()和reset()代码移动到不同的方法,包括我的crossfade方法,在我的playSong()方法中,在onPrepare()方法中.
总结一下:
虽然我有大量的代码不适合这篇文章,但在将其拆除以进行故障排除之后,这就是我通常所拥有的(如果我遗漏了相关内容,请提前道歉):
服务启动方法的一部分:
handler_crossfadeA = new Handler();
guiHandler= new Handler(Looper.getMainLooper());
为每个玩家在服务启动时调用的init()方法:
playerA.setAudioSessionId(11);
playerA.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
playerA.setAudioStreamType(AudioManager.STREAM_MUSIC);
playerA.setOnPreparedListener(this);
playerA.setOnCompletionListener(this);
playerA.setOnErrorListener(this);
Run Code Online (Sandbox Code Playgroud)
playSong()方法的一部分
try{ playerA.setDataSource(getApplicationContext(), trackUri); } catch(Exception e){ }
try{ playerA.prepare(); } catch (IllegalStateException e) { e.printStackTrace();} catch …