android mediarecord 实现暂停断点录音功能

来源:互联网 发布:盐城数据产业园能去吗 编辑:程序博客网 时间:2024/04/27 22:27

android mediarecord 实现暂停断点录音功能

原文出处:blog.csdn.net/wanli_smile/article/details/7715030


最近研究了下MediaRecorder的录音功能,发现暂停之后,继续录音这个功能,网上参考的资料比较少,现在将自己的学习成果分享大家:

基本原理如下:MediaRecorder通过MIC录音,系统没有自带的pause功能,每次暂停录音,都会结束本次的录音。现在本人的设计思路是:MediaRecorder录音暂停时,保存这段所录下的音频A,继续录音后,再次暂停,保留录音音频B;以此类推直到最终的录音结束时,依次读取之前保存的A、B……的录音文件,并将其合并在一起。涉及的技术:文件的保存读取、音频的合并等

音频的合并:设置MediaRecorder的音频输出格式mMediaRecorder01.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
   mMediaRecorder01 .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);输出的是amr格式。amr的音频文件的文件头,相对来说是固定的6个字节的固定字符,A.amr文件和B.amr文件的合并,只需将B以字节流读取,去掉前6个字节,和A的字节流合并后保存,就实现了音频合并,不涉及复杂的音频编码问题。(MediaRecorder的音频输出格式比较多,有jpgg、MP3等之类的格式,合成的原理大同小异,只需要注意他们的音频文件头的格式就可以了。)

 

 

资源代码:

http://download.csdn.net/detail/wanli_smile/4410240

有图有真相:

 

