使用Androids Audiotrack的最佳方式
我正在实现一个Android应用程序来处理PCM声音数据(用于长声音,即音乐曲目)。 我决定使用AudioTrack类来播放音乐,但它不能与活动放在同一个线程中,因为它会阻塞整个应用程序——问题是——我应该将AudioTrack操作放在单独的线程中还是放在异步任务(或任何其他选项)中?最好的办法是什么? 我需要播放/暂停/停止并更改音乐文件 现在我正试图通过java线程来管理它,它几乎正常-播放是正常的,几乎暂停(它“删除”了一部分声音),但当我更改音乐文件时,上一个没有停止,并且有混合输出(我认为我的线程实现有问题) 和-不,我不能在此应用程序中使用MediaPlayer(我想动态修改PCM数据) 我在谷歌和stackoverflow上搜索了一些帮助,但没有任何帮助 这是我当前的实现,如果有人想看看的话使用Androids Audiotrack的最佳方式,android,multithreading,pcm,audiotrack,Android,Multithreading,Pcm,Audiotrack,我正在实现一个Android应用程序来处理PCM声音数据(用于长声音,即音乐曲目)。 我决定使用AudioTrack类来播放音乐,但它不能与活动放在同一个线程中,因为它会阻塞整个应用程序——问题是——我应该将AudioTrack操作放在单独的线程中还是放在异步任务(或任何其他选项)中?最好的办法是什么? 我需要播放/暂停/停止并更改音乐文件 现在我正试图通过java线程来管理它,它几乎正常-播放是正常的,几乎暂停(它“删除”了一部分声音),但当我更改音乐文件时,上一个没有停止,并且有混合输出(我
public class AudioPlayerManager {
private AudioTrack track;
private Thread thread;
private AudioTrackThread trackThread = new AudioTrackThread();
public int getPlayState() {
return track.getPlayState();
}
public int getAudioSession() {
return track.getAudioSessionId();
}
class AudioTrackThread implements Runnable {
private String filePath = "/music/wav/musicfile.wav";
@Override
public void run() {
try {
playWaveFile();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void playWaveFile() throws FileNotFoundException {
int minSize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, minSize,
AudioTrack.MODE_STREAM);
File file = new File(FileListingUtils.getExternalStorageRootFile(),
filePath);
InputStream is = new FileInputStream(file);
byte[] music = new byte[512];
track.play();
try {
handleSound(is, music);
} catch (IOException e) {
e.printStackTrace();
}
track.stop();
track.release();
}
private void handleSound(InputStream is, byte[] music)
throws IOException {
int i;
while ((i = is.read(music)) != -1) {
track.write(music, 0, i);
}
}
}
public void playNew() {
if (track != null) {
track.stop();
//track.flush();
track.release();
}
thread = new Thread(trackThread);
thread.start();
}
public void playOrResume() {
this.track.play();
}
public void pause() {
this.track.pause();
}
}
谢谢你的帮助
M.您的线程生命周期似乎不正确。首先,您必须在每次播放停止或完成时关闭(中断)当前线程,并创建线程的新实例并关闭旧线程 其次,您正在从线程外部调用
track.stop()
。您必须在线程中实现公共停止方法,然后在其中插入最终代码,然后在playNew()方法中调用yourthread.stop()
下面是伪代码:
public void playNew() {
//the following if clause should go to thread's stop() method.
// if (track != null) {
// track.stop();
//track.flush();
// track.release();
// }
//create a new thread if its null
if(thread ==null){
thread = new Thread(new AudioTrackThread());
thread.start();}
//stop the current thread
else{
thread.stop();
thread=null;}
}
关于您的实现,我在某处读到,播放音乐、服务和线程将是一个更好的选择。请阅读中的服务和线程。您的线程生命周期似乎不正确。首先,您必须在每次播放停止或完成时关闭(中断)当前线程,并创建线程的新实例并关闭旧线程 其次,您正在从线程外部调用
track.stop()
。您必须在线程中实现公共停止方法,然后在其中插入最终代码,然后在playNew()方法中调用yourthread.stop()
下面是伪代码:
public void playNew() {
//the following if clause should go to thread's stop() method.
// if (track != null) {
// track.stop();
//track.flush();
// track.release();
// }
//create a new thread if its null
if(thread ==null){
thread = new Thread(new AudioTrackThread());
thread.start();}
//stop the current thread
else{
thread.stop();
thread=null;}
}
关于您的实现,我在某处读到,播放音乐、服务和线程将是一个更好的选择。请阅读中的服务和线程。谢谢您的回复!但不幸的是,效果是一样的。我对我的实现做了一点修改,现在除了加载下一个曲目外,一切都很好。但我以后会回到这个问题上来。谢谢不客气。请发布您的答案,这可能对其他人有帮助。答案在哪里?谢谢您的回复!但不幸的是,效果是一样的。我对我的实现做了一点修改,现在除了加载下一个曲目外,一切都很好。但我以后会回到这个问题上来。谢谢不客气。请张贴您的答案,这可能对其他人有帮助。请问答案在哪里?