Soundpool 还是 MediaPlayer? - Android
Soundpool or MediaPlayer ? - Android
我对那两个感到很困惑类。
我有 1000 个 .wav 文件,这取决于用户加载不同的声音。
此外,用户可以连续播放多个声音,例如依次播放 4 个声音。
所以我应该使用哪个? SoundPool
对 wav 文件更好,但它加载并保持文件加载并不好。
对于这种情况有什么建议吗?
我在使用 MediaPlayer
的路上完成了它,感谢@blipinsk,在我阅读他在上面的评论中建议的答案 Whosebug 之后。
我的文件有点大,SoundPool 可以接受,而且我想顺序播放很多文件。我必须自己使用 SoundPool 中的线程来实现它。相反,它在 MediaPlayer 中使用 OnCompletionListener 就绪。所以,我使用了 MediaPlayer。
实际上我尝试了带线程的 SoundPool,它可以工作,但由于它不支持大型媒体文件,我使用了 Media Player。
我写的这个class将MediaPlayer包装到运行一个播放列表,你可以添加到播放列表,媒体播放器会一个接一个地运行它们。所以这是 class:
import android.media.MediaPlayer;
import android.os.Environment;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by MBH on 01.08.2015.
*/
public class THSafeListMediaPlayer {
private static final String TAG_DEBUG = "MBH";
private String PATH_OF_SOUND_FILES; // I use it because i will put all sound clips in one folder
// , then i will pass the name of the folder only.
private LinkedBlockingQueue<String> playList;
private MediaPlayer mediaPlayer; // The media player to play the sounds, even in background
private ExecutorService executorService; // For making sure there is only one thread at a time
// adding to the queue
private boolean isPaused = false;
private int pausedPosition = -1;
/**
* Constructor will take care of initializing all the important variables
*/
public THSafeListMediaPlayer() {
// initializing the variables
executorService = Executors.newSingleThreadExecutor();
playList = new LinkedBlockingQueue<>();
mediaPlayer = new MediaPlayer();
PATH_OF_SOUND_FILES = Environment.getExternalStorageDirectory().getPath() + "/mbh/sounds/";
}
/**
* It will only add file to the PlayList
*
* @param fileName: The file name
*/
public void addFile(String fileName) {
// you may add executorService here for safer threads adding here
// here i use offer, because it is thread safe
playList.offer(fileName);
}
/**
* It will add file and play the last add file and continue to the play list
*
* @param fileName: the file name, playing the soundtrack will start from this file
*/
public void addFileAndPlay(final String fileName) {
// For MultiThreaded
// executorService.submit(new Runnable() {
// @Override
// public void run() {
// playList.offer(fileName);
// if (!mediaPlayer.isPlaying())
// play(playList.poll());
// }
// });
// For single threaded
playList.offer(fileName);
if (!mediaPlayer.isPlaying())
play(playList.poll());
}
/**
* Start playing the play list if there is files in the playlist
*
* @return: True if playing successfully done, otherwise, false;
*/
public boolean play() {
if (mediaPlayer != null) {
if (!mediaPlayer.isPlaying()) {
if (isPaused) {
mediaPlayer.seekTo(pausedPosition);
mediaPlayer.start();
pausedPosition = -1;
isPaused = false;
return true;
} else if (!playList.isEmpty()) {
play(playList.poll());
return true;
}
}
}
return false;
}
/**
* Pause the current played track, if there is track playing
*/
public void pause() {
if(isPaused)
return;
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
pausedPosition = mediaPlayer.getCurrentPosition();
isPaused = true;
}
}
}
/**
* it will play the given file, when it finishes, or fails, it will play the next from the list
*
* @param fileName: the file name to start playing from it
*/
private void play(String fileName) {
if (mediaPlayer != null) {
if (!mediaPlayer.isPlaying()) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(fileName);
mediaPlayer.prepare();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
playNextSoundTrack();
}
});
mediaPlayer.start();
} catch (Exception e) {
// TODO: Remove this error checking before publishin
// If the current file is not found, play the next track if there is
playNextSoundTrack();
}
}
}
}
/**
* this function will be called recursively to play the next track
*/
private void playNextSoundTrack() {
if (playList.size() != 0) {
play(playList.poll());
}
}
}
我挣扎了一会儿。希望对其他人有帮助。
注意: 我使用 LinkedBlockingQueue 将播放列表曲目保存在其中,因为它是线程安全的。
如果您想在线程中使用此 class,我建议您使用 executorService
如果您将在多线程应用程序中使用它。
我对那两个感到很困惑类。
我有 1000 个 .wav 文件,这取决于用户加载不同的声音。
此外,用户可以连续播放多个声音,例如依次播放 4 个声音。
所以我应该使用哪个? SoundPool
对 wav 文件更好,但它加载并保持文件加载并不好。
对于这种情况有什么建议吗?
我在使用 MediaPlayer
的路上完成了它,感谢@blipinsk,在我阅读他在上面的评论中建议的答案 Whosebug 之后。
我的文件有点大,SoundPool 可以接受,而且我想顺序播放很多文件。我必须自己使用 SoundPool 中的线程来实现它。相反,它在 MediaPlayer 中使用 OnCompletionListener 就绪。所以,我使用了 MediaPlayer。
实际上我尝试了带线程的 SoundPool,它可以工作,但由于它不支持大型媒体文件,我使用了 Media Player。
我写的这个class将MediaPlayer包装到运行一个播放列表,你可以添加到播放列表,媒体播放器会一个接一个地运行它们。所以这是 class:
import android.media.MediaPlayer;
import android.os.Environment;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by MBH on 01.08.2015.
*/
public class THSafeListMediaPlayer {
private static final String TAG_DEBUG = "MBH";
private String PATH_OF_SOUND_FILES; // I use it because i will put all sound clips in one folder
// , then i will pass the name of the folder only.
private LinkedBlockingQueue<String> playList;
private MediaPlayer mediaPlayer; // The media player to play the sounds, even in background
private ExecutorService executorService; // For making sure there is only one thread at a time
// adding to the queue
private boolean isPaused = false;
private int pausedPosition = -1;
/**
* Constructor will take care of initializing all the important variables
*/
public THSafeListMediaPlayer() {
// initializing the variables
executorService = Executors.newSingleThreadExecutor();
playList = new LinkedBlockingQueue<>();
mediaPlayer = new MediaPlayer();
PATH_OF_SOUND_FILES = Environment.getExternalStorageDirectory().getPath() + "/mbh/sounds/";
}
/**
* It will only add file to the PlayList
*
* @param fileName: The file name
*/
public void addFile(String fileName) {
// you may add executorService here for safer threads adding here
// here i use offer, because it is thread safe
playList.offer(fileName);
}
/**
* It will add file and play the last add file and continue to the play list
*
* @param fileName: the file name, playing the soundtrack will start from this file
*/
public void addFileAndPlay(final String fileName) {
// For MultiThreaded
// executorService.submit(new Runnable() {
// @Override
// public void run() {
// playList.offer(fileName);
// if (!mediaPlayer.isPlaying())
// play(playList.poll());
// }
// });
// For single threaded
playList.offer(fileName);
if (!mediaPlayer.isPlaying())
play(playList.poll());
}
/**
* Start playing the play list if there is files in the playlist
*
* @return: True if playing successfully done, otherwise, false;
*/
public boolean play() {
if (mediaPlayer != null) {
if (!mediaPlayer.isPlaying()) {
if (isPaused) {
mediaPlayer.seekTo(pausedPosition);
mediaPlayer.start();
pausedPosition = -1;
isPaused = false;
return true;
} else if (!playList.isEmpty()) {
play(playList.poll());
return true;
}
}
}
return false;
}
/**
* Pause the current played track, if there is track playing
*/
public void pause() {
if(isPaused)
return;
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
pausedPosition = mediaPlayer.getCurrentPosition();
isPaused = true;
}
}
}
/**
* it will play the given file, when it finishes, or fails, it will play the next from the list
*
* @param fileName: the file name to start playing from it
*/
private void play(String fileName) {
if (mediaPlayer != null) {
if (!mediaPlayer.isPlaying()) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(fileName);
mediaPlayer.prepare();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
playNextSoundTrack();
}
});
mediaPlayer.start();
} catch (Exception e) {
// TODO: Remove this error checking before publishin
// If the current file is not found, play the next track if there is
playNextSoundTrack();
}
}
}
}
/**
* this function will be called recursively to play the next track
*/
private void playNextSoundTrack() {
if (playList.size() != 0) {
play(playList.poll());
}
}
}
我挣扎了一会儿。希望对其他人有帮助。
注意: 我使用 LinkedBlockingQueue 将播放列表曲目保存在其中,因为它是线程安全的。
如果您想在线程中使用此 class,我建议您使用 executorService
如果您将在多线程应用程序中使用它。