在Android中播放音频太慢了

时间:2011-06-03 03:19:43

标签: android performance media-player delay

我遇到Android的MediaPlayer问题,因为调用prepare方法时速度太慢。我试图简单地保留一些MediaPlayer对象的Vector(带有预加载的数据源),但多次调用.start()会导致奇怪的问题。

第一个问题是它将跳过其他所有游戏,有时游戏会大声播放一半(或更少)。

播放的音调非常短,但需要尽快播放。我的源代码发布在下面。

非常感谢任何帮助。

凯文

package com.atClass.lemon;

import java.util.Vector;

import com.atClass.cardShoe.SettingTools.SETTING_PREF;
import com.atClass.cardShoe.SettingTools.SETTING_STUB;
import com.atClass.cardShoe.SettingTools.SETTING_VALUE;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.util.Config;
import android.util.Log;

public class MediaHandler {
    public static int cRepeat;
    public static float cVolume = Integer.valueOf(Prefs.cPrefsGet.getString(SETTING_PREF.annunciator_volume.name()+SETTING_STUB._int.name(), PrefDefaults.getDefault(SETTING_PREF.annunciator_volume,SETTING_STUB._int)));
    public static boolean cVolumeEnabled = !(Prefs.cPrefsGet.getString(SETTING_PREF.annunciator_volume.name()+SETTING_STUB._value.name(),PrefDefaults.getDefault(SETTING_PREF.annunciator_volume)).equals(SETTING_VALUE.disabled.name()));

    static Vector <MediaPlayer> cQuickMediaPlayerList = new Vector<MediaPlayer>();

    public static enum AUDIO_CLIP {
        app_boot_sound(R.raw.windows_hardware_insert),
        app_results_sound(R.raw.windows_exclamation),
        app_warning_sound(R.raw.windows_hardware_fail),
        app_card_draw_sound(R.raw.fs_beep5),
        app_lid_open_sound(R.raw.windows_hardware_fail),
        app_top_tigger_overdraw_sound(R.raw.fs_beep6),
        test(R.raw.fs_beep4);

        private int enumResourceId;
        AUDIO_CLIP(int input){ enumResourceId = input;}
        int getItem(){return enumResourceId;}
    }

    public static int getAudioClipIndex(AUDIO_CLIP iAudioClip){
        for (int i=0; i<AUDIO_CLIP.values().length; i++){
            if (AUDIO_CLIP.values()[i] == iAudioClip){
                return i;
            }
        }

        return 0;
    }


    public static void setupQuickMediaPlayer(){
        cQuickMediaPlayerList.clear();
        for (int i=0; i<AUDIO_CLIP.values().length; i++){

            MediaPlayer lMediaPlayer = new MediaPlayer();
            final AssetFileDescriptor afd = Global.gContext.getResources().openRawResourceFd(AUDIO_CLIP.values()[i].getItem());
            try{
                lMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                afd.close();
                lMediaPlayer.prepare();
            }catch(Exception e){}
            lMediaPlayer.setVolume(cVolume,cVolume);
            lMediaPlayer.setLooping(false);
            lMediaPlayer.setOnCompletionListener(new OnCompletionListener(){
                @Override
                public void onCompletion(MediaPlayer lMediaPlayer) {
                    lMediaPlayer.release();
                    try{lMediaPlayer.prepare();}catch(Exception e){e.printStackTrace();}
                }});
            cQuickMediaPlayerList.add(lMediaPlayer);
        }
    }

    public static void playAudio(AUDIO_CLIP iAudioClip){
        float volume = cVolume;

        volume++;
        volume /= 10;

        playAudio(iAudioClip,volume);
    }

    public static void playAudio(final AUDIO_CLIP iAudioClip, final float iVolume){

        Thread lThread = new Thread(new Runnable(){
            public void run() {
                //int resourceId = iAudioClip.getItem();                
                Log.d(Global.TAG,"--> Playing audio clip: " + iAudioClip.name() + "," + iAudioClip.getItem() + "," + getAudioClipIndex(iAudioClip));

                if (cVolumeEnabled == true){

                    //Log.d(Global.TAG,"--> Supplying volume: " + iVolume);
                    //Works but is too slow
//                  try {
//                      final MediaPlayer lMediaPlayer = new MediaPlayer();
//                      AssetFileDescriptor afd = Global.gContext.getResources().openRawResourceFd(iAudioClip.getItem());
//                      lMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
//                      afd.close();
//                      lMediaPlayer.prepare();
//                      lMediaPlayer.setVolume(iVolume,iVolume);
//                      lMediaPlayer.setLooping(false);
//                      lMediaPlayer.setOnCompletionListener(new OnCompletionListener(){
//                          @Override
//                          public void onCompletion(MediaPlayer arg0) {
//                              lMediaPlayer.release();
//                          }});
//                      lMediaPlayer.start();
//                  }catch(Exception e){}

                    try{
                        //Works half the time
                        cQuickMediaPlayerList.get(getAudioClipIndex(iAudioClip)).start();
                    }catch(Exception e){}
                }
            }
        });
        lThread.setPriority(Thread.MAX_PRIORITY);
        lThread.start();
    }
}

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:2)

onCompletionListener,您拨打release(),然后拨打prepare()。这是非法的,这可能是你多次启动它们时遇到问题的原因。如果您想再次调用它,请不要使用release(),因为这会释放MP的所有资源,并且只有在您完成时才会调用它。请改用stop()

然而,这仍然不会加速prepare()。您可能希望尝试使用seekTo(0),但即使这样,它也可能没有您想要的那么快。这实际上取决于你谈论的速度。