[java]
public class EX07 extends Activity {      private ImageButton myButton1;      private ImageButton myButton2;      private ImageButton myButton3;      private ImageButton myButton4;      private Button myButton;      private ListView myListView1;      private String strTempFile = "YYT_";      private File myRecAudioFile;      /**录音保存路径**/      private File myRecAudioDir;      private File myPlayFile;      private MediaRecorder mMediaRecorder01;      private int mMinute;      private boolean xx=true;      /**存放音频文件列表**/      private ArrayList<String> recordFiles;      private ArrayAdapter<String> adapter;      private TextView myTextView1;      /**文件存在**/      private boolean sdcardExit;      /**是否停止录音**/      private boolean isStopRecord;      /**按钮背景图片的标志位**/      private boolean sigle = false;      private String length1 = null;            private  final String SUFFIX=".amr";                  /**暂停按钮**/      Button buttonpause;                  /**记录需要合成的几段amr语音文件**/      private ArrayList<String> list;                  int second=0;            int minute=0;            /**计时器**/      Timer timer;                  /**是否暂停标志位**/      private boolean isPause;            /**在暂停状态中**/      private boolean inThePause;              /** Called when the activity is first created. */      @Override      public void onCreate(Bundle savedInstanceState) {                    super.onCreate(savedInstanceState);          setContentView(R.layout.main);                    //暂停标志位 为false          isPause=false;          //暂停状态标志位          inThePause=false;                    //初始化list          list=new ArrayList<String>();                    //四个按钮          myButton1 = (ImageButton) findViewById(R.id.ImageButton01);          myButton2 = (ImageButton) findViewById(R.id.ImageButton02);          myButton3 = (ImageButton) findViewById(R.id.ImageButton03);          myButton4 = (ImageButton) findViewById(R.id.ImageButton04);          myButton = (Button) findViewById(R.id.myButton);          buttonpause=(Button)findViewById(R.id.mypuase);          myListView1 = (ListView) findViewById(R.id.ListView01);          myTextView1 = (TextView) findViewById(R.id.TextView01);          myButton2.setEnabled(false);          myButton3.setEnabled(false);          myButton4.setEnabled(false);                    myPlayFile=null;            // 判断sd Card是否插入          sdcardExit = Environment.getExternalStorageState().equals(                  android.os.Environment.MEDIA_MOUNTED);          // 取得sd card路径作为录音文件的位置          if (sdcardExit){              String pathStr = Environment.getExternalStorageDirectory().getPath()+"/YYT";              myRecAudioDir= new File(pathStr);              if(!myRecAudioDir.exists()){                  myRecAudioDir.mkdirs();                  Log.v("录音", "创建录音文件!" + myRecAudioDir.exists());              }  //          Environment.getExternalStorageDirectory().getPath() + "/" + PREFIX + "/";          }          // 取得sd card 目录里的.arm文件          getRecordFiles();                    adapter = new ArrayAdapter<String>(this,                  android.R.layout.simple_list_item_1, recordFiles);          // 将ArrayAdater添加ListView对象中          myListView1.setAdapter(adapter);          // 录音                myButton1.setOnClickListener(new ImageButton.OnClickListener() {                     @Override              public void onClick(View v) {              second=0;              minute=0;                                list.clear();  //          Calendar c=Calendar.getInstance();  //          int mMinute1=c.get(Calendar.MINUTE);                                sigle = true;                  // TODO Auto-generated method stub                     start();                    if (sigle = false) {                      myButton1.setBackgroundResource(R.drawable.record_hover1);                  } else {                      myButton1.setBackgroundResource(R.drawable.record_dis1);                      myButton2.setBackgroundResource(R.drawable.stop_hover2);                      myButton3.setBackgroundResource(R.drawable.play_hover1);                      myButton4.setBackgroundResource(R.drawable.delete_hover);                  }                                          }            });          // 停止          myButton2.setOnClickListener(new ImageButton.OnClickListener() {                @Override              public void onClick(View v) {                                                      xx=false;                  sigle = true;                  timer.cancel();                  // TODO Auto-generated method stub                                                      //这里写暂停处理的 文件!加上list里面 语音合成起来                  if(isPause){                                            //在暂停状态按下结束键,处理list就可以了                      if(inThePause){                          getInputCollection(list, false);                      }                      //在正在录音时,处理list里面的和正在录音的语音                      else{                          list.add(myRecAudioFile.getPath());                          recodeStop();                          getInputCollection(list, true);                      }                                            //还原标志位                      isPause=false;                      inThePause=false;                      buttonpause.setText("暂停录音");                                                                                                      //  adapter.add(myRecAudioFile.getName());                                        }                                                                        //若录音没有经过任何暂停                  else{                                                              if (myRecAudioFile != null) {                      // 停止录音                      mMediaRecorder01.stop();                      mMediaRecorder01.release();                      mMediaRecorder01 = null;                      // 将录音频文件给Adapter                      adapter.add(myRecAudioFile.getName());                      DecimalFormat df = new DecimalFormat("#.000");                      if (myRecAudioFile.length() <= 1024*1024) {                          //length1 = (myRecAudioFile.length() / 1024.0)+"";                                                      length1=df.format(myRecAudioFile.length() / 1024.0)+"K";                      } else {                          //length1 = (myRecAudioFile.length() / 1024.0 / 1024)+"";                          //DecimalFormat df = new DecimalFormat("#.000");                            length1=df.format(myRecAudioFile.length() / 1024.0 / 1024)+"M";                      }                          System.out.println(length1);                                                myTextView1.setText("停  止" + myRecAudioFile.getName()                              + "文件大小为:" + length1);                      myButton2.setEnabled(false);                                }                                }                    if (sigle = false) {                      myButton2.setBackgroundResource(R.drawable.stop_hover2);                  } else {                      myButton1.setBackgroundResource(R.drawable.record_hover1);                      myButton2.setBackgroundResource(R.drawable.stop1);                      myButton3.setBackgroundResource(R.drawable.play_hover1);                      myButton4.setBackgroundResource(R.drawable.delete_hover);                  }                                    //停止录音了                  isStopRecord = true;              }            });            // 播放          myButton3.setOnClickListener(new ImageButton.OnClickListener() {                @Override              public void onClick(View v) {                  sigle = true;                  // TODO Auto-generated method stub                  if (myPlayFile != null && myPlayFile.exists()) {                      // 打开播放程序                      openFile(myPlayFile);                  } else {                      Toast.makeText(EX07.this, "你选的是一个空文件", Toast.LENGTH_LONG)                              .show();                      Log.d("没有选择文件","没有选择文件");                  }                  if (sigle = false) {                      myButton3.setBackgroundResource(R.drawable.play_hover1);                  } else {                      myButton1.setBackgroundResource(R.drawable.record_hover1);                      myButton2.setBackgroundResource(R.drawable.stop_hover2);                      myButton3.setBackgroundResource(R.drawable.play1);                      myButton4.setBackgroundResource(R.drawable.delete_hover);                  }              }            });            // 删除          myButton4.setOnClickListener(new OnClickListener() {                @Override              public void onClick(View v) {                  sigle = true;                  // TODO Auto-generated method stub                    if (myPlayFile != null) {                      // 先将Adapter删除文件名                      adapter.remove(myPlayFile.getName());                      // 删除文件                      if (myPlayFile.exists())                          myPlayFile.delete();                      myTextView1.setText("完成删除!");                    }                  if (sigle = false) {                      myButton4.setBackgroundResource(R.drawable.delete_hover);                  } else {                      myButton1.setBackgroundResource(R.drawable.record_hover1);                      myButton2.setBackgroundResource(R.drawable.stop_hover2);                      myButton3.setBackgroundResource(R.drawable.play_hover1);                      myButton4.setBackgroundResource(R.drawable.delete_dis);                  }              }          });                    /**          * 暂停按钮,记录之前保存的语音文件          */          buttonpause.setOnClickListener(new OnClickListener() {                            @Override              public void onClick(View v) {                  // TODO Auto-generated method stub                                isPause=true;                                    //已经暂停过了,再次点击按钮 开始录音,录音状态在录音中              if(inThePause){                  buttonpause.setText("暂停录音");                  start();                  inThePause=false;                                                  }              //正在录音,点击暂停,现在录音状态为暂停              else{                                    //当前正在录音的文件名,全程                  list.add(myRecAudioFile.getPath());                  inThePause=true;                  recodeStop();                  //start();                  buttonpause.setText("继续录音");                                    //计时停止                  timer.cancel();              }              }          });                              myListView1                  .setOnItemClickListener(new AdapterView.OnItemClickListener() {                      @Override                      public void onItemClick(AdapterView<?> arg, View arg1,                              int arg2, long arg3) {                          // TODO Auto-generated method stub                          // 当有单点击文件名时将删除按钮及播放按钮Enable                          myButton3.setEnabled(true);                          myButton4.setEnabled(true);                          myPlayFile = new File(myRecAudioDir.getAbsolutePath()                                  + File.separator                                  + ((TextView) arg1).getText().toString());                                                    DecimalFormat df = new DecimalFormat("#.000");                          if (myPlayFile.length() <= 1024*1024) {                              length1=df.format(myPlayFile.length() / 1024.0)+"K";                          } else {                              length1=df.format(myPlayFile.length() / 1024.0/1024)+"M";                          }                          myTextView1.setText("你选的是"                                  + ((TextView) arg1).getText().toString()                                  + "文件大小为:" + length1);                          Toast.makeText(EX07.this,"你选的是" + (((TextView) arg1).getText())+ "文件大小为:" + length1,                                          Toast.LENGTH_LONG).show();                        }                    });            myButton.setOnClickListener(new Button.OnClickListener() {                @Override              public void onClick(View v) {                  // TODO Auto-generated method stub                  showSize show = new showSize();                  String text = show.showsize();                  Toast.makeText(EX07.this, text, Toast.LENGTH_LONG).show();              }          });      }              protected void recodeStop() {          if (mMediaRecorder01 != null && !isStopRecord) {              // 停止录音              mMediaRecorder01.stop();              mMediaRecorder01.release();              mMediaRecorder01 = null;          }                    timer.cancel();      }              /**      * activity的生命周期,stop时关闭录音资源      */      @Override      protected void onStop() {          // TODO Auto-generated method stub          if (mMediaRecorder01 != null && !isStopRecord) {              // 停止录音              mMediaRecorder01.stop();              mMediaRecorder01.release();              mMediaRecorder01 = null;          }          super.onStop();      }          /**      * 获取目录下的所有音频文件      */      private void getRecordFiles() {          // TODO Auto-generated method stub          recordFiles = new ArrayList<String>();          if (sdcardExit) {              File files[] = myRecAudioDir.listFiles();              if (files != null) {                  for (int i = 0; i < files.length; i++) {                      if (files[i].getName().indexOf(".") >= 0) { // 只取.amr 文件                          String fileS = files[i].getName().substring(                                  files[i].getName().indexOf("."));                          if (fileS.toLowerCase().equals(".mp3")                                  || fileS.toLowerCase().equals(".amr")                                  || fileS.toLowerCase().equals(".mp4"))                              recordFiles.add(files[i].getName());                        }                  }              }          }        }        // 打开录音播放程序      private void openFile(File f) {          Intent intent = new Intent();          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);          intent.setAction(android.content.Intent.ACTION_VIEW);          String type = getMIMEType(f);          intent.setDataAndType(Uri.fromFile(f), type);          startActivity(intent);  //      Uri uri=Uri.fromFile(f);  //      MediaPlayer mediaPlayer=MediaPlayer.create(this, uri);  //      try {  //          mediaPlayer.prepare();  //      } catch (IllegalStateException e) {  //          // TODO Auto-generated catch block  //          e.printStackTrace();  //      } catch (IOException e) {  //          // TODO Auto-generated catch block  //          e.printStackTrace();  //      }  //      mediaPlayer.start();      }        private String getMIMEType(File f) {            String end = f.getName().substring(f.getName().lastIndexOf(".") + 1,                  f.getName().length()).toLowerCase();          String type = "";          if (end.equals("mp3") || end.equals("aac") || end.equals("amr")                  || end.equals("mpeg") || end.equals("mp4")) {              type = "audio";          } else if (end.equals("jpg") || end.equals("gif") || end.equals("png")                  || end.equals("jpeg")) {              type = "image";          } else {              type = "*";          }          type += "/";          return type;      }            private void start(){                                TimerTask timerTask=new TimerTask() {                            @Override              public void run() {                  // TODO Auto-generated method stub                  second++;                  if(second>=60){                      second=0;                      minute++;                  }                  handler.sendEmptyMessage(1);              }          };           timer=new Timer();           timer.schedule(timerTask, 1000,1000);                    try {              if (!sdcardExit) {                  Toast.makeText(EX07.this, "请插入SD card",                          Toast.LENGTH_LONG).show();                  return;              }              String  mMinute1=getTime();              Toast.makeText(EX07.this, "当前时间是:"+mMinute1,Toast.LENGTH_LONG).show();              // 创建音频文件  //          myRecAudioFile = File.createTempFile(mMinute1, ".amr",  //                  myRecAudioDir);                            myRecAudioFile=new File(myRecAudioDir,mMinute1+SUFFIX);              mMediaRecorder01 = new MediaRecorder();              // 设置录音为麦克风              mMediaRecorder01                      .setAudioSource(MediaRecorder.AudioSource.MIC);              mMediaRecorder01                      .setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);              mMediaRecorder01                      .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);                            //录音文件保存这里              mMediaRecorder01.setOutputFile(myRecAudioFile                      .getAbsolutePath());              mMediaRecorder01.prepare();              mMediaRecorder01.start();                //          mMediaRecorder01.getMaxAmplitude();  //          mMediaRecorder01.getAudioSourceMax();              mMediaRecorder01.setOnInfoListener(new OnInfoListener() {                                    @Override                  public void onInfo(MediaRecorder mr, int what, int extra) {                      // TODO Auto-generated method stub                      int a=mr.getMaxAmplitude();                      Toast.makeText(EX07.this, a, 500).show();                  }              });                            myTextView1.setText("录音中......");              myButton2.setEnabled(true);              myButton3.setEnabled(false);              myButton4.setEnabled(false);              isStopRecord = false;          } catch (IOException e) {              e.printStackTrace();            }            }      private String getTime(){          SimpleDateFormat   formatter   =   new   SimpleDateFormat   ("yyyy年MM月dd日HH:mm:ss");                Date  curDate=new  Date(System.currentTimeMillis());//获取当前时间                String   time   =   formatter.format(curDate);            System.out.println("当前时间");          return time;          }            Handler handler=new Handler(){            @Override          public void handleMessage(Message msg) {              // TODO Auto-generated method stub              super.handleMessage(msg);                            myTextView1.setText("录音时间:"+minute+":"+second);          }                };            /**      *  @param isAddLastRecord 是否需要添加list之外的最新录音,一起合并      *  @return 将合并的流用字符保存      */      public  void getInputCollection(List list,boolean isAddLastRecord){                              String  mMinute1=getTime();          Toast.makeText(EX07.this, "当前时间是:"+mMinute1,Toast.LENGTH_LONG).show();                    // 创建音频文件,合并的文件放这里          File file1=new File(myRecAudioDir,mMinute1+SUFFIX);          FileOutputStream fileOutputStream = null;                     if(!file1.exists()){              try {                  file1.createNewFile();              } catch (IOException e) {                  // TODO Auto-generated catch block                  e.printStackTrace();              }          }          try {              fileOutputStream=new FileOutputStream(file1);            } catch (IOException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }          //list里面为暂停录音 所产生的 几段录音文件的名字,中间几段文件的减去前面的6个字节头文件                                              for(int i=0;i<list.size();i++){              File file=new File((String) list.get(i));          Log.d("list的长度", list.size()+"");              try {                  FileInputStream fileInputStream=new FileInputStream(file);                  byte  []myByte=new byte[fileInputStream.available()];                  //文件长度                  int length = myByte.length;                            //头文件                  if(i==0){                          while(fileInputStream.read(myByte)!=-1){                                  fileOutputStream.write(myByte, 0,length);                              }                          }                                        //之后的文件,去掉头文件就可以了                  else{                      while(fileInputStream.read(myByte)!=-1){                                                    fileOutputStream.write(myByte, 6, length-6);                      }                  }                                    fileOutputStream.flush();                  fileInputStream.close();                  System.out.println("合成文件长度:"+file1.length());                            } catch (Exception e) {                  // TODO Auto-generated catch block                  e.printStackTrace();              }                                                        }          //结束后关闭流          try {              fileOutputStream.close();          } catch (IOException e) {              // TODO Auto-generated catch block              e.printStackTrace();          }                        //加上当前正在录音的这一段  //          if(isAddLastRecord){  //                //                //              //刚刚录音的  //              try {  //                  FileInputStream fileInputStream=new FileInputStream(myRecAudioFile);  //                  byte  []myByte=new byte[fileInputStream.available()];  //                  System.out.println(fileInputStream.available()+"");  //                  while(fileInputStream.read(myByte)!=-1){  //                      //outputStream.  //                      fileOutputStream.write(myByte, 6, (fileInputStream.available()-6));  //                  }  //                    //                  fileOutputStream.flush();  //                  fileInputStream.close();  //                  fileOutputStream.close();  //                  System.out.println("合成文件长度:"+file1.length());  //              } catch (Exception e) {  //                  // TODO Auto-generated catch block  //                  e.printStackTrace();  //              }  //                //          }                                      //合成一个文件后,删除之前暂停录音所保存的零碎合成文件              deleteListRecord(isAddLastRecord);              //              adapter.add(file1.getName());            }            private void deleteListRecord(boolean isAddLastRecord){          for(int i=0;i<list.size();i++){              File file=new File((String) list.get(i));              if(file.exists()){                  file.delete();              }          }          //正在暂停后,继续录音的这一段音频文件          if(isAddLastRecord){              myRecAudioFile.delete();          }      }  } 

原创粉丝点击