android錄音播放問題

最近要做一個錄音並且播放的功能,開始用的系統自帶的 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;
     
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.PowerManager;

import com.qihoo.litegame.BaseApplication;
import com.qihoo.utils.ToastUtil;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;

public class PlayerManager implements SensorEventListener {
    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() {
        LogUtils.d("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() {
        LogUtils.d("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();
            LogUtils.d("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();
    }


}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章