溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

在Android應(yīng)用中實(shí)現(xiàn)一個(gè)錄音播放功能

發(fā)布時(shí)間:2020-11-20 16:37:54 來源:億速云 閱讀:183 作者:Leah 欄目:移動開發(fā)

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)在Android應(yīng)用中實(shí)現(xiàn)一個(gè)錄音播放功能,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

播放音頻文件

/**
 * Created by zhb on 2017/1/16.
 * 音樂在線播放
 */

public class PlayManager {
 private Context mcontext;
 public PlayManager(Context context){
  this.mcontext = context;
 }

 public void play(String song){
  MediaPlayer mp = new MediaPlayer();
  try {
//   存儲在SD卡或其他文件路徑下的媒體文件
//   例如:mp.setDataSource("/sdcard/test.mp3");
//   網(wǎng)絡(luò)上的媒體文件
//   例如:mp.setDataSource("http://www...../music/test.mp3");
   mp.setDataSource(song);
   mp.prepare();
   mp.start();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

2.錄制amr格式音頻文件(微信語音便用的這種格式,至于音頻文件格式之間的比較請自行百度)

/**
 * Created by zhb on 2017/1/16.
 * 本地錄音
 */

public class RecordManager {
 //錄制成amr格式............................................................
 private Context mcontext;
 MediaRecorder mediaRecorder ;

 public RecordManager(Context context){
  this.mcontext = context;
  //TODO 初始化安裝路徑,錄音流程
 }

 /**開始錄制*/
 public void start_amr(){
  mediaRecorder = new MediaRecorder();
  /**
   * mediaRecorder.setAudioSource設(shè)置聲音來源。
   * MediaRecorder.AudioSource這個(gè)內(nèi)部類詳細(xì)的介紹了聲音來源。
   * 該類中有許多音頻來源,不過最主要使用的還是手機(jī)上的麥克風(fēng),MediaRecorder.AudioSource.MIC
   */
  mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  /**
   * mediaRecorder.setOutputFormat代表輸出文件的格式。該語句必須在setAudioSource之后,在prepare之前。
   * OutputFormat內(nèi)部類,定義了音頻輸出的格式,主要包含MPEG_4、THREE_GPP、RAW_AMR……等。
   */
  mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
  /**
   * mediaRecorder.setAddioEncoder()方法可以設(shè)置音頻的編碼
   * AudioEncoder內(nèi)部類詳細(xì)定義了兩種編碼:AudioEncoder.DEFAULT、AudioEncoder.AMR_NB
   */
  mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  /**
   * 設(shè)置錄音之后,保存音頻文件的位置,一般是SD卡的位置
   */
  mediaRecorder.setOutputFile(String.valueOf(PathManger.getVoicePath()));

  /**
   * 調(diào)用start開始錄音之前,一定要調(diào)用prepare方法。
   */
  try {
   mediaRecorder.prepare();
   mediaRecorder.start();
  }
  catch (IllegalStateException e) {
   e.printStackTrace();
  }
  catch (IOException e) {
   e.printStackTrace();
  }
 }

 /**停止錄音*/
 public void stop_amr(){
  mediaRecorder.stop();
  mediaRecorder.release();
  mediaRecorder = null;
 }

 /**重置錄音*/
 public void reset_amr(){
  mediaRecorder.reset();
 }

}

3、配置轉(zhuǎn)換工具包(這個(gè)比較簡單,配置以下文件即可)

添加flame.jar,并在armeabi和armeabi-v7a文件夾添加libmp3lame.so
資源文件:http://xiazai.jb51.net/201701/yuanma/androidlibmp3lame(jb51.net).rar

4、錄制MP3格式音頻文件(個(gè)人覺得這種格式能比較好的統(tǒng)一Android端和iOS端的音頻文件,雖然方法相對比較繁雜一些)

/**
 * Created by zhb on 2017/1/16.
 * 本地錄音
 */
public class RecordManager {
 //錄制成MP3格式..............................................
 /**構(gòu)造時(shí)候需要的Activity,主要用于獲取文件夾的路徑*/
 private Activity activity;

 /**文件代號*/
 public static final int RAW = 0X00000001;
 public static final int MP3 = 0X00000002;

 /**文件路徑*/
 private String rawPath = null;
 private String mp3Path = null;

 /**采樣頻率*/
 private static final int SAMPLE_RATE = 11025;

 /**錄音需要的一些變量*/
 private short[] mBuffer;
 private AudioRecord mRecorder;

 /**錄音狀態(tài)*/
 private boolean isRecording = false;
 /**是否轉(zhuǎn)換ok*/
 private boolean convertOk = false;

 public RecordManager(Activity activity, String rawPath, String mp3Path) {
  this.activity = activity;
  this.rawPath = rawPath;
  this.mp3Path = mp3Path;
 }

 /**開始錄音*/
 public boolean start_mp3() {
  // 如果正在錄音,則返回
  if (isRecording) {
   return isRecording;
  }
  // 初始化
  if (mRecorder == null) {
   initRecorder();
  }

  getFilePath();
  mRecorder.startRecording();
  startBufferedWrite(new File(rawPath));

  isRecording = true;
  return isRecording;
 }

 /**停止錄音,并且轉(zhuǎn)換文件,這很可能是個(gè)耗時(shí)操作,建議在后臺中做*/
 public boolean stop_mp3() {
  if (!isRecording) {
   return isRecording;
  }

  // 停止
  mRecorder.stop();
  isRecording = false;
//TODO
  // 開始轉(zhuǎn)換
  FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96);
  convertOk = lameUtils.raw2mp3(rawPath, mp3Path);

  return isRecording ^ convertOk;// convertOk==true,return true
 }

 /**獲取文件的路徑*/
 public String getFilePath(int fileAlias) {
  if (fileAlias == RAW) {
   return rawPath;
  } else if (fileAlias == MP3) {
   return mp3Path;
  } else
   return null;
 }

 /**清理文件*/
 public void cleanFile(int cleanFlag) {
  File f = null;
  try {
   switch (cleanFlag) {
    case MP3:
     f = new File(mp3Path);
     if (f.exists())
      f.delete();
     break;
    case RAW:
     f = new File(rawPath);
     if (f.exists())
      f.delete();
     break;
    case RAW | MP3:
     f = new File(rawPath);
     if (f.exists())
      f.delete();
     f = new File(mp3Path);
     if (f.exists())
      f.delete();
     break;
   }
   f = null;
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**關(guān)閉,可以先調(diào)用cleanFile來清理文件*/
 public void close() {
  if (mRecorder != null)
   mRecorder.release();
  activity = null;
 }

 /**初始化*/
 private void initRecorder() {
  int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
    AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
  mBuffer = new short[bufferSize];
  mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
    AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
    bufferSize);
 }

 /**設(shè)置路徑,第一個(gè)為raw文件,第二個(gè)為mp3文件*/
 private void getFilePath() {
  try {
   String folder = "audio_recorder_2_mp3";
   String fileName = String.valueOf(System.currentTimeMillis());
   if (rawPath == null) {
    File raw = new File(activity.getDir(folder,
      activity.MODE_PRIVATE), fileName + ".raw");
    raw.createNewFile();
    rawPath = raw.getAbsolutePath();
    raw = null;
   }
   if (mp3Path == null) {
    File mp3 = new File(activity.getDir(folder,
      activity.MODE_PRIVATE), fileName + ".mp3");
    mp3.createNewFile();
    mp3Path = mp3.getAbsolutePath();
    mp3 = null;
   }

   Log.d("rawPath", rawPath);
   Log.d("mp3Path", mp3Path);

   runCommand("chmod 777 " + rawPath);
   runCommand("chmod 777 " + mp3Path);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**執(zhí)行cmd命令,并等待結(jié)果*/
 private boolean runCommand(String command) {
  boolean ret = false;
  Process process = null;
  try {
   process = Runtime.getRuntime().exec(command);
   process.waitFor();
   ret = true;
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   try {
    process.destroy();
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
  return ret;
 }

 /**寫入到raw文件*/
 private void startBufferedWrite(final File file) {
  new Thread(new Runnable() {
   @Override
   public void run() {
    DataOutputStream output = null;
    try {
     output = new DataOutputStream(new BufferedOutputStream(
       new FileOutputStream(file)));
     while (isRecording) {
      int readSize = mRecorder.read(mBuffer, 0,
        mBuffer.length);
      for (int i = 0; i < readSize; i++) {
       output.writeShort(mBuffer[i]);
      }
     }
    } catch (IOException e) {
     e.printStackTrace();
    } finally {
     if (output != null) {
      try {
       output.flush();
      } catch (IOException e) {
       e.printStackTrace();

      } finally {
       try {
        output.close();
       } catch (IOException e) {
        e.printStackTrace();
       }
      }
     }
    }
   }
  }).start();
 }
}

5、最后在自己想調(diào)用的地方調(diào)用就好了,PathManger這個(gè)是我自己的路徑管理工具,這里不貼了,反正自己直接放一個(gè)路徑字符串進(jìn)去就好了

/**初始化語音*/
 private void initVoice() {
 //錄音
 RecordManager = new RecordManager(
  CallHelpActivity.this,
  String.valueOf(PathManger.getVoicePathToRaw()),
  String.valueOf(PathManger.getVoicePathToMp3()));
 callHelp_Voice_longclick.setOnTouchListener(new View.OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
  switch(event.getAction()){
   case MotionEvent.ACTION_DOWN:
   RecordManager.start_mp3();
   break;
   case MotionEvent.ACTION_MOVE:

   break;
   case MotionEvent.ACTION_UP:
   RecordManager.stop_mp3();
   break;
  }
  return false;
  }
 });
 //語音播放
 final PlayManager PlayManager = new PlayManager(this);
 callHelp_Voice_click.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  PlayManager.play(String.valueOf(PathManger.getVoicePathToMp3()));
  }
 });
 }

上述就是小編為大家分享的在Android應(yīng)用中實(shí)現(xiàn)一個(gè)錄音播放功能了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI