안 드 로 이 드 음성 인 스 턴 트 메 신 저 녹음,재생 기능 구현 코드

안 드 로 이 드 에서 녹음 과 음성 재생 을 실현 하 는 기능 은 비교적 간단 한 편 이지 만 참고 로 음성 관련 지식 을 간략하게 기록 할 필요 가 있다.
우선,안 드 로 이 드 에 서 는 녹음 지원 두 가지 방식 을 지원 합 니 다.주로 바이트 흐름 모드 와 파일 흐름 모드 를 포함한다.파일 스 트림 모드 로 녹음 작업 을 하 는 것 이 비교적 간단 하고 상대 적 으로 포장 성 이 좋 기 때문에 녹 음 된 파일 도 비교적 작 을 것 이다.그러나 파일 스 트림 모드 에 비해 바이트 스 트림 모드 가 유연 하지 않 지만 바이트 스 트림 모드 를 잘 사용 하려 면 시간 이 필요 합 니 다.
다음은 파일 흐름 모드 의 음성 동작 을 소개 합 니 다.
파일 스 트림 모드
우 리 는 녹음 부분의 실현 을 살 펴 보 자.먼저 우 리 는 녹음 을 시작 하 는 부분 을 실현 한다.
정식 인 코딩 에 앞서 간단 한 설명 이 필요 하 다.일반적으로 녹음 기능 의 실현 은 jin 층 에 있 고 이 층 에 서 는 단일 스 레 드 로 이 루어 진다.만약 에 우리 가 인 코딩 한 녹음 api 에 대해 다 중 스 레 드 작업 을 하면 프로그램 이 직접 반 짝 이 고 자바 층 에서 그 이상 을 포착 할 수 없습니다.그래서 우 리 는 녹음 의 정상 적 인 운행 을 보장 하기 위해 단일 스 레 드 를 사용 해 야 한다.
일반적으로 녹음 을 시작 하 는 절차 도 세 가지 이 고 코드 는 다음 과 같다.

releaseRecord();//              
if (!doStartRecord()) {//          ,        true,    false
  recordFail(); //    ,           
}
다음은 상술 한 세 가지 방법의 실현 을 살 펴 보 자.
실현 은 관련 자원 을 방출 하 는 방법 입 니 다 releaseRecord:

 if (mMediaRecorder != null) {
      mMediaRecorder.release();
      mMediaRecorder = null;
}
이 중 mMediaRecorder 의 MediaRecorder 전역 변수 입 니 다.
다음은 진정 으로 녹음 을 시작 하 는 실현 논리 doStartRecord()

 private boolean doStartRecord() {
    try {
      mMediaRecorder = new MediaRecorder();

      mAudioFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/voice/"
          + System.currentTimeMillis() + ".m4a");
      mAudioFile.getParentFile().mkdirs();
      mAudioFile.createNewFile();

      //          
      mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

      //     mp4   
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

      //    android          
      mMediaRecorder.setAudioSamplingRate(44100);

      //  acc     
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

      //        
      mMediaRecorder.setAudioEncodingBitRate(96000);

      mMediaRecorder.setOutputFile(mAudioFile.getAbsolutePath());

      mMediaRecorder.prepare();
      mMediaRecorder.start();

      mStartRecordTime = System.currentTimeMillis();

    } catch (IOException | RuntimeException e) {
      e.printStackTrace();
      return false;
    }finally {
      if(mAudioRecord != null){
        mAudioRecord.release();
      }
    }

    return true;
  }

이 부분 은 코드 가 비교적 많 지만 관건 적 인 부분 은 제 가 주석 을 달 았 습 니 다.이해 하 는 것 도 어렵 지 않 을 거 라 고 믿 습 니 다.이 부분 에서 우리 가 실현 하 는 것 은 주로 sdcrad 루트 디 렉 터 리 아래 에 voice 디 렉 터 리 를 새로 만 든 다음 에=.m4a==을 접미사 이름 으로 하 는 파일 을 새로 만 드 는 것 입 니 다.mAudio Record 의 관련 매개 변 수 를 설정 한 후 수 집 된 녹음 을 이전 파일 에 저장 합 니 다.모든 것 이 잘 되면 트 루 로 돌아 가 녹음 에 성공 했다 는 뜻 이다.
마지막 으로 사용자 의 녹음 실현 을 제시 하 는 논리 recordFail 입 니 다.

