2011-06-03 134 views
3

我在Android的MediaPlayer中遇到問題,因爲調用prepare方法時它太慢了。我試圖簡單地保留少數MediaPlayer對象(使用它們的預加載數據源)的向量,但多次調用.start()會導致奇怪的問題。在Android中播放音頻太慢

第一個問題是它會跳過每一個其他的遊戲,有時候這個遊戲會有一半(或更少)的聲音。

演奏的音色非常短,但需要儘快播放。我的源代碼發佈在下面。

任何幫助是極大的讚賞。

凱文

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

在你onCompletionListener,你叫release(),其次是prepare()。這是非法的,可能是你多次啓動問題的原因。如果你想再次打電話,不要使用release(),因爲這樣可以釋放MP的所有資源,只有當你使用完成時才能調用它。改爲使用stop()。但是,這仍然不會加快prepare()。您可能想嘗試seekTo(0),但即使如此,它也可能不如您想要的那麼快。這取決於你談論的速度有多快。

+0

嗨GeoBits。感謝您對此問題的快速回復。我將嘗試使用stop()而不是release()和prepare()。謝謝,凱文 – 2011-06-04 16:55:26