android录音播放问题

来源:互联网 发布:触手tv人气软件 编辑:程序博客网 时间:2024/05/16 11:51
最近要做一个录音并且播放的功能,开始用的系统自带的 MediaRecorder,效果一般。
尝试用AudioRecord,在用系统AEC,BS去回音去噪,结果发现效果也是差不多
尝试用WebRtc,结果发现效果也是差不多。
可能跟4.1之后的系统就已经把WebRtc带上了,所以最终还是 MediaRecorder,毕竟它最简单。

播放的时候:
1,需要扬声器和听筒切换,就需要监听距离感应器SensorManager;
2,需要判断耳机插拔状态;
需要注意:
1,mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 
    audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
    始终用这个,因为不用通话模式,听筒的时候声音会很小;
2,需要去注册耳机插拔的广播,因为只是有些机子会插上耳机后会默认耳机播放;
3,最好播放完毕就mediaPlayer.release();mediaPlayer=null;释放资源;
4,部分机型息屏会调Activity的OnPause,所以可能要用到 isScreenOff()判断;
5,音量键调节,是根据audioManager.setMode()方法控制调哪种音量的。所以Activity的OnPause里面要释放到AudioManager.MODE_NORMAL;
     


public class PlayerManager implementsSensorEventListener{
public static final int MODE_SPEAKER = 0;
public static final int MODE_HEADSET = 1;
public static final int MODE_EARPIECE = 2;

private static PlayerManager playerManager;

private Context context;
private AudioManager audioManager;
private MediaPlayer mediaPlayer;
private PlayCallback callback;

private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
private SensorManager sensorManager;
private Sensor sensor;
private HeadsetReceiver headsetReceiver;

private boolean isPause = false;

private String filePath;

private int currentMode = MODE_SPEAKER;

private boolean isScreenOff=false;

public static PlayerManager getManager(){
if (playerManager == null){
synchronized (PlayerManager.class){
playerManager = new PlayerManager();
}
}
return playerManager;
}

private PlayerManager(){
context = BaseApplication.applicationContext;
//    initMediaPlayer();
//    initAudioManager();
}

public String getFilePath() {
return filePath;
}

public boolean isScreenOff() {
return isScreenOff;
}

public void registerSensorListener(){
initSensor();
sensorManager.registerListener(this, sensor,SensorManager.SENSOR_DELAY_NORMAL);
}

public void unregisterSensorListener(){
if(sensorManager != null){
sensorManager.unregisterListener(this);
}
}

public void registerHeadsetReceiver(){
if(headsetReceiver == null){
headsetReceiver = new HeadsetReceiver();
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
context.registerReceiver(headsetReceiver, filter);
}

public void unregisterHeadsetReceiver(){
if(headsetReceiver != null){
context.unregisterReceiver(headsetReceiver);
}
}

private void initSensor() {
if(sensorManager == null){
sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
sensor =sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
}
}

private void initMediaPlayer() {
if(mediaPlayer == null){
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
}
}

private void initAudioManager() {
if(audioManager == null){
audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
}
if (Build.VERSION.SDK_INT >= 11){
          audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
       } else {
      audioManager.setMode(AudioManager.MODE_IN_CALL);
       }
resetPlayMode();
}

public void play(Context context, String path, finalPlayCallback callback){
FileInputStream is = null;
try {
File file = new File(path);
if (file.exists()) {
is = new FileInputStream(file);
FileDescriptor fd = is.getFD();
play(context, fd, 0, 0x7ffffffffffffffL, callback);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(is != null){
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

public void play(Context context, AssetFileDescriptor afd,final PlayCallback callback){
try {
play(context, afd.getFileDescriptor(), afd.getStartOffset(),afd.getLength(), callback);
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
if(afd != null){
afd.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

public void play(Context context, FileDescriptor fd, longoffset, long length, final PlayCallback callback){
this.callback = callback;
try {
initMediaPlayer();
initAudioManager();
intcurrentValue=audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
if(currentValue == 0){
ToastUtil.show(R.string.voice_value_no);
}

mediaPlayer.reset();
mediaPlayer.setDataSource(fd, offset, length);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
@Override
public void onPrepared(MediaPlayer mp) {
if(callback != null){
callback.onPrepared();
}
mediaPlayer.start();

if(TextUtil.isEmpty(SharePreferenceUtil.obtainSharePreference(null,BusinessConstant.Voice_First_Tip))){
SharePreferenceUtil.commitSharePreference(null,BusinessConstant.Voice_First_Tip, "1");
ToastUtil.show(R.string.voice_first_tip);
}
}
});
mediaPlayer.setOnCompletionListener(newMediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
resetPlayMode();
mediaPlayer.release();
mediaPlayer=null;
if(callback != null){
callback.onComplete();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

public boolean isPause(){
return isPause;
}

public void pause(){
if (isPlaying()){
isPause = true;
mediaPlayer.pause();
}
}

public void resume(){
if (isPause && mediaPlayer != null){
isPause = false;
mediaPlayer.start();
}
}

public int getCurrentMode() {
return currentMode;
}

public void changeToEarpieceMode(){
if(audioManager != null){
currentMode = MODE_EARPIECE;
// if (Build.VERSION.SDK_INT >= 11){
//audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
// } else {
// audioManager.setMode(AudioManager.MODE_IN_CALL);
// }
audioManager.setSpeakerphoneOn(false);
}
}

public void changeToHeadsetMode(){
if(audioManager != null){
currentMode = MODE_HEADSET;
// audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);
}
}

public void changeToSpeakerMode(){
if(audioManager != null){
currentMode = MODE_SPEAKER;
// audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(true);
}
}

public void resetPlayMode(){
if(audioManager != null){
if (audioManager.isWiredHeadsetOn()){
changeToHeadsetMode();
} else {
changeToSpeakerMode();
}
}
}

public void stop(){
if (isPlaying()){
try {
mediaPlayer.stop();
if(callback != null){
callback.onStop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

public void stopAndDestroy(){
if (isPlaying()){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
if(callback != null){
callback.onStop();
}
}
}
 
public void destroy(){
stopAndDestroy();
if(audioManager != null){
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager = null;
}
}

public boolean isPlaying() {
return mediaPlayer != null &&mediaPlayer.isPlaying();
}

@Override
public void onSensorChanged(SensorEvent event) {
//耳机模式下直接返回
if (currentMode == MODE_HEADSET){ // || audioManager == null|| audioManager.isWiredHeadsetOn()
return;
}

float value = event.values[0];
if (isPlaying()){
if (value == sensor.getMaximumRange()) {
resetPlayMode();
setScreenOn();
} else {
changeToEarpieceMode();
setScreenOff();
}
} else {
if(value == sensor.getMaximumRange()){
resetPlayMode();
setScreenOn();
}
}
}

private void setScreenOff(){
ZhumaApplication.log("setScreenOff===");
isScreenOff = true;
if (wakeLock == null){
powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
wakeLock =powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,"PlayerManager");
}
wakeLock.acquire();
}

private void setScreenOn(){
ZhumaApplication.log("setScreenOn===");
isScreenOff = false;
if (wakeLock != null){
wakeLock.setReferenceCounted(false);
wakeLock.release();
wakeLock = null;
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy){

}

class HeadsetReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
ZhumaApplication.log("HeadsetReceiver==="+action);
if(Intent.ACTION_HEADSET_PLUG.equals(action)){
int state = intent.getIntExtra("state", 0);
if (state == 1){
changeToHeadsetMode();
} else if (state == 0){
resume();
}
}elseif(AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)){
//拔出耳机会触发此广播,拔出不会触发,且此广播比上一个早,故可在此暂停播放,收到上一个广播时在恢复播放
pause();
changeToSpeakerMode();
}
}
}

public interface PlayCallback{

void onPrepared();

void onComplete();

void onStop();
}


}



0 0