Sai*_*Sai 31 android android-audiomanager
我已经尝试了几乎所有方法,但是我无法在循环单个轨道之间实现无间隙音频播放,持续时间为10-15秒.
我尝试过的步骤失败了:
不同的音频文件格式.mp3 .wav .ogg使用
setLooping(true):
MediaPlayer mp1 = MediaPlayer.create(MainActivity.this, R.raw.track1);
mp1.setLooping(true);
mp1.start();
Run Code Online (Sandbox Code Playgroud)创建两个媒体播放器并使用setOnCompletionListener相同的循环逐个循环
无法循环无间隙.
使用setNextMediaPlayer(nextmp)它的工作方式,但只有两个循环是可能的.在完成前两个循环后,我们必须准备并重新开始.
mp1.start();
mp1.setNextMediaPlayer(mp2);
Run Code Online (Sandbox Code Playgroud)更新: @Jeff Mixon的结果回答: Mediaplayer循环因Android错误而停止.Jeff Mixon工作正常,但之后只有10或20个循环,由于一些垃圾收集问题,Mediaplayers会立即停止离开日志,如下所示.我真的有点困在这里2年了.提前致谢.
E/MediaPlayer(24311): error (1, -38)
E/MediaPlayer(23256): Error(1,-1007)
E/MediaPlayer(23546): Error (1,-2147483648)
Run Code Online (Sandbox Code Playgroud)Mat*_*ini 32
从我所做的测试来看,这个解决方案运行良好,150个循环和13秒160 kbps MP3没有任何问题:
public class LoopMediaPlayer {
public static final String TAG = LoopMediaPlayer.class.getSimpleName();
private Context mContext = null;
private int mResId = 0;
private int mCounter = 1;
private MediaPlayer mCurrentPlayer = null;
private MediaPlayer mNextPlayer = null;
public static LoopMediaPlayer create(Context context, int resId) {
return new LoopMediaPlayer(context, resId);
}
private LoopMediaPlayer(Context context, int resId) {
mContext = context;
mResId = resId;
mCurrentPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mCurrentPlayer.start();
}
});
createNextMediaPlayer();
}
private void createNextMediaPlayer() {
mNextPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setNextMediaPlayer(mNextPlayer);
mCurrentPlayer.setOnCompletionListener(onCompletionListener);
}
private MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
mCurrentPlayer = mNextPlayer;
createNextMediaPlayer();
Log.d(TAG, String.format("Loop #%d", ++mCounter));
}
};
}
Run Code Online (Sandbox Code Playgroud)
要使用LoopMediaPlayer你可以打电话:
LoopMediaPlayer.create(context, R.raw.sample);
Run Code Online (Sandbox Code Playgroud)
Jef*_*xon 13
丑陋的概念证明代码,但你会明白:
// Will need this in the callbacks
final AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.sample);
// Build and start first player
final MediaPlayer player1 = MediaPlayer.create(this, R.raw.sample);
player1.start();
// Ready second player
final MediaPlayer player2 = MediaPlayer.create(this, R.raw.sample);
player1.setNextMediaPlayer(player2);
player1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
// When player1 completes, we reset it, and set up player2 to go back to player1 when it's done
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
player2.setNextMediaPlayer(player1);
}
});
player2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
// Likewise, when player2 completes, we reset it and tell it player1 to user player2 after it's finished again
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
player1.setNextMediaPlayer(player2);
}
});
// This loop repeats itself endlessly in this fashion without gaps
Run Code Online (Sandbox Code Playgroud)
这适用于API 19设备和5秒128 kbps MP3.循环中没有间隙.
至少就KitKat而言,Mattia Maestrini的答案(对此问题)是我发现的唯一解决方案,该解决方案可以对大型(> 1Mb未压缩)音频样本进行无间隙循环。我试过了:
通过简单地将Maestrini的LoopMediaPlayer类包括在我的项目中,然后用MediaPlayer.create()调用替换LoopMediaPlayer.create()调用,我可以确保.OGG示例被无缝循环。 LoopMediaPlayer因此,这是一个值得称赞的实用且透明的解决方案。
但是这种透明性引出了一个问题:一旦我将MediaPlayer调用交换为LoopMediaPlayer调用,实例调用MediaPlayer方法(如)将如何进行。isPlaying,.pause还是.setVolume? 以下是我针对此问题的解决方案。也许可以由比我更精通Java的人来改进它(我欢迎他们的投入),但是到目前为止,我发现这是一个可靠的解决方案。
我对Maestrini班级所做的唯一更改(除了Lint建议的一些调整之外)在下面的代码结尾处进行了标记;其余内容包括在内。我除了是落实的几种方法MediaPlayer中LoopMediaPlayer调用它们mCurrentPlayer。
警告:虽然我实现了MediaPlayer以下几种有用的方法,但并未实现所有这些方法。 因此,如果您希望例如打电话给.attachAuxEffect您,则需要按照我添加的内容自行添加此方法LoopMediaPlayer。确保复制这些方法的原始接口(即,Parameters,Throws和Returns):
public class LoopMediaPlayer {
private static final String TAG = LoopMediaPlayer.class.getSimpleName();
private Context mContext = null;
private int mResId = 0;
private int mCounter = 1;
private MediaPlayer mCurrentPlayer = null;
private MediaPlayer mNextPlayer = null;
public static LoopMediaPlayer create(Context context, int resId) {
return new LoopMediaPlayer(context, resId);
}
private LoopMediaPlayer(Context context, int resId) {
mContext = context;
mResId = resId;
mCurrentPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mCurrentPlayer.start();
}
});
createNextMediaPlayer();
}
private void createNextMediaPlayer() {
mNextPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setNextMediaPlayer(mNextPlayer);
mCurrentPlayer.setOnCompletionListener(onCompletionListener);
}
private final MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
mCurrentPlayer = mNextPlayer;
createNextMediaPlayer();
Log.d(TAG, String.format("Loop #%d", ++mCounter));
}
};
// code-read additions:
public boolean isPlaying() throws IllegalStateException {
return mCurrentPlayer.isPlaying();
}
public void setVolume(float leftVolume, float rightVolume) {
mCurrentPlayer.setVolume(leftVolume, rightVolume);
}
public void start() throws IllegalStateException {
mCurrentPlayer.start();
}
public void stop() throws IllegalStateException {
mCurrentPlayer.stop();
}
public void pause() throws IllegalStateException {
mCurrentPlayer.pause();
}
public void release() {
mCurrentPlayer.release();
mNextPlayer.release();
}
public void reset() {
mCurrentPlayer.reset();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6472 次 |
| 最近记录: |