package com.metis.base.manager;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.SystemClock;
import android.widget.Toast;
import com.metis.base.utils.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Beak on 2015/8/7.
*/
public class VoiceManager extends AbsManager implements AudioManager.OnAudioFocusChangeListener{
private static final String TAG = VoiceManager.class.getSimpleName();
private static final int MAX_RECORD_DURATION = 60 * 1000;
private static VoiceManager sManager = null;
public static synchronized VoiceManager getInstance (Context context) {
if (sManager == null) {
sManager = new VoiceManager(context.getApplicationContext());
}
return sManager;
}
private AudioManager mAudioManager = null;
private MediaRecorder mRecorder = null;
private boolean isRecording = false;
private OnRecordListener mRecordListener = null;
private String mRecordPath = null;
private long mStartTime = 0;
private MediaPlayer mPlayer = null;
private boolean isPlaying = false;
private String mPlayPath = null;
private OnPlayListener mPlayListener = null;
private MediaRecorder.OnErrorListener mRecordErrorListener = new MediaRecorder.OnErrorListener() {
@Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.v(TAG, "onError what=" + what + " extra=" + extra);
stopRecord();
}
};
private MediaPlayer.OnPreparedListener mPlayerPreparedListener = new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
isPlaying = true;
if (mPlayListener != null) {
mPlayListener.onPlayStart(VoiceManager.this, mp);
}
mUpdateHandler.post(mPlayUpdateRunnable);
/*final int length = mPlayListenerList.size();
for (int i = 0; i < length; i++) {
OnPlayListener listener = mPlayListenerList.get(i);
if (listener != null) {
listener.onPlayStart(mp);
}
}*/
}
};
private MediaPlayer.OnCompletionListener mPlayerCompetionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
stopPlay();
}
};
private Runnable mRecordUpdateRunnable = new Runnable() {
@Override
public void run() {
long currentDuration = SystemClock.elapsedRealtime() - mStartTime;
if (currentDuration > MAX_RECORD_DURATION && isRecording) {
stopRecord();
return;
}
if (mRecordListener != null && isRecording) {
mRecordListener.onRecording(mRecordPath, mRecorder, currentDuration);
}
if (isRecording) {
mUpdateHandler.postDelayed(this, 1000);
}
}
};
private Runnable mPlayUpdateRunnable = new Runnable() {
@Override
public void run() {
if (mPlayListener != null && isPlaying) {
mPlayListener.onPlaying(VoiceManager.this, mPlayPath, mPlayer, mPlayer.getCurrentPosition());//TODO
}
if (isPlaying) {
mUpdateHandler.postDelayed(this, 1000);
}
}
};
private Handler mUpdateHandler = new Handler();
private VoiceManager(Context context) {
super(context);
mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mRecorder = null;
}
public void startRecord (String path) {
mRecorder = new MediaRecorder();
//mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 14800, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_8BIT, 1024 * 128);
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
mRecorder.setOutputFile(path);
mRecordPath = path;
mRecorder.setOnErrorListener(mRecordErrorListener);
/*mRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
}
});*/
int result = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//TODO couldn't get audio focus
Toast.makeText(getContext(), "startRecord result failed", Toast.LENGTH_SHORT).show();
return;
}
doRecord();
Log.v(TAG, "startRecord ");
}
public void stopRecord () {
mRecorder.stop();
mRecorder.reset();
mRecorder.release();
mRecorder = null;
mAudioManager.abandonAudioFocus(this);
isRecording = false;
mUpdateHandler.removeCallbacks(mRecordUpdateRunnable);
if (mRecordListener != null) {
mRecordListener.onRecordStop(mRecordPath, SystemClock.elapsedRealtime() - mStartTime);
}
mRecordPath = null;
mStartTime = 0;
}
private void doRecord () {
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
isRecording = false;
}
mRecorder.start();
isRecording = true;
mStartTime = SystemClock.elapsedRealtime();
if (mRecordListener != null) {
mRecordListener.onRecordStart(mRecordPath);
}
mUpdateHandler.post(mRecordUpdateRunnable);
}
public void startPlay (String path) {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(path);
mPlayPath = path;
mPlayer.setOnPreparedListener(mPlayerPreparedListener);
mPlayer.setOnCompletionListener(mPlayerCompetionListener);
int result = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
//TODO couldn't get audio focus
Toast.makeText(getContext(), "startPlay result failed", Toast.LENGTH_SHORT).show();
return;
}
mPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getPlayingPath () {
return mPlayPath;
}
public void stopPlay () {
mPlayer.stop();
mPlayer.reset();
mPlayer.release();
mPlayer = null;
isPlaying = false;
mPlayPath = null;
mUpdateHandler.removeCallbacks(mPlayUpdateRunnable);
if (mPlayListener != null) {
mPlayListener.onPlayStop(this);
}
/*final int length = mPlayListenerList.size();
for (int i = 0; i < length; i++) {
OnPlayListener listener = mPlayListenerList.get(i);
if (listener != null) {
listener.onPlayStop();
}
}*/
}
public boolean isPlaying () {
return isPlaying;
}
public boolean isRecording () {
return isRecording;
}
@Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
if (isRecording()) {
stopRecord();
}
if (isPlaying()) {
stopPlay();
}
}
Log.v(TAG, "focusChange=" + focusChange);
/*switch (mMode) {
case MODE_RECORD:
doRecord();
break;
case MODE_PLAY_BACK:
break;
}*/
}
public void setOnRecordListener (OnRecordListener listener) {
mRecordListener = listener;
}
public static interface OnRecordListener {
public void onRecordStart (String targetPath);
public void onRecording (String targetPath, MediaRecorder recorder, long currentDuration);
public void onRecordStop (String targetPath, long durationInMills);
}
public void setOnPlayListener (OnPlayListener listener) {
mPlayListener = listener;
}
/*public void registerOnPlayListener (OnPlayListener listener) {
if (mPlayListenerList.contains(listener)) {
return;
}
mPlayListenerList.add(listener);
}
public void unregisterOnPlayListener (OnPlayListener listener) {
if (!mPlayListenerList.contains(listener)) {
return;
}
mPlayListenerList.remove(listener);
}*/
public static interface OnPlayListener {
public void onPlayStart (VoiceManager voiceManager, MediaPlayer player);
public void onPlaying (VoiceManager voiceManager, String targetPath, MediaPlayer mp, long position);
public void onPlayStop (VoiceManager voiceManager);
}
}