即使使用OGG格式,Android MediaPlayer循环也存在空白 [英] Android MediaPlayer loop has gaps even with OGG format
问题描述
在Android 4.x中,我的音频循环应用在声音循环中存在0.2到0.5秒的间隔.
In Android 4.x my audio looping app has 0.2 to 0.5 second gaps in the sound loops.
我正在使用MediaPlayer,因为我的声音可能很大(在某些情况下,每次声音为2-3mb),并且可以同时运行多个实例.
I'm using MediaPlayer as my sounds can be quite large (2-3mb each in some cases) and it can run multiple instances at the same time.
我对此进行了相当多的研究,发现Android 4.x有一个错误...但是,我尝试了许多变通方法,但似乎其中的任何一个都无法正常工作.
I have researched this quite a bit and I see there is a bug for Android 4.x... however, I have tried many work arounds and I can't seem to get any of them working.
- 使用Audacity(质量等级2到10,没关系)将所有wavs转换为OGG
- 尝试过setNextMediaPlayer()
- 试图在停止并重复上使用seekTo(0)
- 尝试了具有自己的bug的soundPool
以下是我正在使用的代码示例:
Here's a sample of the code I'm using:
public class SoundPlayer implements OnCompletionListener {
private MediaPlayer mp = null;
public void initPlayer() {
if(mp == null) {
mp = new MediaPlayer();
}
}
public void prepare(Context context, int resource) {
initPlayer();
try{
mp.reset();
Uri uri = Uri.parse("android.resource://com.myapp.app/"+resource);
mp.setDataSource(context,uri);
mp.prepare();
isPrepared = true;
mp.setOnCompletionListener(this);
} catch(Exception e) {
e.printStackTrace();
}
}
.......... etc (Uses typical MediaPlayer methods such as stop(), start(), setLooping(true)
}
我没有使用任何特别的东西,所以我只是想知道是否有人知道可以解决Android上的循环错误.
I'm not using anything special, so I'm just wondering if anyone knows of a work around for the looping bug on Android.
推荐答案
好的旧帖子,但是此解决方案有效.这是一种骇客.如果有人来回答这个问题,将会有所帮助.
Okay old Post, but this solution works. This is kind of hack. It'll help somebody if somebody came to this answer.
我正在使用三个媒体播放器. mp1
,mp2
,mp3
. mp1
开始播放,我将mp2
设置为其setNextMediaPlayer
.当mp1
结束时,我将mp3
设置为mp2's
setNextMediaPlayer
.当mp2
结束时,我将mp1
设置为mp3's
setNextMediaPlayer
.以下是播放暂停,停止,设置音量的完整代码.只需创建一个对象BZMediaPlayer
,通过提供uri
或资源ID即可开始.
I am just using three media players. mp1
, mp2
, mp3
. mp1
gets play, and I set mp2
to its setNextMediaPlayer
. when mp1
ends, I set mp3
to mp2's
setNextMediaPlayer
. when mp2
ends, I set mp1
to mp3's
setNextMediaPlayer
. Following is the complete code which play pause, stop, set vol. Just create an object BZMediaPlayer
, start it by providing uri
, or resource id.
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.util.Log;
public class BZMediaPlayer {
private Context context;
private Uri uri;
private int resourceId;
// which file is getting played
public static final int URI_PLAYING = 1;
public static final int RESOURCE_PLAYING = 2;
private int filePlaying;
// states of the media player
public static final int STATE_PLAYING = 1;
public static final int STATE_PAUSED = 2;
public static final int STATE_STOP = 3;
// current state
private int state = STATE_STOP;
// current mediaPlayer which is playing
private int mediaPlayerIndex = -1;
// 3 media players
private MediaPlayer mp[] = new MediaPlayer[3];
// current volume
private float vol;
public BZMediaPlayer(Context context) {
this.context = context;
}
/**
* plays the provided uri
* @param uri
*/
public void play(Uri uri) {
this.uri = uri;
// current playing file
filePlaying = URI_PLAYING;
// stop any playing session
stop();
// initialize and set listener to three mediaplayers
for (int i = 0; i < mp.length; i++) {
mp[i] = MediaPlayer.create(context, uri);
mp[i].setOnCompletionListener(completionListener);
}
// set nextMediaPlayers
mp[0].setNextMediaPlayer(mp[1]);
mp[1].setNextMediaPlayer(mp[2]);
// start the first MediaPlayer
mp[0].start();
// set mediaplayer inex
mediaPlayerIndex = 0;
// set state
state = STATE_PLAYING;
}
/**
* play file from resource
* @param resourceId
*/
public void play(int resourceId) {
this.resourceId = resourceId;
filePlaying = RESOURCE_PLAYING;
stop();
for (int i = 0; i < mp.length; i++) {
mp[i] = MediaPlayer.create(context, resourceId);
mp[i].setOnCompletionListener(completionListener);
}
mp[0].setNextMediaPlayer(mp[1]);
mp[1].setNextMediaPlayer(mp[2]);
mp[0].start();
mediaPlayerIndex = 0;
state = STATE_PLAYING;
}
/**
* play if the mediaplayer is pause
*/
public void play() {
if (state == STATE_PAUSED) {
mp[mediaPlayerIndex].start();
Log.d("BZMediaPlayer", "playing");
state = STATE_PLAYING;
}
}
/**
* pause current playing session
*/
public void pause() {
if (state == STATE_PLAYING) {
mp[mediaPlayerIndex].pause();
Log.d("BZMediaPlayer", "pausing");
state = STATE_PAUSED;
}
}
/**
* get current state
* @return
*/
public int getState() {
return state;
}
/**
* stop every mediaplayer
*/
public void stop() {
for(int i = 0 ; i < mp.length ; i++) {
if (mp[i] != null) {
mp[i].stop();
if(mp[i].isPlaying()) {
mp[i].release();
}
}
}
state = STATE_STOP;
}
/**
* set vol for every mediaplayer
* @param vol
*/
public void setVol(float vol) {
this.vol = vol;
for(int i = 0 ; i < mp.length ; i++) {
if (mp[i] != null && mp[i].isPlaying()) {
mp[i].setVolume(vol, vol);
}
}
}
/**
* internal listener which handles looping thing
*/
private MediaPlayer.OnCompletionListener completionListener = new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer curmp) {
int mpEnds = 0;
int mpPlaying = 0;
int mpNext = 0;
if(curmp == mp[0]) {
mpEnds = 0;
mpPlaying = 1;
mpNext = 2;
}
else if(curmp == mp[1]) {
mpEnds = 1;
mpPlaying = 2;
mpNext = 0; // corrected, else index out of range
}
else if(curmp == mp[2]) {
mpEnds = 2;
mpPlaying = 0; // corrected, else index out of range
mpNext = 1; // corrected, else index out of range
}
// as we have set mp2 mp1's next, so index will be 1
mediaPlayerIndex = mpPlaying;
Log.d("BZMediaPlayer", "Media Player " + mpEnds);
try {
// mp3 is already playing release it
if (mp[mpNext] != null) {
mp[mpNext].release();
}
// if we are playing uri
if (filePlaying == URI_PLAYING) {
mp[mpNext] = MediaPlayer.create(context, uri);
} else {
mp[mpNext] = MediaPlayer.create(context, resourceId);
}
// at listener to mp3
mp[mpNext].setOnCompletionListener(this);
// set vol
mp[mpNext].setVolume(vol, vol);
// set nextMediaPlayer
mp[mpPlaying].setNextMediaPlayer(mp[mpNext]);
// set nextMediaPlayer vol
mp[mpPlaying].setVolume(vol, vol);
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
希望它将对某人有帮助
Edit: clean code
这篇关于即使使用OGG格式,Android MediaPlayer循环也存在空白的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!