使用MediaRecorder录制音频,不能看到我们录制的音频数据,使用AudioRecord可以直接对音频数据进行操作。
AudioRecord
使用AudioRecord的步骤:
1. 获得AudioRecord对象
2. 开始录音
3. 获得音频数据
4. 停止录制
5. 释放资源
public class MainActivity extends Activity {
Button record;
Button stop_record;
AudioRecord audioRecord;
boolean isRecording=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
record=(Button)findViewById(R.id.record);
stop_record=(Button)findViewById(R.id.stop_record);
record.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
doRecord(); //调用录制
}
});
stop_record.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
stopRecord(); //停止录制方法
}
});
}
//新开了一个录制线程,因为直接执行startRecord方法时会将主线程阻塞,导致程序异常。因为线程执行了一个死程序,即不停的读取数据。
public void doRecord() {
// TODO 自动生成的方法存根
Thread audioThread=new Thread(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
startRecord();//新线程调用录音
}
});
audioThread.start();
record.setText("录音中");
}
//开始录音
public void startRecord() {
// TODO 自动生成的方法存根
int frequence=8000;//采样频率
String filePath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+getFileTime()+".pcm";//pcm是数字信号对模拟信号的一个抽样量化和编码。
File file=new File(filePath);
//要在次级线程中调用Toast,需要按以下格式,另外,Looper.loop()会是线程阻塞,其他显示方式请查资料
// Looper.prepare();//创建该线程的Looper对象
//
// Toast.makeText(getBaseContext(), filePath, Toast.LENGTH_LONG).show();
// Looper.loop();
if(file.exists()) file.delete();
try{
file.createNewFile();
OutputStream os=new FileOutputStream(file);
BufferedOutputStream bos=new BufferedOutputStream(os);
DataOutputStream dos=new DataOutputStream(bos);//获得流操作对象
int buffersize=AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);//获得AudioRecord需要的最小内存
audioRecord=new AudioRecord(MediaRecorder.AudioSource.MIC, frequence, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, buffersize);
short [] buffer=new short[buffersize];
audioRecord.startRecording();
isRecording=true;
while(isRecording){
int bufferReadResult=audioRecord.read(buffer, 0, buffersize);//采集音频数据
for(int i=0;i< bufferReadResult;i++)
{
dos.writeShort(buffer[i]);
}
}
audioRecord.stop();
audioRecord.release();
dos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//获得当前时间,并返回String格式
private String getFileTime() {
// TODO 自动生成的方法存根
Date curTime=Calendar.getInstance().getTime();
SimpleDateFormat df=new SimpleDateFormat("yyyyMMddHHmmss");//设置输出格式
String time=df.format(curTime).toString();
return time;
}
//停止录音
protected void stopRecord() {
// TODO 自动生成的方法存根
isRecording=false;
record.setText("录音");
}
另外也需在注册文件中声明权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
AudioTrack
AudioTrack播放的必须是未经压缩的数据,也就是“裸数据”即原始数据。例如,AudioRecord中的short或者byte数组就是原始数据,这些数据经各种各样的压缩形式后就可以得到一些如MP3等格式文件。上文的.pcm格式文件就是裸数据。pcm是数字信号对模拟信号的一个抽样量化和编码。
使用AudioTrack的步骤:
1. 获得AudioTrack对象
2. 开始播放
3. 写入音频数据
4. 停止播放
5. 释放资源
public class MainActivity extends Activity {
Button play;
Button stop_play;
AudioTrack audioTrack;
boolean isPlaying=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play=(Button)findViewById(R.id.play);
stop_play=(Button)findViewById(R.id.stop_play);
play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
play.setText("播放中..");
isPlaying=true;//调用线程播放
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
if(audioTrack==null)
startPlay();
}
});
thread.start();
}
});
stop_play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO 自动生成的方法存根
stopPlay();
}
});
}
//开始播放
protected void startPlay() {
// TODO 自动生成的方法存根
String path=Environment.getExternalStorageDirectory().getAbsolutePath()+"/20170308105452.pcm";//播放文件的名字是自己选择的
File file=new File(path);
int musicLength=(int)file.length();
short []music=new short[musicLength];
if(audioTrack==null)
//实例化播放器
audioTrack=new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, musicLength, AudioTrack.MODE_STREAM);
audioTrack.play();
try{
InputStream is=new FileInputStream(file);
BufferedInputStream bis=new BufferedInputStream(is);
DataInputStream dis=new DataInputStream(bis);//获得数据流
int i=0;
while(dis.available()>0){//条件为结果文件中还有可读文件
music[i++]=dis.readShort();
}
audioTrack.write(music, 0, musicLength);
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
//暂停播放
protected void pausePlay() {
// TODO 自动生成的方法存根
play.setText("播放");
}
//重新播放
protected void reStart() {
// TODO 自动生成的方法存根
}
//停止播放
protected void stopPlay() {
// TODO 自动生成的方法存根
if(audioTrack!=null)
{
isPlaying=false;
audioTrack.stop();
audioTrack.release();
audioTrack=null;
}
play.setText("播放");
}