Android媒体播放器音频故障/断断续续仅在较新的设备上

时间:2015-01-19 21:20:00

标签: android audio android-mediaplayer nexus-5 nexus-10

我有一个相当标准的媒体播放器对象,它在onCreate中启动,并在我的应用程序中循环播放背景音乐。该文件不是非常大,它是一个6MB的MP3。来自onCreate:

MediaPlayer mp;
mp = MediaPlayer.create(MainActivity.this, R.raw.lostmexicancity);
mp.setLooping(true);
mp.setVolume(0.4f, 0.4f);
mp.start();

这适用于我的大多数测试设备,包括旧手机,三星Galaxy Tab 2 10"平板电脑,甚至是Nexus 4.

不幸的是,我遇到了新设备的问题,我在Nexus 5和较新的Nexus 10上遇到音频故障/口吃。这些问题只发生在较新的设备上,通常是在正确播放几秒钟后,而不是立即发生。我的Nexus 4和5都运行Android 4.4.4但问题只发生在Nexus 5上。

当我暂停媒体播放器对象并在短时间内播放不同的媒体播放器对象(在游戏中为短战而战斗音乐)时,这个问题似乎更加恶化了,但即使没有这种额外的复杂情况也会发生故障。

我读过Android的新版本已经引起了Mediaplayer的问题,但我还没有得到修复或建议。

有没有其他人遇到过这个问题,谁可以建议修复或解决方法?谢谢你的时间!

2 个答案:

答案 0 :(得分:0)

我已经注意到我的Android设备上也发生了这种情况。

我注意到你没有在播放音频之前调用Prepare()这是一个重要的功能。 EDIT--只有在使用new创建MediaPlayer时才需要调用prepare,而不是使用内置的MediaPlayer.Create()。

关于在源之间切换时的问题,我建议调用SeekTo()你要播放的音频中的确切时间,并使用SeekComplete侦听器等待该位置。在评论中,我有一小段hacky代码,直到调用start之后才设置mediaPlayer上的音量。这似乎减少了口吃,但你可能会失去第一小部分音频。

我正在使用Xamarin Studio C#,但即使您使用的是Java,也应该使用相同的方法。

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType (Android.Media.Stream.Music);
mediaPlayer.SetDataSource ("dataSourcePath");

mediaPlayer.Looping = true;

//It is necessary to call prepare after setting the data source
mediaPlayer.Prepare ();

//Ensure the audio has seeked to the position you need
bool seekingComplete = false;
mediaPlayer.SeekComplete += (object sender, EventArgs e) => {
    seekingComplete = true;
};

mediaPlayer.SeekTo(0);

//Forces the audio to complete seeking
while(seekingComplete == false)
{
    //Here, you just wait 2 milliseconds at a time 
    //for this buffering and seeking to complete
    await Task.Delay(2);
}

mediaPlayer.Start();

//Hacky way to prevent the glitch sound at the start is to set the
//volume after calling start
//mediaPlayer.SetVolume(0.4f, 0.4f);

答案 1 :(得分:0)

我遇到了类似的问题,并通过在搜索之前始终暂停媒体播放器来解决了该问题。像下面这样的东西对我有用:

if (mediaPlayer.isPlaying()) {
    mediaPlayer.pause();
    mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete(MediaPlayer mp) {
            mp.start();
            mp.setOnSeekCompleteListener(null);
        }
    });
}
mediaPlayer.seekTo(pos);