mAudioFile = null;
    mHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
        Toast.makeText(VioceActivity.this, "    ", Toast.LENGTH_SHORT).show();
      }
    }, 100);
이곳 의 논 리 는 비교적 간단 하지만 주의해 야 할 것 은 우리 가 녹음 을 시작 하 는 방법 은 메 인 스 레 드 가 아 닌 스 레 드 에서 실 행 된 것 이기 때문에 우 리 는 hander 를 통 해 인터페이스 알림 효 과 를 실현 해 야 한 다 는 것 이다.이 mHander 는 OnCreate()방법 에 초기 화 된 부분 변수 입 니 다.
mHandler = new Handler(Looper.getMainLooper());
종합 적 으로 녹음 을 시작 하 는 모든 논 리 는 이미 모두 실현 되 었 다.다음은 녹음 을 끝내는 실현 논리 이다.
주제 의 논 리 는 다음 과 같다.

if (!doStopRecord()) {//            ,    true,    false
          recordFail();//        
        }
이곳 의 doStopRecord 실현 논 리 는 다음 과 같다.

 mMediaRecorder.stop();
      mEndRecordTime = System.currentTimeMillis();

      final int seond = (int) ((mEndRecordTime - mStartRecordTime) / 1000);

      if (seond < 3) {
        recordFail();
        return false;
      } else {
        mHandler.post(new Runnable() {
          @Override
          public void run() {
            mText.setText("  " + seond + "  !");
          }
        });
      }
    } catch (RuntimeException e) {
      e.printStackTrace();
      return false;
    }
    return true;
사실 우 리 는 녹음 을 중단 하 는 논 리 를 실현 하 는 것 도 간단 하 다.먼저 mMediaRecorder.stop()을 호출 한다.녹음 을 중단 한 다음 에 녹음 시간 이 3s 이상 인지 판단 하고 3s 이상 이면 녹음 이 효과 적 이 고 사용자 에 게 알려 주 며 녹음 이 성공 했다.
종합 적 으로 우리 파일 흐름 의 녹음 코드 는 이미 실현 되 었 다.이어서 우 리 는 그것 에 대한 방송 을 실현 할 것 이다.모든 코드 를 참고 할 필요 가 있 으 면 여기에 찍 어 주세요.

private void doPlay(File mAudioFile) {
    //      MediaPlayer
    mMediaPlayer = new MediaPlayer();

    try{

      //      
      mMediaPlayer.setDataSource(mAudioFile.getAbsolutePath());

      //      
      mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
          stopPlay();
        }
      });

      //        
      mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
          playFail();
          //    
          stopPlay();
          //     
          return true;
        }
      });

      //    ,    
      mMediaPlayer.setVolume(1,1);
      mMediaPlayer.setLooping(false);

      mMediaPlayer.prepare();
      mMediaPlayer.start();
    }catch (Exception e){
      e.printStackTrace();
      playFail();
      stopPlay();
    }
  }

전체적으로 파일 기반 녹음 은 비교적 쉽게 이 루어 진다.바이트 스 트림 모드 를 통 해 녹음 하 는 방법 을 소개 한다.
바이트 흐름 모드 녹음
녹음 시작:주요 논리 startRecord 2()의 실현

