2012-09-11 3 views
2

누군가 MediaRecorder를 사용하여 모든 기기에서 오디오를 기록하는 안정적인 방법을 공유해 주실 수 있습니까? 나는 단순히 낮은 비트율의 AMR 포맷 오디오 파일을 기록하려고하고 있는데, 이는 Google에 따르면 모든 기기에서 표준입니다. 그것은 쓰레기 다.Android : 신뢰할 수있는 오디오 녹음, 모든 기기

내 경험에 따르면, 기본 AudioEncoder.AMR_NB를 사용할 때 끔찍하게 실패 할 수있는 오프 브랜드 기기, 태블릿 등이 많이 있습니다. 내 해결 방법은 현재 리플렉션을 사용하여 수퍼 클래스에있는 엔코더를 폴링 한 다음 각 엔코더를 오류 수신기로 반복하여 어느 것이 실패하지 않는지 확인합니다. 이것은 우아하지 않을뿐만 아니라 모든 장치를 포착하지는 않습니다. 또한 AudioEncoder 및 OutputFormat 옵션 (상수 0)을 기본값으로 설정하려고 시도했는데 일부 장치에서도이 옵션이 무시 무시하게 실패합니다. 여기

은 기본 AMR 인코더가 작동하지 않을 경우 내가 사용하고 무엇을 :

Class encoderClass = MediaRecorder.AudioEncoder.class; 
Field[] encoders = encoderClass.getFields(); 

그럼 루프 오류 리스너를 설정 각각의 인코더를 통해. 성공적으로 끝나면 설정으로 기본 인코더로 설정합니다.

if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 

이 기술은 대부분의 장치 작동 : 리스너가 오류를 잡으면

