即使使用OGG格式,Android MediaPlayer循环也存在空白 [英] Android MediaPlayer loop has gaps even with OGG format

查看:80
本文介绍了即使使用OGG格式,Android MediaPlayer循环也存在空白的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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.

我正在使用三个媒体播放器. mp1mp2mp3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