对于录制音频,Android系统就都自带了一个小小的应用,但是使用起来可能不是特别的灵活,所以有提供了另外的俩种。
下边来介绍下这三种录制的方式;
1、通过Intent调用系统的录音器功能,然后在录制完成保存以后在onActivityResult中返回录制的音频的uri,然后通过Mediaplayer进行播放
调用系统的录音器
private final static int REQUEST_RECORDER = 100;
private Uri uri;
public void recorder_Intent(){
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent,REQUEST_RECORDER);
}
获取返回的信息
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && REQUEST_RECORDER == requestCode){ uri = data.getData(); } }
<span style="background-color: rgb(255, 255, 255);"><span style="font-size:24px;">通过Mediaplayer进行播放</span></span>
if (uri != null){ if (mediaPlayer != null) { try { mediaPlayer.reset(); mediaPlayer.setDataSource(RecorderActivity.this, uri); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } }else Toast.makeText(RecorderActivity.this,"没有成功创建Mediaplayer",Toast.LENGTH_SHORT).show(); }
2、通过MediaRecorder来进行音频的录制:
MediaRecorder 类可用于音频和视频的捕获。再构造了一个MediaRecorder对象之后,为了捕获音频,必须调用setAudioEncoder和setAudioSource这俩个方法。如果不调用这些方法,那么将不会录制音频(视频也同样不会),另外,MediaRecorder在准备录制之前通常还会调用setOutputFormat 和setOutputFile,
在实例化MediaRecorder之后,应该调用的第一个方法是setAudioSource。它采用一个AudioSource内部类中定义的常量作为参数,我们通常使用的常量是MediaRecorder。AudioSource.MIC.
根据顺序,下一个调用的就是setOutputFormat ,这个方法采用在MediaRecorder.OutputFormat内部类中指定的常量作为参数:
(1)MediaRecorder.OutputFormat.MPEG_4:这个常量指定输出的文件将是一个MPEG_4文件,包含音频跟视频轨
(2)MediaRecorder.OutputFormat.RAW_AMR;这个常量表示输出一个没有任何容器类型的原始文件,只有在捕获没有视频的音频且音频编码器是AMR_NB时才会使用这个常量。
(3)MediaRecorder.OutputFormat.THREE_GPP:这个常量指定输出的文件将是一个3gpp文件(.3gp)。它可能同时包含音频跟视频轨
MediaRecorder音频编码,在设置输出格式之后,可以调用setAudioEncoder方法来设置应该使用编码器,可能的值指定为MediaRecorder.AudioEncoder类中的常量,出来使用DEFAULT之外,只存在一个其他的值:MediaRecorder.AudioEncoder.AMR_NB,这是自适应多速率窄带编解码器。
这种编解码器针对语音进行了优化,因此不适应于语音之外的其他内容。默认情况下他的采样率是8kHz,码率在 4.75~12.2kbps之间,这个俩个数据对于录制语音之外的其他内容而言非常低,但是,这是当前可用于MediaRecorder的唯一选择。
下来就看代码的实现:
这是录制的代码:
private MediaRecorder mediaRecorder = new MediaRecorder();
private File audioFile;
public void recorder_Media(){
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Android/data/com.example.chengpengfei_d.recorderdemo/files");
path.mkdirs();
amplitude = new RecordAmplitude();
try {
audioFile = File.createTempFile("recording",".3gp",path);
mediaRecorder.setOutputFile(audioFile.getAbsolutePath());
mediaRecorder.prepare();
mediaRecorder.start();
isRecording = true;
amplitude.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
这是播放的代码
case FLAG_MEDIA: isRecording = false; amplitude.cancel(true); mediaRecorder.stop(); mediaRecorder.release(); mediaPlayer.reset(); try { mediaPlayer.setDataSource(audioFile.getAbsolutePath()); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } break;
3 使用AudioRecord录制原始音频:
这就是第三种捕获音频的方法。使用AudioRecord的类。AudioRecord是三个方法中最灵活的(因为他允许访问原始音频流),但是他是拥有最少的内置功能,如不会自动压缩音频等等。
使用AudioRecord的基础知识非常简单。我们只需要构造一个AudioRecord类型的对象,并传入各种不同配置参数。
需要制定的第一个值就是音频源。下面使用值与之前用于MediaRecorder的值相同,其在MediaRecorder.AudioSource 中定义。实际上,这意味着可以使用MediaRecorder.AudioSource.MIC;
int audiosource = MediaRecorder.AudioSource.MIC;
需要指定的下一个值是录制的采样率,应以赫兹为单位,我们知道,MediaRecorder采样的音频是8000赫兹。而CD质量的音频通常是44100赫兹(44100Hz),Hz或赫兹是每秒的样本数量。不同的Android手机硬件将能够以不同的采样率进行采样,对于我的这个例子将以11025Hz的采样率来进行采样,这是一个常用的采样率。
int sampleRateInHz = 11025;
接下来,需要指定捕获的音频通道的数量,在AudioFormat类中指定了用于此参数的常量,而且可根据名称理解他们。
现在将使用单声道配置。
int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
随后,需要指定音频格式。在AudioFormat类中也指定了一下各种可能的常量。
在这四个选择中,我们选择PCM_16位和PCM 8位。PCM代表脉冲编码调制(Pulse Code Modulation) 他实际上是原始的音频样本。因此可以设置每个样本的分辨率为16位或8位。16位将占用更多的控件和处理能力,但表示的音频将更接近真实。
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
最后将需要指定缓冲区大小。时间上可以查询AudioRecord类以获得最小缓冲区大小,查询方式是调用getMinBufferSize的静态方法,同时传入采样率,通道配置以及音频格式。
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig ,audioFormat);
下边就看实际的代码吧:
主要分俩个方法,还有些初始化的代码:
private boolean isPlaying = false; private int frequency = 11025; int audioFormat = AudioFormat.ENCODING_PCM_16BIT; int audiosource = MediaRecorder.AudioSource.MIC; int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; File recordingFile = null; RecordAudio recordAudio = null; PlayAudio playAudio = null; public void recorder_Audio() throws IOException { //AudioRecord不会直接保存音频,需要自己保存 File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()); path.mkdirs(); try { recordingFile = File.createTempFile("recording", ".pcm", path); } catch (IOException e) { e.printStackTrace(); } recordAudio = new RecordAudio(); recordAudio.execute(); } public void playRecorder() { isRecording = false; playAudio = new PlayAudio(); playAudio.execute(); } //播放录制音频的异步任务 private class PlayAudio extends AsyncTask<Void,Integer,Void>{ @Override protected Void doInBackground(Void... params) { isPlaying = true; int bufferSize = AudioTrack.getMinBufferSize(frequency,channelConfig,audioFormat); short[] buffer = new short[bufferSize / 4]; DataInputStream dis= null; try { dis = new DataInputStream(new BufferedInputStream(new FileInputStream(recordingFile))); } catch (FileNotFoundException e) { e.printStackTrace(); } AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,channelConfig,audioFormat,bufferSize,AudioTrack.MODE_STREAM); audioTrack.play(); try { while(isPlaying && dis.available() > 0 ){ int i = 0; while(dis.available() > 0 && i < buffer.length){ buffer[i] = dis.readShort(); i++; } audioTrack.write(buffer,0,buffer.length); } dis.close(); } catch (IOException e) { e.printStackTrace(); } return null; } } <span style="white-space:pre"> </span>
//录制音频的一个异步任务; private class RecordAudio extends AsyncTask<Void,Integer,Void>{ @Override protected Void doInBackground(Void... params) { isRecording = true; DataOutputStream dos = null; try { dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(recordingFile))); int bufferSize = AudioRecord.getMinBufferSize(frequency,channelConfig,audioFormat); AudioRecord audioRecord = new AudioRecord(audiosource,frequency,channelConfig,audioFormat,bufferSize); short [] buffer = new short[bufferSize]; audioRecord.startRecording(); int r = 0; while(isRecording){ int bufferReadResult = audioRecord.read(buffer,0,bufferSize); for (int i = 0; i<bufferReadResult; i++){ try { dos.writeShort(buffer[i]); } catch (IOException e) { e.printStackTrace(); } } publishProgress(new Integer(r)); r++; } audioRecord.stop(); dos.close(); } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); mTv_progress.setText(values[0] + ""); } }
至此三种方式也就完了,这是一个关于音频录制的实例,通过三种不同方式的录制来达到相同的目的,但是要了解,三种的优缺点,如果想看实际效果,下载以后运行下看看吧,本实例是在Android studio中开发,如果Ecplise的话那么直接移植代码,以及清单文件的内容,应该就可以,如果不行可以联系我。
下载地址:http://download.csdn.net/detail/u012808234/9482926