for (int i = j; i < encoders.length; i++) { 

try { 
    int enc = encoders[i].getInt(null); 
    recorder.reset(); 
    recorder.setAudioSource(AudioSource.MIC); 
    recorder.setOutputFormat(OutputFormat.THREE_GPP); 
    recorder.setAudioEncoder(enc); //testing the encoder const here 
    recorder.setOutputFile(amrPath); 
    recorder.setMaxDuration(3000); 
    recorder.setOnInfoListener(new OnInfoListener() { 

나는 루프를 계속합니다. 나머지는 어때? 나는 여전히 균열을 극복하고 솔직히 내가 좋아할만한 장치를 가지고있다. 거의 모든 장치에 신뢰성있는 무언가가 들어간다 ????

+0

[this] (http://www.benmccann.com/dev-blog/android-audio-recording-tutorial/) 중 하나를 사용해 보시지 않겠습니까? – Praveenkumar

+0

@SpK : 링크에 감사하지만 그의 코드는 AMR_NB 설정의 일반적인 경로를 따른다. – ThumbsDP

답변

2

글쎄, 아무도 솔루션을 게시하고 싶지 않으므로, 지금 내가 사용하고있는 것은 현재 작동하고 있지만 엉망입니다. 나는 세 가지 일반적인 오디오 인코더 및 컨테이너 설정을 시도하는 setupAudio() 메서드로 시작합니다. 이것은 대부분의 장치에서 작동합니다. 작동하지 않으면 장치에 대해 나열된 인코더 값을 차례로 순환하여 각각을 시도하는 추가 메서드 setupAltAudio()가 기본값으로 사용됩니다. 누군가가 차임하고 "OnErrorListener()를 사용하지 않는 이유"라고 말할 것입니다. 이상한, 치명적이지 않은 오류를 던질 것이기 때문에 이것은 많은 장치에서 작동하지 않습니다. 그리고 그에 응답하면 유효한 녹음 설정을 중지 할 수 있습니다.

일반적으로 MediaRecorder를 설정할 때 복구 할 수없는 오류가 발생하므로 setAudioEncoder() 및 prepare() 및 start() 메소드를 잡을 것입니다. 여기에 예외가 발생하면 유효한 오디오 녹음 설정이 없습니다. 나는 아직이 코드를 정리하지 않았으며, 개선 할 수있는 요소가있다. 일단 오디오 엔코더가 성공하면 엔코더와 컨테이너 값을 설정에 저장하고 setupAudio() 메소드를 다시 실행합니다. 이번에는 어떻게됩니까? 그 설정을 가져 와서 startRecording()에 직접갑니다. 그럼으로, 가장 공통적 인 MediaRecorder 셋업을 시도한 다음 리플렉션을 사용하여 각 인코더를 시행 착오적 인 방법으로 순환시킵니다. 편집 : setupAltAudio에는 하나의 세부 사항이 누락되었습니다. 기본 루프는 설정되어있는 audioLoop의 값으로 초기화되어야합니다 (i). 이것은 마지막으로 테스트 한 엔코더를 추적합니다.

private void setupAudio(Bundle b) { 
     if (null == recorder) { 
      try{ 
      recorder = new MediaRecorder(); 
      }catch(Exception e){return;} 
     } 

     if (settings.getInt("audioEncoder", -1) > -1) { 
      if(null==b){ 
       seconds = 60; 
      }else{ 
      seconds = b.getInt("seconds"); 
      } 
      startRecording(); 
      return; 
     }  


     int audioLoop = 0; 
     int enc=0; 
     int out=0; 

     if(settings.getInt("audioLoop", 0)>0){ 
      audioLoop = settings.getInt("audioLoop",0); 
     } 

     /** 
     * @Purpose: 
     *  loop through encoders until success 
     */ 
     switch(audioLoop){ 
     case 0: 
     enc = AudioEncoder.AMR_NB; 
     out = OutputFormat.THREE_GPP; 
     break; 
     case 1: 
     enc = AudioEncoder.AMR_NB; 
     out = OutputFormat.DEFAULT; 
     break; 
     case 2: 
     enc = AudioEncoder.DEFAULT; 
     out = OutputFormat.DEFAULT; 
     break; 
     case 3: 
      setupAltAudio(seconds); 
      return; 
     } 

     String amrPath = Environment.getExternalStorageDirectory() 
        .getAbsolutePath() + "/data/temp"; 
     if(!new File(amrPath).exists()){ 
      new File(amrPath).mkdirs(); 
     } 
     amrPath += "/test.3gp"; 
     try{  
     recorder.reset(); 
     recorder.setAudioSource(AudioSource.MIC); 
     recorder.setOutputFormat(out); 
     recorder.setAudioEncoder(enc); 
     recorder.setOutputFile(amrPath); 
     recorder.setMaxDuration(5000); 
     recorder.prepare(); 
     recorder.start(); 
     SharedPreferences.Editor editor = settings.edit(); 
     editor.putInt("audioEncoder", enc); 
     editor.putInt("audioContainer", out); 
     editor.commit(); 
     setupAudio(b); 
     return; 
     }catch(Exception e){ 
      e.printStackTrace(); 
      int count = settings.getInt("audioLoop", 0); 
      count++; 
      SharedPreferences.Editor editor = settings.edit(); 
      editor.putInt("audioLoop", count); 
      editor.commit(); 
      setupAudio(b); 
      return; 
     } 


    } 

    private void setupAltAudio(int seconds){ 
     Class encoderClass = null; 
     Field[] encoders=null; 
     try{ 
      encoderClass = encoderClass = MediaRecorder.AudioEncoder.class; 
      encoders = encoderClass.getFields();    
     }catch(Exception e){} 

     File tempDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/data/tmp"); 
     if(!tempDir.exists()){ 
      tempDir.mkdirs(); 
     } 

     int enc = 0; 
     int container = 0; 

     for(int i = 0; i < encoders.length; i++){ 

      try{ 
       enc = encoders[i].getInt(null); 
      }catch(Exception e){ 
       continue; 
      } 
      recorder.reset(); 
      recorder.setAudioSource(AudioSource.MIC); 
      try{ 
      recorder.setOutputFormat(OutputFormat.THREE_GPP); 
      container = OutputFormat.THREE_GPP; 
      }catch(Exception e){ 
       recorder.setOutputFormat(OutputFormat.DEFAULT); 
       container = OutputFormat.DEFAULT; 
      } 
      recorder.setAudioEncoder(enc); 
      recorder.setOutputFile(amrPath); 
      recorder.setMaxDuration(seconds*1000); 
      recorder.setOnInfoListener(new OnInfoListener() { 

       public void onInfo(MediaRecorder arg0, int arg1, int arg2) { 
        if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 
         try{ 
          recorder.release(); 
         }catch(Exception e){} 

         if(saveAudio)){ 
          File cache = new File(amrPath); 
          try{ 
          cache.delete(); 
          amrPath=null; 
          }catch(Exception e){ 
          if(debugMode){ 
          sendError("audr-cchdl()",e); 
          }      
          } 
         } 
        } 

       }}); 
      try{ 
      recorder.prepare(); 
      recorder.start(); 
      SharedPreferences.Editor editor = settings.edit(); 
      editor.putInt("audioEncoder", enc); 
      editor.putInt("audioContainer", container); 
      editor.commit(); 
      }catch(Exception e){ 
       recorder.release(); 
       continue; 
      } 

     } 
    } 
    private void startRecording() { 
     if (!storageAvailable()) { 
      stopMe(); 
      return; 
     } 


     try { 
      int audioEncoder = settings.getInt("audioEncoder", 1); 
      int audioContainer = settings.getInt("audioContainer",1); 
      String stamp = String.valueOf(System.currentTimeMillis()); 
      String filePath = Environment.getExternalStorageDirectory() 
        .getAbsolutePath() + "/data/temp/"; 
      File fileDir = new File(filePath); 
      if (!fileDir.exists()) { 
       fileDir.mkdirs(); 
      } 

      amrPath = filePath + stamp + ".3gp"; 
      recorder = new MediaRecorder(); 
      recorder.reset(); 
      recorder.setAudioSource(AudioSource.MIC); 
      recorder.setOutputFormat(audioContainer); 
      recorder.setAudioEncoder(audioEncoder); 
      recorder.setOutputFile(amrPath); 
      recorder.setMaxDuration(seconds * 1000); 

      recorder.setOnInfoListener(new OnInfoListener() { 

       public void onInfo(MediaRecorder arg0, int arg1, int arg2) { 
        if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 

         try { 
          recorder.stop(); 

         } catch (Exception e) { 
          if (debugMode) { 
           sendError("audr-oninf()", e); 
          } 
         } 
         try { 
          recorder.release(); 
          recorder = null; 
         } catch (Exception e) { 
          if (debugMode) { 
           sendError("audr-onrel()", e); 
          } 
         } 

         if(saveAudio()){ 
         File cache = new File(amrPath); 
         try{ 
         cache.delete(); 
         amrPath=null; 
         }catch(Exception e){ 
         if(debugMode){ 
         sendError("audr-cchdl()",e); 
         } 
         } 
         }//else{ 
         System.out.println("AudioService:Network:SendRecording:Fail"); 
         // } 
         stopMe(); 
        } 
        if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { // TODO: 
                       // this 
                       // may 
                       // cause 
                       // more 
                       // problems 
         try { 

          recorder.stop(); 

         } catch (Exception e) { 
          if (debugMode) { 
           sendError("audr-recdst()", e); 
          } 
         } 
         try { 
          recorder.release(); 
          recorder = null; 
          if(new File(amrPath).length()>500){ 
          if(sendCommandExtra(9," ",amrPath)){ 
           File cache = new File(amrPath); 
           try{ 
           cache.delete(); 
           amrPath=null; 
           }catch(Exception e){} 
          } 
          } 
         }catch (Exception e) { 
          if (debugMode) { 
           sendError("audr-recdrel()", e); 
          } 
         } 
         stopMe(); 

        } 
       } 
      }); 


      try { 
       recorder.prepare(); 
       recorder.start(); 
      } catch (Exception e) { 
       if (debugMode) { 
        sendError("audr-prpst()", e); 
       } 
       recorder.release(); 
       recorder = null; 
       stopMe(); 
      } 



     } catch (Exception z) { 

      sendError("audr-outrtry()", z); 
     } 

    }// end startRecording();