(Android) MediaPlayer & AudioRecord

原创 2015年11月18日 16:06:59
MediaRecorder和AudioRecord都可以录制音频,区别是MediaRecorder录制的音频文件是经过压缩后的,需要设置编码器。并且录制的音频文件可以用系统自带的Music播放器播放。

而AudioRecord录制的是PCM格式的音频文件,需要用AudioTrack来播放,AudioTrack更接近底层。

在用MediaRecorder进行录制音视频时,最终还是会创建AudioRecord用来与AudioFlinger进行交互。

C++层MediaRecorder创建AudioRecord类的代码位于AudioSource类构造函数中,代码如下:


  1. mRecord = new AudioRecord(  
  2.             inputSource, sampleRate, AudioSystem::PCM_16_BIT,  
  3.             channels > 1? AudioSystem::CHANNEL_IN_STEREO: AudioSystem::CHANNEL_IN_MONO,  
  4.             16 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */  
  5.             flags);  

AudioSource对象的创建位于StagefrightRecorder::createAudioSource()函数中,而createAudioSource函数又是在StagefrightRecorder类开始录音或录像时被创建的。

AudioRecord API

private boolean isPlaying = false;
private boolean isRecording = false;

private String filePath;

private int frequence = 8000; //录制频率,单位hz.这里的值注意了,写的不好,可能实例化AudioRecord对象的时候,会出错。我开始写成11025就不行。这取决于硬件设备
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

class RecordAsyncTask extends AsyncTask<Void, Integer, Void>{

@Override
protected Void doInBackground(Void... params) {
File audioFile =
new File(filePath);
if(audioFile.exists()){
audioFile.delete();
}
try {
audioFile.createNewFile();
}
catch (IOException e){
e.printStackTrace();
}
isRecording = true;
try {
//开通输出流到指定的文件
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(audioFile)));
//根据定义好的几个配置,来获取合适的缓冲大小
int bufferSize = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
//实例化AudioRecord
AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC, frequence, channelConfig, audioEncoding, bufferSize);
//定义缓冲
short[] buffer = new short[bufferSize];

//开始录制
record.startRecording();

int r = 0; //存储录制进度
//定义循环,根据isRecording的值来判断是否继续录制
while(isRecording){
//从bufferSize中读取字节,返回读取的short个数
//这里老是出现buffer overflow,不知道是什么原因,试了好几个值,都没用,TODO:待解决
int bufferReadResult = record.read(buffer, 0, buffer.length);
//循环将buffer中的音频数据写入到OutputStream中
for(int i=0; i<bufferReadResult; i++){
dos.writeShort(buffer[i]);
}
publishProgress(
new Integer(r)); //向UI线程报告当前进度
r++; //自增进度值
}
//录制结束
record.stop();
dos.close();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

class PlayAsyncTask extends AsyncTask<Void, Integer, Void> {

@Override
protected Void doInBackground(Void... params) {
// Get the file we want to playback.
File audioFile = new File(filePath);
isPlaying = true;
int bufferSize = AudioTrack.getMinBufferSize(frequence, channelConfig, audioEncoding);
short[] buffer = new short[bufferSize/4];
try {
//定义输入流,将音频写入到AudioTrack类中,实现播放
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(audioFile)));
//实例AudioTrack
AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, frequence, channelConfig, audioEncoding, bufferSize, AudioTrack.MODE_STREAM);
//开始播放
track.play();
//由于AudioTrack播放的是流,所以,我们需要一边播放一边读取
while(isPlaying && dis.available()>0){
int i = 0;
while(dis.available()>0 && i<buffer.length){
buffer[i] = dis.readShort();
i++;
}
//然后将数据写入到AudioTrack中
track.write(buffer, 0, buffer.length);

}

//播放结束
track.stop();
dis.close();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}


MediaPlayer API

//Start recording
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);//Call this after setAudioSource()
mRecorder.setOutputFile(filePath);// Call this after setOutputFormat()
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//Call this after setOutputFormat()
mRecorder.setAudioChannels(1); //1:mono, 2:stereo
mRecorder.setAudioSamplingRate(8000); // 16kHz for AMR_WB ,8kHz for AMR_NB

try {
mRecorder.prepare();
mRecorder.start();
isRecording = true;
}catch (IOException e){
e.printStackTrace();
}

//Stop recording
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}

//Start playing Local file
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(FileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();


//Start playing video online
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();


//Stop playing
mPlayer.release();
mPlayer = null;



android的AudioRecord

  • 2012年10月26日 22:51
  • 69KB
  • 下载

Android使用AudioRecord遇到的问题与解决方法

问题: 1、android判断是否禁用了录音权限       通过判断分贝值是否大于0,在代码中搜索 volume > 0 2、部分手机在调用 audioRecord.startRecordin...
  • wyyl1
  • wyyl1
  • 2015年05月14日 12:11
  • 17650

Android多媒体学习十:利用AudioRecord类实现自己的音频录制程序

AudioRecord类相对于MediaRecorder来说,更加接近底层,为我们封装的方法也更少。然而实现一个AudioRecord的音频录制程序也很简单。本实例代码如下: 可惜,本实例测试时有个问...

android中AudioRecord采集音频的参数说明

在android中采集音频的api是android.media.AudioRecord类 其中构造器的几个参数就是标准的声音采集参数 以下是参数的含义解释 public AudioRecord ...

Android提高第十篇之AudioRecord实现&quot;助听器&quot;

http://blog.csdn.net/hellogv/archive/2010/11/22/6026455.aspx       Android可以通过MediaRecorder和AudioRec...

音频,PCM,采样率及android的AudioRecord与AudioTrack 资料整理

采样频率,也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。采样频率的倒数是采样周期或者叫作采样时间,它是采样之间的时间间隔。通俗的讲采样频率是指计...

JNI在Android开发中的应用之--用AudioRecord录音,用AudioTrack播放声音.

[java] view plaincopyprint? 下面是主Activity.      package com.example.hellojni;      import andro...

Android音频录制--AudioRecord

最近公司有个项目,需要用到音频录制,就研究了一下这部分。 android的音频录制有2种方式,对应的是两个不同的类:AudioRecord和MediaRecord。MediaRecord的特点是相对...

Android AudioRecord录音相关和音频文件的封装

前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net  ...
  • luckkof
  • luckkof
  • 2014年02月17日 16:15
  • 987
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:(Android) MediaPlayer & AudioRecord
举报原因:
原因补充:

(最多只允许输入30个字)