【Android -- 音频】使用 MediaRecord 录音

前言

AudioRecord 和 MediaRecorder 两种都可以录制音频,MediaRecorder 已实现大量的封装,操作起来更加简单,而 AudioRecord 使用起来更加灵活,能实现更多的功能。
1. AudioRecord(基于字节流录音)

  • 优点:可以实现语音的实时处理,进行边录边播,对音频的实时处理。
  • 缺点:输出是PCM的语言数据,如果保存成音频文件是不能被播放器播放的。要用到AudioTrack这个去进行处理。

2. MediaRecorder(基于文件录音)

  • 优点:封装度很高,操作简单
  • 缺点:无法实现实时处理音频,输出的音频格式少。

主要函数

  • setAudioChannels(int numChannels) 设置录制的音频通道数

  • setAudioEncoder(int audio_encoder) 设置audio的编码格式

  • setAudioEncodingBitRate(int bitRate) 设置录制的音频编码比特率

  • setAudioSamplingRate(int samplingRate) 设置录制的音频采样率

  • setAudioSource(int audio_source) 设置用于录制的音源

  • setAuxiliaryOutputFile(String path) 辅助时间的推移视频文件的路径传递

  • setAuxiliaryOutputFile(FileDescriptor fd)在文件描述符传递的辅助时间的推移视频

  • setCamera(Camera c) 设置一个recording的摄像头

  • setCaptureRate(double fps) 设置视频帧的捕获率

  • setMaxDuration(int max_duration_ms) 设置记录会话的最大持续时间(毫秒)

  • setMaxFileSize(long max_filesize_bytes) 设置记录会话的最大大小(以字节为单位)

  • setOutputFile(FileDescriptor fd) 传递要写入的文件的文件描述符

  • setOutputFile(String path) 设置输出文件的路径

  • setOutputFormat(int output_format) 设置在录制过程中产生的输出文件的格式

  • setPreviewDisplay(Surface sv) 表面设置显示记录媒体(视频)的预览

  • setVideoEncoder(int video_encoder) 设置视频编码器,用于录制

  • setVideoEncodingBitRate(int bitRate) 设置录制的视频编码比特率

  • setVideoFrameRate(int rate) 设置要捕获的视频帧速率

  • setVideoSize(int width, int height) 设置要捕获的视频的宽度和高度

  • setVideoSource(int video_source) 开始捕捉和编码数据到setOutputFile(指定的文件)

  • setLocation(float latitude, float longitude) 设置并存储在输出文件中的地理数据(经度和纬度)

  • setProfile(CamcorderProfile profile) 指定CamcorderProfile对象

  • setOrientationHint(int degrees)设置输出的视频播放的方向提示

  • setOnErrorListener(MediaRecorder.OnErrorListener l)注册一个用于记录录制时出现的错误的监听器

  • setOnInfoListener(MediaRecorder.OnInfoListener listener)注册一个用于记录录制时出现的信息事件

  • getMaxAmplitude() 获取在前一次调用此方法之后录音中出现的最大振幅

  • prepare()准备录制。

  • release()释放资源

  • reset()将MediaRecorder设为空闲状态

  • start()开始录制

  • stop()停止录制

配置参数:

1.)视频编码格式MediaRecorder.VideoEncoder

default,H263,H264,MPEG_4_SP,VP8

2.)音频编码格式MediaRecorder.AudioEncoder

default,AAC,HE_AAC,AAC_ELD,AMR_NB,AMR_WB,VORBIS

3.)视频资源获取方式MediaRecorder.VideoSource

default,CAMERA,SURFACE

4.)音频资源获取方式MediaRecorder.AudioSource

defalut,camcorder,mic,voice_call,voice_communication,voice_downlink,voice_recognition, voice_uplink

5.)资源输出格式MediaRecorder.OutputFormat

amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp,aac_adif, aac_adts, output_format_rtp_avp,
 output_format_mpeg2ts ,webm

实现代码

在这里插入图片描述

1. 在清单文件中,添加权限

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

2. 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_record"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始录音"
        android:layout_margin="10dp"/>
</LinearLayout>

3. 逻辑代码

public class MainActivity extends BaseActivity {
    @BindView(R.id.btn_record)
    Button mStartRecord;

    private boolean isStart = false;
    private MediaRecorder mRecorder = null;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {
        checkPermission();
    }

    @OnClick(R.id.btn_record)
    public void clicked() {
        if(!isStart){
            startRecord();
            mStartRecord.setText("停止录制");
            isStart = true;
        }else{
            stopRecord();
            mStartRecord.setText("开始录制");
            isStart = false;
        }
    }

    //开始录制
    private void startRecord(){
        if(mRecorder == null){
            File dir = new File(Environment.getExternalStorageDirectory(),"sounds");
            if(!dir.exists()){
                dir.mkdirs();
            }
            File soundFile = new File(dir,System.currentTimeMillis() +".amr");
            if(!soundFile.exists()){
                try {
                    soundFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  //音频输入源
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);   //设置输出格式
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);   //设置编码格式
            mRecorder.setOutputFile(soundFile.getAbsolutePath());
            try {
                mRecorder.prepare();
                mRecorder.start();  //开始录制
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    //停止录制,资源释放
    private void stopRecord(){
        if(mRecorder != null){
            mRecorder.stop();
            mRecorder.release();
            mRecorder = null;
        }
    }

    /**
     * 权限申请
     */
    private void checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            String[] permissions = new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE};
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, permissions, 200);
                    return;
                }
            }
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
            grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == 200) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                    intent.setData(uri);
                    startActivityForResult(intent, 200);
                    return;
                }
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == 200) {
            checkPermission();
        }
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin-Dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值