首页 > 其他分享 >【android】MediaRecorder录音录像

【android】MediaRecorder录音录像

时间:2023-03-06 11:23:42浏览次数:50  
标签:MediaRecorder void 录制 录音 mediaRecorder import android btn

前言

  Android除了支持播放多媒体文件之外,还可以从对应的硬件中捕获多媒体,比如从麦克风录音、从摄像头录像等。本篇博客讲解一下Android下如何通过MediaRecorder进行录音以及录像的步骤,最后将以简单的Demo演示。

   本篇博客的主要内容:

  1. MediaRecorder
  2. MediaRecorder录制音频
  3. MediaRecorder录制视频
  4. MediaRecorder的内部类

 

MediaRecorder

  MediaRecorder主要用于记录音频与视频,它位于"android.media.MediaRecorder"下。它为开发人员提供了详尽的AIP以完成记录音频与视频的工作,下面简单介绍一些常用的。

  • void prepar():准备录制。
  • void start():开始录制。
  • void stop():停止录制。
  • void reset():重置MediaRecorder。
  • void release():释放MediaRecorder占用的资源。
  • void setAudioEncoder(int):设置音频记录的编码格式。
  • void setAudoSource(int):设置音频记录的音频源。
  • void setOutoutFormat(int):设置记录的媒体文件的输出转换格式。
  • void setPreviewDisplay(Surface):设置视频的预览界面。
  • void setVideoEncoder(int):设置视频记录的编码格式。
  • void setVideoSource(int):设置视频记录的视频源。
  • void setOutputFile(String):媒体文件输出路径。
  • void setMaxDuration(int):设置最大记录时长,单位为毫秒。

  上面仅仅列出了一些常用的方法,但是通过这个方法可以看出MediaRecorder是需要在多个状态之间切换的,准备、开始、停止、重置等等。MediaRecorder也为我们提供了一套状态切换的规则,只有在既定的状态下,才能完成对应的操作,下图是官方文档提供的状态图。

 

 

 

上图非常直观的展示了MediaRecorder的状态间的转换,这里只说几点需要注意的地方:

  • 当为MediaRecorder设定媒体录入源之后即初始化完成,这个时候才可以为其设定其他的参数。
  • 在开始录制前必须先调用prepare()准备录制。
  • 只有在Initial初始化状态,才可以对MediaRecorder调用release()释放资源,其他状态必须先stop()或者reset()。
  • 错误状态是游离在所有状态之外的,当发生错误的时候,只有进行reset()才会进入Initial初始状态。

 

  MediaRecorder录制视频必不可少的步骤:

  1. 调用new MediaRecorder()构造函数得到MediaRecorder的实例。
  2. 调用setOutputFormat()设定媒体文件的输出格式,必须在设定音频与视频的编码格式之前设定。
  3. 如果需要记录音频,则调用setAudioSource()设定音频的录入源以及调用setAudioEncoder()设定音频的编码方式。
  4. 如果需要记录视频,则调用setVideoSource()设定视频的录入员以及调用setVideoEncoder()设定视频的编码方式。
  5. 调用setOutputFile()设定记录的媒体文件保存的路径。
  6. 先调用prepare()准备录制,准备完成之后调用start()开始录制。
  7. 记录完成后,调用stop()停止录制。

  

MediaRecorder录制音频

  上面介绍了使用MediaRecorder录制视频必不可少的步骤,因为录制音频无需捕获图像,所以更简单一些。下面直接通过一个简单的示例,演示如何录制音频,录制的音频文件保存在sd根目录下,注释很详细,这里不在累述了。布局很简单,只有两个Button,开始录音、结束录音,就不提供布局代码了。

  实现代码:

package cn.bgxt.mediarecorderdemo;

