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

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);  
        buttοnpause=(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();  
        }  
    }  
} 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AndroidMediaRecord类可以用来录制音频,包括通过蓝牙设备进行录音。 要使用蓝牙设备录音,首先需要确保设备已经正确配对并连接了蓝牙耳机或扬声器。可以使用BluetoothAdapter类来管理蓝牙连接,以及使用BluetoothDevice类来获取已配对的蓝牙设备。 在开始录音之前,需要先创建一个MediaRecord对象,并设置音频的采样率、编码格式、音频源等参数。可以使用setAudioSource()方法来指定音频源为蓝牙耳机,例如MediaRecorder.AudioSource.MIC。 然后,使用setOutputFile()方法指定音频文件的保存路径和格式。可以使用getFileDescriptor()方法将蓝牙耳机连接的文件描述符作为录音文件的输出。 接下来,需要调用prepare()方法进行准备工作,并使用start()方法开始录音录音过程中,可以使用stop()方法停止录音,并使用release()方法释放MediaRecord对象。 在录音完成后,可以使用MediaPlayer类来播放录音文件,或者使用其他处理方式对录音进行编辑和处理。 需要注意的是,蓝牙耳机的音质和录音效果可能会受到设备和耳机本身的限制,因此可能会在使用过程中遇到问题。在录音过程中,可以使用onErrorListener来处理录音出错的情况,并给出相应的提示。 总体而言,使用AndroidMediaRecord类进行蓝牙录音是很方便的。只需注意正确设置参数和处理录音异常的情况,就可以顺利实现蓝牙录音功能

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值