Android录音器实验报告,Android实现录音(MediaRecorder)
Android提供了两个API用于录音的实现:MediaRecorder 和 AudioRecord,各有优劣。
1、MediaRecorder
已经集成了录音、编码、压缩等,支持少量的录音音频格式,大概有.aac(API = 16) .amr .3gp
优点:大部分已经集成,直接调用相关接口即可,代码量小
缺点:无法实时处理音频;输出的音频格式不是很多,例如没有输出mp3格式文件
2、AudioRecord
主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫、语音)
优点:语音的实时处理,可以用代码实现各种音频的封装
缺点:输出是PCM语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩
先说 MediaRecorder : MediaRecorder因为大部分功能已经集成,所以使用起来相对比较简单。
下面是个小demo:
① 界面
界面比较简单,由于MediaRecorder 并不能实现暂停、继续录音的功能
录音界面.png
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始" />
android:id="@+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="停止" />
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"/>
② 相关录音功能
开始录音
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 实现录音还是比较简单的,只是不能暂停。
Android录音器实验报告,Android实现录音(MediaRecorder)相关推荐
- android对象识别实验报告,Android 3相册实验报告.doc
Android 3相册实验报告 中原工学院计算机学院 软件平台开发技术大作业 班 级: 软件121 作品名称: 3D相册 姓 名: 辛俊闪 学 号: 201200834101 指导教师: 刘凤华 20 ...
- android消息响应实验报告,android实验一实验报告-20210401011015.docx-原创力文档
Last revision on 21 December 2020 Last revision on 21 December 2020 Android实验一实验报告 Android实验报告一 姓名:丁 ...
- android博学谷实验报告,Android项目实战系列—基于博学谷(四)我的模块(上)...
image 由于这个模块内容较多,篇幅较长,请耐心阅读. "我"的模块分为四个部分 一."我"的界面 1.底部导航栏 (1).导入界面图片 将底部导航栏所需图片 ...
- Android五子棋开发实验报告,Android五子棋游戏实验报告.doc
Android开发总结报告 _____扫雷小游戏 2011年1月 一.背景 扫雷是一个简单的单人游戏.游戏的目的是在没有触碰任何一个地雷的情形下清空一个雷区.扫雷不仅有Windows版本,也有其他平台 ...
- android新闻客户端实验报告,Android 新闻客户端学习笔记
学习了新闻客户端开发后,有很多是通用的,就把客户端用到的一些做个笔记,已备以后使用,主要用到的知识点有: 1. Android网络编程 2. Android中BaseAdapter的使用 3. ...
- Android开发实验-- 电话拨号器实验报告
电话拨号器实验报告 一.实验准备工作 Android Studio 二.实验详细步骤 1.activity_main页面布局设计 2.mainactivity文件实现功能 3.Androidmainf ...
- 20155318 《Java程序设计》实验四 (Android程序设计)实验报告
20155318 <Java程序设计>实验四 (Android程序设计)实验报告 实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android.组 ...
- 20175333曹雅坤实验四《Android程序设计》实验报告
20175333实验四<Android程序设计>实验报告 一.实验内容及步骤 - Android程序设计-1 Android Stuidio的安装测试: 参考<Java和Androi ...
- 单片机8位抢答器实训机电报告_CD4511八路抢答器实验报告-
CD4511八路抢答器实验报告- 本文关键词:八路,实验,报告,抢答器,CD4511 CD4511八路抢答器实验报告- 本文简介:小学期实验设计任务目录摘要I第1章绪论11.1课题研究的相关背景11. ...
最新文章
- k8s-ingress 413 Request Entity Too Large
- 高并发架构系列:MQ消息队列的12点核心原理总结
- 最新综述:用于文本分类的数据增强方法
- edge无法上网dns_如何在Microsoft Edge中通过HTTPS启用DNS
- [Java基础]Date类基础
- jenkins即将重启问题
- TCP/IP网络编程(3)
- 物联网(lot)特定场景最佳实践
- matlab生成手机app,matlab使用App designer生成可独立运行的app
- 调整csgo画面显示FPS值
- 清明祭娭毑_原水_新浪博客
- Python爬取小猪短租全网数据
- 美国克莱姆森大学计算机专业排名,美国西北大学计算机专业排名怎么样?
- Java:String类学习笔记
- Oracle Dimension in DWH
- 铁路 信号组调工 技师 练习题 01
- 引用类型作为函数的返回类型
- python3的numpy包中的numpy.logspace解析
- 专访金榕:四年蜕变,阿里iDST是如何登上浪潮之巅的?
- 小米8 SE刷机安卓13
热门文章
- 牛客练习赛61 B 吃水果
- 牛客练习赛61 B 吃水果 题解
- 串行口发送子程序C语言,基于C语言的RS232串行接口通信实现
- [备忘]苹果系统MAC OS X 10.5.6 (雪豹 snowleopard 10.5.6) 启用root方法
- vs2010c语言生成dll,VS2010下生成dll的方法
- [转载] 新兵训练营系列课程——平台服务部署及Web框架
- 【项目笔记_手写笔】在51822 上移植SSD1306驱动
- 聊天机器人(chatbot)终极指南:自然语言处理(NLP)和深度机器学习(Deep Machine Learning)
- 谈谈最近深圳找工作经历
- 未明学院学员报告:做了微博数据分析后,我发现现在最火的明星原来是……