当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现录音功能实现实例(MediaRecorder)

Android实现录音功能实现实例(MediaRecorder)

2019年07月24日  | 移动技术网IT编程  | 我要评论

阿忠农家乐,西餐厅英语,超级贴身保镖全文阅读

本文介绍了android实现录音的实例代码(mediarecorder),分享给大家,具体如下:

android提供了两个api用于录音的实现:mediarecorder 和 audiorecord,各有优劣。

1、mediarecorder

已经集成了录音、编码、压缩等,支持少量的录音音频格式,大概有.aac(api = 16) .amr .3gp

优点:大部分已经集成,直接调用相关接口即可,代码量小

缺点:无法实时处理音频;输出的音频格式不是很多,例如没有输出mp3格式文件

2、audiorecord

主要是实现边录边播(audiorecord+audiotrack)以及对音频的实时处理(如会说话的汤姆猫、语音)

优点:语音的实时处理,可以用代码实现各种音频的封装

缺点:输出是pcm语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩

先说 mediarecorder : mediarecorder因为大部分功能已经集成,所以使用起来相对比较简单。

下面是个小demo:

① 界面

界面比较简单,由于mediarecorder 并不能实现暂停、继续录音的功能

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/activity_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <button
    android:id="@+id/btn_start"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="开始" />

  <button
    android:id="@+id/btn_stop"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:enabled="false"
    android:text="停止" />

  <textview
    android:id="@+id/text_time"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="00:00:00"
    android:padding="5dp"
    android:layout_margintop="10dp"/>

</linearlayout>

② 相关录音功能

开始录音

  public void startrecord() {
    // 开始录音
    /* ①initial:实例化mediarecorder对象 */
    if (mmediarecorder == null)
      mmediarecorder = new mediarecorder();
    try {
      /* ②setaudiosource/setvediosource */
      mmediarecorder.setaudiosource(mediarecorder.audiosource.mic);// 设置麦克风
      /*
       * ②设置输出文件的格式:three_gpp/mpeg-4/raw_amr/default three_gpp(3gp格式
       * ,h263视频/arm音频编码)、mpeg-4、raw_amr(只支持音频且音频编码要求为amr_nb)
       */
      mmediarecorder.setoutputformat(mediarecorder.outputformat.mpeg_4);
      /* ②设置音频文件的编码:aac/amr_nb/amr_mb/default 声音的(波形)的采样 */
      mmediarecorder.setaudioencoder(mediarecorder.audioencoder.aac);
      filename = dateformat.format("yyyymmdd_hhmmss", calendar.getinstance(locale.china)) + ".m4a";
      if (!fileutils.isfolderexist(fileutils.getfoldername(audiosavedir))) {
        fileutils.makefolders(audiosavedir);
      }
      filepath = audiosavedir + filename;
      /* ③准备 */
      mmediarecorder.setoutputfile(filepath);
      mmediarecorder.prepare();
      /* ④开始 */
      mmediarecorder.start();
    } catch (illegalstateexception e) {
      logutil.i("call startamr(file mrecaudiofile) failed!" + e.getmessage());
    } catch (ioexception e) {
      logutil.i("call startamr(file mrecaudiofile) failed!" + e.getmessage());
    }
  }

音频编码可以根据自己实际需要自己设定,文件名防止重复,使用了日期_时分秒的结构,audiosavedir 是文件存储目录,可自行设定。

停止录音

  public void stoprecord() {
    try {
      mmediarecorder.stop();
      mmediarecorder.release();
      mmediarecorder = null;
      filepath = "";
    } catch (runtimeexception e) {
      logutil.e(e.tostring());
      mmediarecorder.reset();
      mmediarecorder.release();
      mmediarecorder = null;

      file file = new file(filepath);
      if (file.exists())
        file.delete();

      filepath = "";
    }
  }

时长记录

  // 记录录音时长
  private void counttime() {
    while (isrecording) {
        logutil.d("正在录音");
        timecount++;
        message msg = message.obtain();
        msg.what = time_count;
        msg.obj = timecount;
        myhandler.sendmessage(msg);
      try {
        timethread.sleep(1000);
      } catch (interruptedexception e) {
        e.printstacktrace();
      }
    }
    logutil.d("结束录音");
    timecount = 0;
    message msg = message.obtain();
    msg.what = time_count;
    msg.obj = timecount;
    myhandler.sendmessage(msg);
  }

将录音时长格式化

  // 格式化 录音时长为 时:分:秒
  public static string formatmiss(int miss) {
    string hh = miss / 3600 > 9 ? miss / 3600 + "" : "0" + miss / 3600;
    string mm = (miss % 3600) / 60 > 9 ? (miss % 3600) / 60 + "" : "0" + (miss % 3600) / 60;
    string ss = (miss % 3600) % 60 > 9 ? (miss % 3600) % 60 + "" : "0" + (miss % 3600) % 60;
    return hh + ":" + mm + ":" + ss;
  }

activity全部代码

import android.media.mediarecorder;
import android.os.bundle;
import android.os.environment;
import android.os.handler;
import android.os.message;
import android.support.v7.app.appcompatactivity;
import android.text.format.dateformat;
import android.view.view;
import android.widget.button;
import android.widget.textview;

import com.zzx.hellokotlin.r;
import com.zzx.hellokotlin.utils.fileutils;
import com.zzx.hellokotlin.utils.logutil;

