采用 MediaRecorder 实现录音功能
快速录音需求,还要求音频文件很小,呵呵,那就干吧:
package com.zzq.mydemo.test;import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;import com.zzq.mydemo.BaseActivity;
import com.zzq.mydemo.R;import java.io.File;
import java.io.IOException;/*** 录音 Activity* <p>* <activity* android:name=".RecordingActivity"* android:theme="@style/Theme.AppCompat.Dialog" />*/public class RecordingActivity extends BaseActivity {private Dialog mDialog;private TextView mTvCountdown;private TimeCount mTimeCount;private MediaRecorder mRecorder;private String mFileName;private String mFilePath;public static final String FILE_NAME = "FILE_NAME";public static final String FILE_PATH = "FILE_PATH";@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);showDialog();initMediaRecorder();// 多加 100毫秒,用于补偿 TimeCount的时间损耗,解决跳 1秒的 BUG【目前很好用】mTimeCount = new TimeCount(10100, 1000);}private void initMediaRecorder() {mRecorder = new MediaRecorder();mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);mRecorder.setAudioChannels(1);// 设置录音文件的清晰度,这里将 1s音频压缩到 1k大小mRecorder.setAudioSamplingRate(8000);mRecorder.setAudioEncodingBitRate(8000);}@Overrideprotected void onDestroy() {stopRecording();if (mTimeCount != null) {mTimeCount.cancel();}if (mDialog != null && mDialog.isShowing()) {mDialog.dismiss();mDialog = null;}super.onDestroy();}private void showDialog() {mDialog = new Dialog(this, R.style.NormalDialogStyle);View view = View.inflate(this, R.layout.dialog_recording, null);WindowManager.LayoutParams lp = mDialog.getWindow().getAttributes();lp.width = WindowManager.LayoutParams.WRAP_CONTENT;lp.height = WindowManager.LayoutParams.WRAP_CONTENT;lp.gravity = Gravity.CENTER;mDialog.setContentView(view, lp);// 设置点击对话框外部是否关闭对话框mDialog.setCanceledOnTouchOutside(true);// 点击对话框外部或者点击返回键都会触发此回调mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {@Overridepublic void onCancel(DialogInterface dialog) {forResult();}});mTvCountdown = (TextView) view.findViewById(R.id.tv_countdown);Button btnRecording = (Button) view.findViewById(R.id.btn_recording);btnRecording.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startRecording();break;case MotionEvent.ACTION_UP:forResult();break;default:break;}return true;}});mDialog.show();}private class TimeCount extends CountDownTimer {private TimeCount(long millisInFuture, long countDownInterval) {super(millisInFuture, countDownInterval);}@Overridepublic void onTick(long millisUntilFinished) {mTvCountdown.setText(millisUntilFinished / 1000 + "s");}@Overridepublic void onFinish() {forResult();}}private void startRecording() {mTimeCount.start();setFileNameAndPath();// 设置录音文件的保存路径mRecorder.setOutputFile(mFilePath);try {mRecorder.prepare();mRecorder.start();} catch (IOException e) {Log.e("RecordingActivity", "prepare() failed");}}/*** 设置录音文件的名字和保存路径*/private void setFileNameAndPath() {mFileName = System.currentTimeMillis() + ".aac";mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SoundRecorder/" + mFileName;File file = new File(mFilePath);if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}}private void stopRecording() {if (mRecorder != null) {try {mRecorder.stop();} catch (IllegalStateException e) {// 如果当前java状态和jni里面的状态不一致Log.e("RecordingActivity", "stop() failed");}mRecorder.release();mRecorder = null;}}private void forResult() {Intent intent = new Intent();intent.putExtra(FILE_NAME, mFileName);intent.putExtra(FILE_PATH, mFilePath);setResult(RESULT_OK, intent);finish();}
}
布局文件:
<?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="wrap_content"android:background="#ffffff"android:orientation="vertical"android:paddingLeft="30dp"android:paddingRight="30dp"><TextViewandroid:id="@+id/tv_countdown"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="30dp"android:gravity="center"android:text="10s"android:textColor="#ff0000"android:textSize="30sp" /><Buttonandroid:id="@+id/btn_recording"android:layout_width="250dp"android:layout_height="50dp"android:layout_gravity="center"android:layout_marginBottom="30dp"android:layout_marginTop="30dp"android:text="按住开始录音"android:textColor="#ffffff"android:textSize="18sp" /></LinearLayout>
其中有趣的点:
1、录音前先初始化 MediaRecorder:initMediaRecorder(),省时间,做到点击录音后就可以马上去录音;
2、通过调整 setAudioSamplingRate(int i) 和 setAudioEncodingBitRate(int i) 可以控制所录音频的质量,从而调整音频文件大小;
3、退出时要及时清理垃圾;
4、TimeCount有个跳 1秒的 BUG,这是程序运行耗时不断累积造成的,通过多加 100毫秒的方式,来补偿 TimeCount 的时间损耗,解决跳 1秒的 BUG,目前很好用(不知道有没有坑 >_<|||):
mTimeCount = new TimeCount(10100, 1000);
5、设置 setCanceledOnTouchOutside(true) 时,要监听此行为并结束录音:
// 设置点击对话框外部是否关闭对话框mDialog.setCanceledOnTouchOutside(true);// 点击对话框外部或者点击返回键都会触发此回调mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {@Overridepublic void onCancel(DialogInterface dialog) {forResult();}});
6、用了 “按住录音,放开停止” 的方式:
Button btnRecording = (Button) view.findViewById(R.id.btn_recording);btnRecording.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startRecording();break;case MotionEvent.ACTION_UP:forResult();break;default:break;}return true;}});
下面是调用录音页面及播放所录音频的代码:
public class MainActivity extends BaseActivity {private MediaPlayer mMediaPlayer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void onJump(View view) {Intent intent = new Intent(this, RecordingActivity.class);startActivityForResult(intent, 1);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == Activity.RESULT_OK) {String fileName = data.getStringExtra(RecordingActivity.FILE_NAME);String filePath = data.getStringExtra(RecordingActivity.FILE_PATH);if (!filePath.isEmpty()) {if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {stopPlaying();return;}playAudio(false, filePath);}}}private void playAudio(boolean isInternet, String filePath) {if (mMediaPlayer == null) {mMediaPlayer = new MediaPlayer();mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {stopPlaying();}});}try {if (isInternet) {mMediaPlayer.setDataSource(this, Uri.parse(filePath));} else {mMediaPlayer.setDataSource(filePath);}mMediaPlayer.prepare();} catch (IOException e) {e.printStackTrace();}mMediaPlayer.start();}private void stopPlaying() {if (mMediaPlayer != null) {mMediaPlayer.stop();mMediaPlayer.release();mMediaPlayer = null;}}@Overrideprotected void onDestroy() {stopPlaying();super.onDestroy();}
}
参考文章:
1、https://www.jianshu.com/p/6bbb51ac4938
2、https://www.jianshu.com/p/6d91a8d7b974
3、https://blog.csdn.net/hecheng2009/article/details/74807032
4、https://blog.csdn.net/feiyu1947/article/details/85332322
采用 MediaRecorder 实现录音功能相关推荐
- android录音倒计时,android MediaRecorder实现录音功能 显示时间 计时
初始化: if (recorder==null){ recorder=new MediaRecorder();//初始化录音对象 recorder.setAudioSource(MediaRecord ...
- android利用MediaRecorder实现录音功能
android用手机录音保存到sd卡中: 布局文件: <?xml version="1.0" encoding="utf-8"?> <Line ...
- 基于Camera2和MediaRecorder实现视频录制
一.概述 视频录制,在一般开发中很少遇到,大部分开发工作都是写写页面,请求接口,展示数据等等.真要遇到,可能采用第三方库实现,一来实现快速,二来可能觉得别人实现的比较好.特别是在开发周期很紧的情况下, ...
- java audiorecord_Android 录音实现(AudioRecord)
上一篇文章介绍了使用 MediaRecorder 实现录音功能 Android录音实现(MediaRecorder) ,下面我们继续看看使用 AudioRecord 实现录音功能. AudioReco ...
- 美团外卖商家端视频探索之旅
美团外卖商家端视频探索之旅 背景 美团外卖至今已迅猛发展了六年,随着外卖业务量级与日俱增,单一的文字和图片已无法满足商家的需求,商家迫切需要更丰富的商品描述手段吸引用户,增加流量,进而提高下单转化率和 ...
- android录制视频实现
Android视频录制使用MediaRecorder来录制,SurfaceView来预览视频 与录制音频类似,录制视频的步骤为: 1. 构造MediaRecorder对象 2. 设置视频的声音和视 ...
- [转发]Android视频技术探索之旅:美团外卖商家端的实践
美团技术团队 2019-09-12 20:02:11 背景 2013年美团外卖成立,至今一直迅猛发展.随着外卖业务量级与日俱增,单一的文字和图片已无法满足商家的需求,商家迫切需要更丰富的商品描述手段吸 ...
- Android视频技术探索之旅:美团外卖商家端的实践
总第354篇 2019年 第32篇 美美导读:移动互联网时代,4G的普及推动了移动视频的发展,丰富的视频内容满足了用户多样化的需求.美团外卖商家端也尝试引入了视频功能,旨在提升商品信息描述的丰富度.本 ...
- Android实现视频剪切、视频拼接以及音视频合并
因公司项目有需求,要实现视频剪切,视频拼接以及音视频合并的功能,自己通过在网上查找大量的资料终于把功能实现了,把实现的公共类提取出来,以便以后复习巩固. 使用map4parser作为视频处理包,and ...
最新文章
- CSS before / after伪元素
- 跨域 (1) jsonp 跨域
- linux 查看进程
- Spring Framework 3.2 M1发布
- 关注BLUEBEE的浏览器发展
- iOS开发cocoaPod的使用
- 关于 VB,VC,Delphi,SDK 的笑话
- 解决 GitHub 拉取代码网速慢的问题
- 彻底理解ThreadLocal(转)
- CRM中多张关联表join的报表
- 推理框架runtime的动态输入、输出思路
- Android一帧一帧的动画
- Hadoop开发环境搭建之Eclipse配置
- 永磁同步电机矢量控制(二)——控制原理与坐标变换推导
- APK编辑器v2.4.3强行修改app背景图、去广告、重新架构等
- 计算机网络课程设计组建大型网吧局域网,计算机网络课程设计组建网吧局域网...
- 【 FlutterUnit 食用指南】 开源篇
- 新年第一天 | 恶补新一季《黑镜》的同时,营长又深入扒了扒它那擅长机器学习的新爸爸是如何赚钱的
- 【数字水印】基于matlab DFT数字水印嵌入提取攻击【含Matlab源码 2320期】
- CS231n公开课系列1_视频+课件+作业下载+GitHub批量下载工具
热门文章
- 一行python代码,带你重温经典小游戏
- Scratch 投篮游戏
- 替代A100,英伟达向中国市场推出性能阉割版A800 GPU芯片
- 鸿蒙系统手机一览表,华为鸿蒙os系统支持的手机型号有哪些?鸿蒙os适配机型列表一览[多图]...
- 欧洲杯爆冷:法国点球大战遭瑞士淘汰,本泽马3分钟2球,姆巴佩罚丢点球
- 计算机端口概念理解(转载)
- Rust开发环境搭建(Linux)
- zotero 文献格式 深圳大学硕士论文格式
- 【附源码】Java计算机毕业设计高校流动党员信息管理系统(程序+LW+部署)
- Python turtle 学习之画个五角星