private boolean startRecord2() {
    try {
      mAudioFile2 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/voice/"
          + System.currentTimeMillis() + ".pcm");
      mAudioFile2.getParentFile().mkdirs();
      mAudioFile2.createNewFile();

      mFileOutputStream = new FileOutputStream(mAudioFile2);
      //  AudioRecord

      //        
      int audioSource = MediaRecorder.AudioSource.MIC;

      //    
      int sampleRate = 44100;

      //     
      int channelConfig = AudioFormat.CHANNEL_IN_MONO;

      //  pcm(       Pulse Code Modulation)    
      int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

      //  AudioRecord   buffer     
      int minBufferSize = AudioRecord.getMinBufferSize(sampleRate,channelConfig,audioFormat);
      //  AudioRecord  
      mAudioRecord = new AudioRecord(audioSource,sampleRate,channelConfig,audioFormat,Math.max(BUFFER_SIZE,minBufferSize));

      mAudioRecord.startRecording();
      mStartRecordTime = System.currentTimeMillis();

      //      ,      
      while(mIsRecord){
        int read = mAudioRecord.read(mBuffer,0,BUFFER_SIZE);
        if(read >0 ){
          //         
          mFileOutputStream.write(mBuffer,0,read);
        }else{
          return false;
        }
      }

    } catch (IOException | RuntimeException e) {
      e.printStackTrace();
      return false;
    }

    //    
    return true;
  }

녹음 을 중단 한 doStopRecord()구현:

private boolean doStopRecord() {
    try {

      mMediaRecorder.stop();
      mEndRecordTime = System.currentTimeMillis();

      final int seond = (int) ((mEndRecordTime - mStartRecordTime) / 1000);

      if (seond < 3) {
        recordFail();
        return false;
      } else {
        mHandler.post(new Runnable() {
          @Override
          public void run() {
            mText.setText("  " + seond + "  !");
          }
        });
      }
    } catch (RuntimeException e) {
      e.printStackTrace();
      return false;
    }
    return true;
  }

그 중 관련 매개 변수 에 대한 설명:

 private boolean mIsRecord = false;
  private final int BUFFER_SIZE = 2048;//      
  private byte[] mBuffer;
  private FileOutputStream mFileOutputStream;
  private AudioRecord mAudioRecord;
  private File mAudioFile2;

다음은 바이트 스 트림 모드 에서 녹 음 된 파일 을 재생 하 는 것 입 니 다.doplay 2()테마 클래스 의 실현:

private void doPlay2(File mAudioFile) {

    //    ,     
    int steamType = AudioManager.STREAM_MUSIC;

    //    
    int sampleRate = 44100;

    //MONO                       
    int channelConfig = AudioFormat.CHANNEL_OUT_MONO;

    //    16bit             
    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

    //   
    int mode = AudioTrack.MODE_STREAM;

    //      buffer   
    int minBufferSize =AudioTrack.getMinBufferSize(sampleRate,channelConfig,audioFormat);

    AudioTrack audioTrack = new AudioTrack(steamType,sampleRate,channelConfig,audioFormat,
        Math.max(minBufferSize,BUFFER_SIZE),mode);

    //         
    FileInputStream inputStream = null;

    try{
      inputStream = new FileInputStream(mAudioFile2);
      int read;
      //      ,        
      audioTrack.play();
      while((read = inputStream.read(mBuffer)) > 0){
        int ret = audioTrack.write(mBuffer,0,read);
      switch (ret){
        case AudioTrack.ERROR:
        case AudioTrack.ERROR_BAD_VALUE:
        case AudioTrack.ERROR_INVALID_OPERATION:
        case AudioTrack.ERROR_DEAD_OBJECT:
            playFail();
            return ;
        default:
          break;
      }
      }

    }catch (Exception e){
      e.printStackTrace();
    }finally {
      mIsPlaying = false;

      if(inputStream != null)
        closeQuietly(inputStream);
      resetQuietly(audioTrack);
    }

  }

천만 마디 말 은 직접 코드 로 오 는 것 보다 직접적 으로 하 는 것 이 좋 지 않 을 것 이다.그래서 코드 실현 점 은 여기에 있다.
실현 효 과 는 다음 과 같다.

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기