2012-10-09 69 views
1

我喜歡Android Soundpool類,因爲它的簡單性和它在我的應用程序中使用的標準音頻文件效果很好。現在我想讓用戶通過在SD卡上指定音頻文件來指定特定的聲音。不幸的是,我遇到了Soundpool的限制,當聲音文件太大時,我得到一個android音頻 - soundpool替代品

AudioFlinger無法創建軌道。狀態:-12

響應。看來我還沒有進入在MediaPlayer的複雜性前切換到MediaPlayer的一次,我想詢問是否有可用於Android的音頻庫,

  • 具有的Soundpool的簡單播放不同的聲音
  • 犯規Soundpool有關於文件大小的限制。

非常感謝。

馬丁

+0

[This](http://stackoverflow.com/q/6484574/645270)問題可以幫助。我不認爲答案提到了文件大小雖然(但他們沒有提及替代品) – keyser

+0

thx Keyser,我看到這個帖子之前,Jetplayer似乎不是我正在尋找 – dorjeduck

回答

2

現在我來到了該播放音頻添加到其隨後與類的MediaPlayer一個非常簡單的AudioPool類。這個實現肯定不成熟,但我只是想分享它,因爲它至少給出了一些想法,可以輕鬆地解決這個問題。如果您發現此課程有任何問題,請告訴我們。

用法:

AudioPool ap = new AudioPool(); 

File root = Environment.getExternalStorageDirectory() ; 

int id1 = ap.addAudio(root + "/gong1.mp3"); 
int id2 = ap.addAudio(root + "/gong2.mp3"); 
int id3 = ap.addAudio(root + "/gong3.mp3"); 

ap.playAudio(id1); 
ap.playAudio(id3); 
ap.playAudio(id3); 
ap.playAudio(id2); 

將發揮gong1 - 隨後> gong1 - > gong3 - > gong3。因爲這基本上是我需要我把它留在這裏...

import java.util.HashMap; 
import java.util.LinkedList; 
import java.util.Map; 

import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.util.Log; 

public class AudioPool { 

static String TAG = "AudioPool"; 

MediaPlayer mPlayer; 

int mAudioCounter; 

int mCurrentId; 

HashMap<Integer, String> mAudioMap; 

LinkedList<Integer> mAudioQueue; 

public AudioPool() { 

    mAudioMap = new HashMap<Integer, String>(); 
    mAudioQueue = new LinkedList<Integer>(); 
    mAudioCounter = 0; 

} 

public int addAudio(String path) { 
    Log.d(TAG, "adding audio " + path + " to the pool"); 

    if (mAudioMap.containsValue(path)) { 
     return getAudioKey(path); 
    } 
    mAudioCounter++; 
    mAudioMap.put(mAudioCounter, path); 
    return mAudioCounter; 
} 

public boolean playAudio(int id) { 

    if (mAudioMap.containsKey(id) == false) { 
     return false; 
    } 

    if (mPlayer == null) { 
     setupPlayer(); 
    } 

    if (mPlayer.isPlaying() == false) { 
     return prepareAndPlayAudioNow(id); 
    } else { 
     Log.d(TAG, "adding audio " + id + " to the audio queue"); 

     mAudioQueue.add(id); 
    } 
    return true; 
} 

public Integer[] getAudioIds() { 
    return (Integer[]) mAudioMap.keySet().toArray(
      new Integer[mAudioMap.keySet().size()]); 
} 

public void releaseAudioPlayer() { 
    if (mPlayer != null) { 
     mPlayer.release(); 
     mPlayer = null; 
    } 
} 


private boolean prepareAndPlayAudioNow(int id) { 
    mCurrentId = id; 
    try { 
     Log.d(TAG, "playing audio " + id + " now"); 
     mPlayer.reset(); 
     mPlayer.setDataSource(mAudioMap.get(id)); 
     mPlayer.prepare(); 
     mPlayer.start(); 
     return true; 
    } catch (Exception e) { 
     Log.d(TAG, "problems playing audio " + e.getMessage()); 
     return false; 
    } 
} 

private boolean playAudioAgainNow() { 
    try { 
     mPlayer.seekTo(0); 
     mPlayer.start(); 
     return true; 
    } catch (Exception e) { 
     Log.d(TAG, "problems playing audio"); 
     return false; 
    } 
} 

private void setupPlayer() { 
    mPlayer = new MediaPlayer(); 
    mPlayer.setOnCompletionListener(new OnCompletionListener() { 
     @Override 
     public void onCompletion(MediaPlayer mp) { 
      audioDone(); 
     } 
    }); 
} 

private void audioDone() { 

    if (mAudioQueue.size() > 0) { 
     Log.d(TAG, mAudioQueue.size() + " audios in queue"); 
     int nextId = mAudioQueue.removeFirst(); 

     if (mCurrentId == nextId) { 
      playAudioAgainNow(); 
     } else { 
      prepareAndPlayAudioNow(nextId); 
     } 

    } else { 
     releaseAudioPlayer(); 
    } 
} 

private int getAudioKey(String path) { 
    for (Map.Entry<Integer, String> map : mAudioMap.entrySet()) { 
     if (map.getValue().compareTo(path) == 0) { 
      return map.getKey(); 
     } 
    } 
    return -1; 
} 

}