import java.io.File;
import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class RecordActivity extends Activity {
    private Button btn_RecordStart, btn_RecordStop;
    private MediaRecorder mediaRecorder;
    private boolean isRecording;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record);

        btn_RecordStart = (Button) findViewById(R.id.btn_RecordStart);
        btn_RecordStop = (Button) findViewById(R.id.btn_RecordStop);

        btn_RecordStop.setEnabled(false);

        btn_RecordStart.setOnClickListener(click);
        btn_RecordStop.setOnClickListener(click);
    }

    private View.OnClickListener click = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_RecordStart:
                start();
                break;
            case R.id.btn_RecordStop:
                stop();
                break;
            default:
                break;
            }
        }
    };

    /**
     * 开始录音
     */
    protected void start() {
        try {
            File file = new File("/sdcard/mediarecorder.amr");
            if (file.exists()) {
                // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
                file.delete();
            }
            mediaRecorder = new MediaRecorder();
            // 设置音频录入源
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            // 设置录制音频的输出格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            // 设置音频的编码格式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            // 设置录制音频文件输出文件路径
            mediaRecorder.setOutputFile(file.getAbsolutePath());

            mediaRecorder.setOnErrorListener(new one rrorListener() {

                @Override
                public void one rror(MediaRecorder mr, int what, int extra) {
                    // 发生错误,停止录制
                    mediaRecorder.stop();
                    mediaRecorder.release();
                    mediaRecorder = null;
                    isRecording=false;
                    btn_RecordStart.setEnabled(true);
                    btn_RecordStop.setEnabled(false);
                    Toast.makeText(RecordActivity.this, "录音发生错误", 0).show();
                }
            });

            // 准备、开始
            mediaRecorder.prepare();
            mediaRecorder.start();

            isRecording=true;
            btn_RecordStart.setEnabled(false);
            btn_RecordStop.setEnabled(true);
            Toast.makeText(RecordActivity.this, "开始录音", 0).show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 录音结束
     */
    protected void stop() {
        if (isRecording) {
            // 如果正在录音,停止并释放资源
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
            isRecording=false;
            btn_RecordStart.setEnabled(true);
            btn_RecordStop.setEnabled(false);
            Toast.makeText(RecordActivity.this, "录音结束", 0).show();
        }
    }

    @Override
    protected void onDestroy() {
        if (isRecording) {
            // 如果正在录音,停止并释放资源
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        super.onDestroy();
    }

}

  录制音频需要访问麦克风设备,访问设备需要添加权限:

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

  效果展示:

 

 

MediaRecorder录制视频

  上面已经介绍了使用MediaRecorder录制视频的步骤,这里依照步骤一步一步写代码就可以了。下面通过一个简单的Demo演示如何使用MediaRecorder录制一段从摄像头捕获到的视频,录制的视频文件将保持在SD卡上。布局很简单,两个Button,开始、停止,然后还有一个SurfaceView显示预览效果,就不给出布局代码了。

  实现代码:

package cn.bgxt.mediarecorderdemo;

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class VideoActivity extends Activity {
    private Button btn_VideoStart, btn_VideoStop;
    private SurfaceView sv_view;
    private boolean isRecording;
    private MediaRecorder mediaRecorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video);

        btn_VideoStart = (Button) findViewById(R.id.btn_VideoStart);
        btn_VideoStop = (Button) findViewById(R.id.btn_VideoStop);
        sv_view = (SurfaceView) findViewById(R.id.sv_view);

        btn_VideoStop.setEnabled(false);

        btn_VideoStart.setOnClickListener(click);
        btn_VideoStop.setOnClickListener(click);

        // 声明Surface不维护自己的缓冲区,针对Android3.0以下设备支持
        sv_view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    private View.OnClickListener click = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.btn_VideoStart:
                start();
                break;
            case R.id.btn_VideoStop:
                stop();
                break;
            default:
                break;
            }
        }
    };

    protected void start() {
        try {
            File file = new File("/sdcard/video.mp4");
            if (file.exists()) {
                // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
                file.delete();
            }

            mediaRecorder = new MediaRecorder();
            mediaRecorder.reset();
            // 设置音频录入源
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            // 设置视频图像的录入源
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            // 设置录入媒体的输出格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            // 设置音频的编码格式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
            // 设置视频的编码格式
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
            // 设置视频的采样率,每秒4帧
            mediaRecorder.setVideoFrameRate(4);
            // 设置录制视频文件的输出路径
            mediaRecorder.setOutputFile(file.getAbsolutePath());
            // 设置捕获视频图像的预览界面
            mediaRecorder.setPreviewDisplay(sv_view.getHolder().getSurface());

            mediaRecorder.setOnErrorListener(new one rrorListener() {

                @Override
                public void one rror(MediaRecorder mr, int what, int extra) {
                    // 发生错误,停止录制
                    mediaRecorder.stop();
                    mediaRecorder.release();
                    mediaRecorder = null;
                    isRecording=false;
                    btn_VideoStart.setEnabled(true);
                    btn_VideoStop.setEnabled(false);
                    Toast.makeText(VideoActivity.this, "录制出错", 0).show();
                }
            });

            // 准备、开始
            mediaRecorder.prepare();
            mediaRecorder.start();

            btn_VideoStart.setEnabled(false);
            btn_VideoStop.setEnabled(true);
            isRecording = true;
            Toast.makeText(VideoActivity.this, "开始录像", 0).show();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    protected void stop() {
        if (isRecording) {
            // 如果正在录制,停止并释放资源
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
            isRecording=false;
            btn_VideoStart.setEnabled(true);
            btn_VideoStop.setEnabled(false);
            Toast.makeText(VideoActivity.this, "停止录像,并保存文件", 0).show();
        }
    }

    @Override
    protected void onDestroy() {
        if (isRecording) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        super.onDestroy();
    }

}

  录制视频需要用到麦克风和摄像头硬件,还需要赋予一些相应的权限。

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

  效果展示:

 

 

 

 

 

MediaRecorder的内部类

  通过上面录制视频的Demo可以看出,使用MediaRecorder录制视频,需要设置一些录入源、编码格式、输出格式等。这些方法都是以int类型的参数设定的,它们其实都是在MediaRecorder的内部类中已经以常量的形式定义好了,直接适用场景进行选择即可。

  • MediaRecorder.AudioEncoder:音频的编码格式。
  • MediaRecorder.AudioSource:录制的音频源。
  • MediaRecorder.OutputFormat:媒体文件的输出编码格式。
  • MediaRecorder.VideoEncoder:视频的编码格式。
  • MediaRecorder.VideoSource:录制的视频源。

 

  源码下载

【参考连接】

Android--MediaRecorder录音录像

 

 

 

 

 

 

 

标签:MediaRecorder,void,录制,录音,mediaRecorder,import,android,btn
From: https://www.cnblogs.com/opensmarty/p/17183082.html

相关文章

  • 【android】通过 PackageManager 获得你想要的 App 信息
    一、前言开门见山,开篇明义。有些场景下,我们会需要获取一些其它App的各项信息,例如:App名称,包名、Icon等。这个时候就需要使用到PackageManager这个类了。本篇就Pack......
  • Android 查询远程服务器的工具QueryUtils
    /***查询远程服务器的工具*@authorchen.lin**/publicclassQueryUtils{privatestaticfinalStringTAG="CommonUtils";privatestaticQueryUtilsins......
  • Android intent跳转工具类
    /***进行页面跳转的工具**@authorchen.lin**/publicclassIntentUtil{privatestaticfinalStringIMAGE_TYPE="image/*";privatestaticfinalStr......
  • 说一下在写Android APP时遇到的具体问题
    问题一:总是显示出nosuchtable错误不要担心这个问题(该担心还是得担心一下的哈),以我出错多次的经验来看,只需要在运行APP之后,回到虚拟机的主界面,然后找到相应的APP虚拟软件,......
  • Android学习-每日打卡APP-实现浏览功能
    接着写每日打卡App现在实现了浏览功能packagecom.example.clockappliction;importandroidx.appcompat.app.AppCompatActivity;importandroid.content.Intent;im......
  • 3月5号Android学习
    <?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools......
  • 【Android逆向】脱壳项目 frida-dexdump 原理分析
    1.项目代码地址https://github.com/hluwa/frida-dexdump2.核心逻辑为defdump(self):logger.info("[+]Searching...")st=time.time()......
  • Android学习-ListView再视
    之前接触了一点ListView的基础知识,但没有自己去敲,学的不是很深刻,今天我按照教程,写了一个listview的基本实现,基本掌握了listviewlistview的学习是为了给RecyclerView打一下......
  • 【Android逆向】脱壳项目frida_dump 原理分析
    脱dex核心文件dump_dex.js核心函数functiondump_dex(){varlibart=Process.findModuleByName("libart.so");varaddr_DefineClass=null;varsymbol......
  • Android studio ListView的界面
    新建.java文件,定义一个实体类bt_list_adapter_type.java,作为ListView适配器的适配类型;publicclassbt_list_adapter_type{privateStringname;privateintim......