关闭

(Android) MediaPlayer & AudioRecord

314人阅读 评论(0) 收藏 举报
分类:
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

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:24471次
    • 积分:586
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:12篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论