使用MediaRecorder录制音频,不能看到我们录制的音频数据,使用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播放的必须是未经压缩的数据,也就是“裸数据”即原始数据。例如,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("播放"); }