Слишком медленное воспроизведение звука в Android - PullRequest
3 голосов
/ 03 июня 2011

У меня проблема с MediaPlayer для Android в том, что он слишком медленный при вызове метода prepare. Я попытался просто сохранить вектор нескольких объектов MediaPlayer (с их предварительно загруженными источниками данных), но многократный вызов .start () приводит к странным проблемам.

Первая проблема заключается в том, что она пропускает каждую другую игру, а иногда игра будет вдвое (или меньше) громче.

Воспроизводимые тоны очень короткие, но их необходимо воспроизвести как можно быстрее. Мой исходный код размещен ниже.

Любая помощь очень ценится.

Kevin

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 ]

2 голосов
/ 03 июня 2011

В вашем onCompletionListener вы звоните release(), а затем prepare().Это незаконно, и, вероятно, именно поэтому у вас возникают проблемы с их многократным запуском.Если вы хотите вызвать его снова, не используйте release(), потому что это освобождает все ресурсы для MP и должно вызываться только тогда, когда вы сделали с ним.Вместо этого используйте stop().

Однако это все равно не ускорит prepare().Возможно, вы захотите попробовать seekTo(0), но даже тогда это может быть не так быстро, как вы хотите.Это действительно зависит от того, как быстро вы говорите.

2 голосов
/ 03 июня 2011

Вы должны использовать SoundPool вместо: http://developer.android.com/reference/android/media/SoundPool.html

...