录音时候音频的外放

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了录音时候音频的外放相关的知识,希望对你有一定的参考价值。

参考技术A AVAudiosession*audioSession=[AVAudioSessionsharedInstance];

//1.设置为播放和录音状态,以便可以在录制完之后播放录音AVAudioSessionCategoryAmbient AVAudioSessionCategoryPlayAndRecord

[audioSessionsetCategory:AVAudioSessionCategoryPlayAndRecorderror:nil];

[audioSessionsetActive:isActiveerror:nil];

[audioSessionoverrideOutputAudioPort:AVAudioSessionPortOverrideSpeakererror:nil];

//2.这个方法相当于上面方法的和但是比overrideOutputAudioPort时效性更长

//[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];

UInt32doChangeDefaultRoute =1;

//3.下面方法相当于overrideOutputAudioPort但实效性更长会影响其他应用音频的使用

//kAudioSessionProperty_OverrideAudioRoute kAudioSessionProperty_OverrideCategoryDefaultToSpeaker

AudioSessionSetProperty(

kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,

sizeof(doChangeDefaultRoute),

&doChangeDefaultRoute

);

//加两个地址

http://blog.csdn.net/xy5811/article/details/8563137

https://developer.apple.com/library/content/qa/qa1754/_index.html

Android MediaPlayer播放 听筒外放切换

Android MediaPlayer播放 听筒外放切换,通过注册监听,来判断是否靠近听筒。

结合mediaplayer坐音频播放,Android hardware搞一个根据光感听筒外放切换。
MediaManager是播放器构建模式,维护了一个MediaPlayer,用来重新处理播放器。

MediaManager.builder()
                        .setContext(MainActivity.this)
                        .setDebugModel(true)
                        .setMediaListener(new MediaCallBack() {
                            @Override
                            public void progress(int i, int max) {

                            }

                            @Override
                            public void prepare(int duration, String time) {

                            }

                            @Override
                            public void start() {

                            }

                            @Override
                            public void end() {

                            }

                            @Override
                            public void stop() {

                            }
                        })
                        .setUrl("https://96.f.1ting.com/local_to_cube_202004121813/96kmp3/2020/09/21/21e_wc/01.mp3")
                        .build();

开始播放

                MediaManager.start();

停止

                MediaManager.stop();

是否正在播放

                MediaManager.isPlaying();

暂停

                MediaManager.pause();

继续

                MediaManager.resume();

销毁当前的mediaplayer destory时候调用

                MediaManager.removeAll();

AudioManager

Android为我们提供的(音量大小控制)的API: AudioManager(音频管理器)了,该类位于Android.Media包下,提供了音量控制与铃声模式相关操作。

获得AudioManager对象实例

AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);

PowerManager

Android系统为我们提供的电源管理的一个API,其相关接口与设备电池的续航能力有很大的关联, 官方也说了,除非是迫不得已吧,不然的话,应该尽量避免使用这个类,并且使用完以后一定要及时释放。所谓的电源管理包括:CPU运行,键盘或者屏幕亮起来!核心其实就是wakelock锁机制,只要我们拿着这个锁, 那么系统就无法进入休眠状态,可以给用户态程序或内核获取到。锁可以是:”有超时的“或者 “没有超时“,超时的锁到时间后会自动解锁,如果没有了锁或超时,内核会启动休眠机制来进入休眠。

添加权限

    <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

获取PowerManager对象实例

 powerManager = (PowerManager) getActivity().getSystemService(POWER_SERVICE);

整体的代码如下:


/**
 * Created by SHICHENG
 * <p>
 * Time on 2021/11/08
 */
public class AudioSensorBinder implements LifecycleObserver, SensorEventListener {

    public final String TAG = this.getClass().getSimpleName();

    private final AudioManager audioManager;
    private final PowerManager powerManager;

    @Nullable
    private WeakReference<AppCompatActivity> activity;
    private SensorManager sensorManager;
    private Sensor sensor;
    private PowerManager.WakeLock wakeLock;

    @RequiresApi(api = Build.VERSION_CODES.M)
    public AudioSensorBinder(@Nullable AppCompatActivity mActivity) {
        this.activity = new WeakReference<>(mActivity);
        //可以监听生命周期
        if (getActivity()!=null){
            getActivity().getLifecycle().addObserver(this);
        }
        audioManager = (AudioManager) getActivity().getSystemService(AUDIO_SERVICE);
        powerManager = (PowerManager) getActivity().getSystemService(POWER_SERVICE);
        registerProximitySensorListener();
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {

    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        sensorManager.unregisterListener(this);
        sensorManager = null;
        wakeLock = null;
        activity = null;
    }
    /**
     * 注册距离感应器监听器,监测用户是否靠近手机听筒
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void registerProximitySensorListener() {
        if ( getActivity() == null) {
            return;
        }
        sensorManager = (SensorManager) getActivity().getSystemService(SENSOR_SERVICE);
        if (sensorManager == null) {
            return;
        }
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }


    private AppCompatActivity getActivity() {
        if (activity != null) {
            return activity.get();
        }
        return null;
    }


    @Override
    public void onSensorChanged(SensorEvent event) {
        if (audioManager == null) {
            return;
        }
        if (isHeadphonesPlugged()) {
            // 如果耳机已插入,设置距离传感器失效
            return;
        }
        if (true) {
            Log.i(TAG, "onSensorChanged: " + MediaManager.isPlaying() + " event.values[0]: " + event.values[0]);
        }
        if (MediaManager.isPlaying()) {
            // 如果音频正在播放
            float distance = event.values[0];
            if (distance >= sensor.getMaximumRange()) {
                // 用户远离听筒,音频外放,亮屏
                changeToSpeaker();
                if (true) {
                    Log.i(TAG, "onSensorChanged: 外放");
                }
            } else {
                MediaManager.resume();
                // 用户贴近听筒,切换音频到听筒输出,并且熄屏防误触
                changeToReceiver();
                if (true) {
                    Log.i(TAG, "onSensorChanged: 听筒");
                }
                audioManager.setSpeakerphoneOn(false);
            }
        } else {
            // 音频播放完了
            changeToSpeaker();
        }
    }

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

    }

    @SuppressLint("WrongConstant")
    private boolean isHeadphonesPlugged() {
        if (audioManager == null) {
            return false;
        }
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            AudioDeviceInfo[] audioDevices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
            for (AudioDeviceInfo deviceInfo : audioDevices) {
                if (deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
                        || deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
                    return true;
                }
            }
            return false;
        } else {
            return audioManager.isWiredHeadsetOn();
        }
    }

    /**
     * 切换到外放
     */
    public void changeToSpeaker() {
        setScreenOn();
        if (audioManager == null) {
            return;
        }
        audioManager.setMode(AudioManager.MODE_NORMAL);
        audioManager.setSpeakerphoneOn(true);
    }

    /**
     * 切换到耳机模式
     */
    public void changeToHeadset() {
        if (audioManager == null) {
            return;
        }
        audioManager.setSpeakerphoneOn(false);
    }

    /**
     * 切换到听筒
     */
    public void changeToReceiver() {
        setScreenOff();
        if (audioManager == null) {
            return;
        }
        audioManager.setSpeakerphoneOn(false);
        audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
    }

    private void setScreenOff() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Log.i(TAG, "setScreenOff: 熄灭屏幕");
            if (wakeLock == null) {
                wakeLock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
            }
            wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/);
        }
    }

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

