(Android) MediaPlayer & AudioRecord

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;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值