2012-10-09 72 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; 
} 

}