MediaManager


/**
 * Created by SHICHENG
 * <p>
 * Time on 2021/11/08
 */
public class MediaManager {

    private static MediaManagerBuilder mediaManagerBuilder;

    public static MediaManagerBuilder builder() {
        mediaManagerBuilder = new MediaManagerBuilder();
        return mediaManagerBuilder;
    }

    public static void start(){
        mediaManagerBuilder.start();
    }

    public static boolean isPlaying(){
        if (mediaManagerBuilder!=null){
            return mediaManagerBuilder.isPlaying();
        }
        return false;
    }

    public static void stop(){
        if (mediaManagerBuilder!=null){
            mediaManagerBuilder.stop();
        }
    }

    public static void pause(){
        if (mediaManagerBuilder!=null){
            mediaManagerBuilder.pause();
        }
    }

    public static void resume(){
        if (mediaManagerBuilder!=null){
            mediaManagerBuilder.resume();
        }
    }
    public static void removeAll(){
        if (mediaManagerBuilder!=null){
            mediaManagerBuilder.removeAll();
        }
    }

    public static class MediaManagerBuilder{

        public final String TAG = this.getClass().getSimpleName();
        private Handler handler = new Handler();
        private boolean isSeekBarChanging;//互斥变量,防止进度条与定时器冲突。

        private Context context;
        private MediaConfig config;
        private MediaCallBack mediaListener;
        private MediaPlayer mediaPlayer;
        private boolean DEBUG = false;
        private SimpleDateFormat format;
        private Timer timer;
        private TimerTask timerTask;
        private SeekBar seekBar;

        private MediaManagerBuilder() {
            this.config = new MediaConfig();
            this.mediaPlayer = new MediaPlayer();
            this.format = new SimpleDateFormat("mm:ss");
        }

        /**
         * 当前Activity的上下文
         *
         * @param context
         * @return
         */

        public MediaManagerBuilder setContext(Context context){
            this.context = context;
            return this;
        }

        /**
         * 设置MediaPlayer Url链接
         *
         * @param url
         * @return
         */
        public MediaManagerBuilder setUrl(String url){
            this.config.url = url;
            return this;
        }

        /**
         * 设置播放进度监听回调
         *
         * @param mediaListener
         * @return
         */
        public MediaManagerBuilder setMediaListener(MediaCallBack mediaListener){
            this.mediaListener = mediaListener;
            return this;
        }

        /**
         * 设置是否是debug
         *
         * @param b
         * @return
         */
        public MediaManagerBuilder setDebugModel(boolean b){
            this.DEBUG = b;
            return this;
        }

        /**
         * 设置进度条
         */
        public MediaManagerBuilder setProgressSeek(SeekBar seek){
            this.seekBar = seek;
            return this;
        }


        /**
         * 初始化MediaPlayer
         */

        public MediaManagerBuilder build(){
            Uri uri = Uri.parse(config.url);
            //播放器不能为空
            if (mediaPlayer!=null){
                //如果是正在播放的状态 需要暂停上一个
                if (mediaPlayer.isPlaying()){
                    mediaPlayer.stop();
                }
                //重置播放器
                mediaPlayer.release();
            }
            //创建新的播放器
            mediaPlayer = new MediaPlayer();
            try {
                mediaPlayer.setDataSource(config.url); //指定音频文件的路径
                mediaPlayer.prepare();//让mediaplayer进入准备状态
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        if (seekBar!=null){
                            seekBar.setMax(mediaPlayer.getDuration());
                        }
                        mediaListener.prepare(mediaPlayer.getDuration(),format.format(mediaPlayer.getDuration()) + "");
                    }
                });
                // 监听音频播放完的代码,实现音频的自动循环播放
                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer arg0) {
                        mediaListener.end();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
            timerTask = new TimerTask() {

                Runnable updateUI = new Runnable(怎么给录音降噪处理

微信小程序开发之录音机 音频播放 动画 (真机可用)

微信怎么录音

在iOS中绘制录音音频波形图

我有一段录音,里面有杂音,并且声音太底,有人能帮我去除吗,

Android 开发 如何实现高质量的录音