import java.io.file;
import java.io.ioexception;
import java.util.calendar;
import java.util.locale;

public class record2activity extends appcompatactivity {


  // 录音界面相关
  button btnstart;
  button btnstop;
  textview texttime;

  // 录音功能相关
  mediarecorder mmediarecorder; // mediarecorder 实例
  boolean isrecording; // 录音状态
  string filename; // 录音文件的名称
  string filepath; // 录音文件存储路径
  thread timethread; // 记录录音时长的线程
  int timecount; // 录音时长 计数
  final int time_count = 0x101;
  // 录音文件存放目录
  final string audiosavedir = environment.getexternalstoragedirectory().getabsolutepath()+"/audiodemo/";

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_record2);

    btnstart = (button) findviewbyid(r.id.btn_start);
    btnstop = (button) findviewbyid(r.id.btn_stop);
    texttime = (textview) findviewbyid(r.id.text_time);

    btnstart.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view v) {
        // 开始录音
        btnstart.setenabled(false);
        btnstop.setenabled(true);

        startrecord();
        isrecording = true;
        // 初始化录音时长记录
        timethread = new thread(new runnable() {
          @override
          public void run() {
            counttime();
          }
        });
        timethread.start();
      }
    });

    btnstop.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view v) {
        // 停止录音
        btnstart.setenabled(true);
        btnstop.setenabled(false);

        stoprecord();
        isrecording = false;
      }
    });

  }

  // 记录录音时长
  private void counttime() {
    while (isrecording) {
        logutil.d("正在录音");
        timecount++;
        message msg = message.obtain();
        msg.what = time_count;
        msg.obj = timecount;
        myhandler.sendmessage(msg);
      try {
        timethread.sleep(1000);
      } catch (interruptedexception e) {
        e.printstacktrace();
      }
    }
    logutil.d("结束录音");
    timecount = 0;
    message msg = message.obtain();
    msg.what = time_count;
    msg.obj = timecount;
    myhandler.sendmessage(msg);
  }


  /**
   * 开始录音 使用amr格式
   * 录音文件
   * @return
   */
  public void startrecord() {
    // 开始录音
    /* ①initial:实例化mediarecorder对象 */
    if (mmediarecorder == null)
      mmediarecorder = new mediarecorder();
    try {
      /* ②setaudiosource/setvediosource */
      mmediarecorder.setaudiosource(mediarecorder.audiosource.mic);// 设置麦克风
      /*
       * ②设置输出文件的格式:three_gpp/mpeg-4/raw_amr/default three_gpp(3gp格式
       * ,h263视频/arm音频编码)、mpeg-4、raw_amr(只支持音频且音频编码要求为amr_nb)
       */
      mmediarecorder.setoutputformat(mediarecorder.outputformat.mpeg_4);
      /* ②设置音频文件的编码:aac/amr_nb/amr_mb/default 声音的(波形)的采样 */
      mmediarecorder.setaudioencoder(mediarecorder.audioencoder.aac);
      filename = dateformat.format("yyyymmdd_hhmmss", calendar.getinstance(locale.china)) + ".m4a";
      if (!fileutils.isfolderexist(fileutils.getfoldername(audiosavedir))) {
        fileutils.makefolders(audiosavedir);
      }
      filepath = audiosavedir + filename;
      /* ③准备 */
      mmediarecorder.setoutputfile(filepath);
      mmediarecorder.prepare();
      /* ④开始 */
      mmediarecorder.start();
    } catch (illegalstateexception e) {
      logutil.i("call startamr(file mrecaudiofile) failed!" + e.getmessage());
    } catch (ioexception e) {
      logutil.i("call startamr(file mrecaudiofile) failed!" + e.getmessage());
    }
  }

  /**
   * 停止录音
   */
  public void stoprecord() {
    //有一些网友反应在5.0以上在调用stop的时候会报错,翻阅了一下谷歌文档发现上面确实写的有可能会报错的情况,捕获异常清理一下就行了,感谢大家反馈!
    try {
      mmediarecorder.stop();
      mmediarecorder.release();
      mmediarecorder = null;
      filepath = "";

    } catch (runtimeexception e) {
      logutil.e(e.tostring());
      mmediarecorder.reset();
      mmediarecorder.release();
      mmediarecorder = null;

      file file = new file(filepath);
      if (file.exists())
        file.delete();

      filepath = "";
    }
  }

  // 格式化 录音时长为 时:分:秒
  public static string formatmiss(int miss) {
    string hh = miss / 3600 > 9 ? miss / 3600 + "" : "0" + miss / 3600;
    string mm = (miss % 3600) / 60 > 9 ? (miss % 3600) / 60 + "" : "0" + (miss % 3600) / 60;
    string ss = (miss % 3600) % 60 > 9 ? (miss % 3600) % 60 + "" : "0" + (miss % 3600) % 60;
    return hh + ":" + mm + ":" + ss;
  }


  handler myhandler = new handler() {
    @override
    public void handlemessage(message msg) {
      switch (msg.what) {
        case time_count:
          int count = (int) msg.obj;
          logutil.d("count == " + count);
          texttime.settext(formatmiss(count));

          break;
      }
    }
  };
}

总结:mediarecorder 实现录音还是比较简单的,只是不能暂停。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网