热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android录音播放管理工具

这篇文章主要为大家详细介绍了Android录音播放管理工具,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

1、语音播放直接用系统工具就好了,这个就不多说了,根据传入的路径(网络路径或本地路径均可)播放音频文件

/**
 * 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");
//   网络上的媒体文件
//   例如: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设置声音来源。
   * MediaRecorder.AudioSource这个内部类详细的介绍了声音来源。
   * 该类中有许多音频来源,不过最主要使用的还是手机上的麦克风,MediaRecorder.AudioSource.MIC
   */
  mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  /**
   * mediaRecorder.setOutputFormat代表输出文件的格式。该语句必须在setAudioSource之后,在prepare之前。
   * OutputFormat内部类,定义了音频输出的格式,主要包含MPEG_4、THREE_GPP、RAW_AMR……等。
   */
  mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
  /**
   * mediaRecorder.setAddioEncoder()方法可以设置音频的编码
   * AudioEncoder内部类详细定义了两种编码:AudioEncoder.DEFAULT、AudioEncoder.AMR_NB
   */
  mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  /**
   * 设置录音之后,保存音频文件的位置,一般是SD卡的位置
   */
  mediaRecorder.setOutputFile(String.valueOf(PathManger.getVoicePath()));

  /**
   * 调用start开始录音之前,一定要调用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、配置转换工具包(这个比较简单,配置以下文件即可)

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

4、录制MP3格式音频文件(个人觉得这种格式能比较好的统一Android端和iOS端的音频文件,虽然方法相对比较繁杂一些)

/**
 * Created by zhb on 2017/1/16.
 * 本地录音
 */
public class RecordManager {
 //录制成MP3格式..............................................
 /**构造时候需要的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;

 /**录音状态*/
 private boolean isRecording = false;
 /**是否转换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;
 }

 /**停止录音,并且转换文件,这很可能是个耗时操作,建议在后台中做*/
 public boolean stop_mp3() {
  if (!isRecording) {
   return isRecording;
  }

  // 停止
  mRecorder.stop();
  isRecording = false;
//TODO
  // 开始转换
  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();
  }
 }

 /**关闭,可以先调用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);
 }

 /**设置路径,第一个为raw文件,第二个为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();
  }
 }

 /**执行cmd命令,并等待结果*/
 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 

5、最后在自己想调用的地方调用就好了,PathManger这个是我自己的路径管理工具,这里不贴了,反正自己直接放一个路径字符串进去就好了

/**初始化语音*/
 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()));
  }
 });
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • Vue 2 中解决页面刷新和按钮跳转导致导航栏样式失效的问题
    本文介绍了如何通过配置路由的 meta 字段,确保 Vue 2 项目中的导航栏在页面刷新或内部按钮跳转时,始终保持正确的 active 样式。具体实现方法包括设置路由的 meta 属性,并在 HTML 模板中动态绑定类名。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 本文将详细介绍如何使用剪映应用中的镜像功能,帮助用户轻松实现视频的镜像效果。通过简单的步骤,您可以快速掌握这一实用技巧。 ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 如何在PHPcms网站中添加广告
    本文详细介绍了在PHPcms网站后台添加广告的方法,涵盖多种常见的广告形式,如百度广告和Google广告,并提供了相关设置的步骤。同时,文章还探讨了优化网站流量的SEO策略。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • 本文介绍如何通过Windows批处理脚本定期检查并重启Java应用程序,确保其持续稳定运行。脚本每30分钟检查一次,并在需要时重启Java程序。同时,它会将任务结果发送到Redis。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文介绍如何通过SQL查询从JDE(JD Edwards)系统中提取所有字典数据,涵盖关键表的关联和字段选择。具体包括F0004和F0005系列表的数据提取方法。 ... [详细]
  • 本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
author-avatar
何止爱你2010_694
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有