2013-07-05 26 views

回答

2

有两种方法,我可以看到这个工作:使用MediaPlayerSoundPool

MediaPlayer的

您可以使用MediaPlayer.OnCompletionListener与文件的列表相结合,简单地监听完成和播放下一一。总的来说,这种方式效果很好,我用它可以播放非常短的片段(< 1s),没有问题。

的Soundpool

另一种方法是使用SoundPool类与处理器相结合,只需提前排队玩法事件。这假定你知道每个剪辑的长度,但取决于你应该能够找到的格式。

您选择哪种解决方案取决于多种因素:有多少文件,他们是多么短暂,它们是什么格式,你在哪里,如何固定或可变的名单是让他们等

个人我会去与MediaPlayer,因为这是更容易实施,并会可能符合您的需求。

+0

我的剪辑是最多几秒钟。然后我会先试用MediaPlayer。 –

+0

现在看起来MediaPlayer方法工作得不错。谢谢! –

+0

很高兴听到它!你可以随时让它更复杂:) –

1

一种方法是将它们连接成一个音频文件,然后为它创建一个MediaPlayer并设置一个OnSeekCompleteListener。按照您喜欢的顺序搜索每个片段,然后在onSeekComplete()中播放它们。它的时间不准确,MediaPlayer使用起来很敏感,所以它可能不是您的最佳选择,但它足够满足我的目的。

这里是我的代码:

private MediaPlayer MP = new MediaPlayer(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    //... 

    FileDescriptor fd = getResources().openRawResourceFd(R.raw.pronounciations).getFileDescriptor(); 
    try { 
     setVolumeControlStream(AudioManager.STREAM_MUSIC); // Lets the user control the volume. 
     MP.setDataSource(fd); 
     MP.setLooping(false); 
     MP.prepare(); 
     MP.start(); // HACK! Some playing seems required before seeking will work. 
     Thread.sleep(60); // Really need something like MediaPlayer.bufferFully(). 
     MP.pause(); 
     MP.setOnErrorListener(new OnErrorListener() { 
      public boolean onError(MediaPlayer mp, int what, int extra) { 
       return false; 
      } 
     }); 
     MP.setOnSeekCompleteListener(new OnSeekCompleteListener() { 
      public void onSeekComplete(MediaPlayer mp) { 
       // The clip is queued up and read to play. 
       // I needed to do this in a background thread for UI purposes. 
       // You may not need to. 
       new Thread() { 
        @Override 
        public void run() { 
         MP.start(); 
         try { 
          Thread.sleep(soundRanges[curWordID][1]); 
         } catch(InterruptedException e) {} 
         MP.pause(); 
        } 
       }.start(); 
      } 
     }); 
    } catch(Throwable t) {} 
} 

private void playCurrentWord() { 
    if(soundRanges != null && !MP.isPlaying() && !silentMode) { 
     try { 
      MP.seekTo(soundRanges[curWordID][0]); 
     } 
     catch(Throwable t) {} 
    } 
} 

你可能会需要使用外部声音编辑工具来连接您的剪辑。我使用Audacity来查找和编辑我保存在文件中的剪辑开始和长度。

soundRanges [curWordID] [0]是剪辑开始声音文件中的偏移量,soundRanges [curWordID] [1]是其长度。

+0

你可以详细说明这种方法吗?你在内存中连接这个吗?我还没有找到支持从内存播放的API,它总是需要某种文件描述符。 –

+1

好吧,我编辑添加相关代码片段,但它看起来像你已经有一个不需要串联的解决方案。 –

+0

哇真棒,要尽快尝试! –