Android实现语音播放与录音功能

本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下

项目用到的技术点和亮点

  • 语音录音 (单个和列表)
  • 语音播放(单个和列表)
  • 语音录音封装
  • 语音播放器封装
  • 语音列表顺序播放
  • 语音列表单个播放 复用问题处理

因为安装原生录音不能录mp3格式文件 而mp3格式是安卓和ios公用的,所以我们需要的是能直接录取mp3文件或者录完的格式转成mp3格式

下面添加这个库 能直接录mp3文件,我觉得是最方便的

compile ‘com.czt.mp3recorder:library:1.0.3'

1. 语音录音封装

代码简单 自己看吧

package com.video.zlc.audioplayer;

import com.czt.mp3recorder.MP3Recorder;
import com.video.zlc.audioplayer.utils.LogUtil;

import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
 * @author zlc
 */
public class AudioManage {

  private MP3Recorder mRecorder;
  private String mDir;       // 文件夹的名称
  private String mCurrentFilePath;
  private static AudioManage mInstance;

  private boolean isPrepared; // 标识MediaRecorder准备完毕
  private AudioManage(String dir) {
    mDir = dir;
    LogUtil.e("AudioManage=",mDir);
  }

  /**
   * 回调“准备完毕”
   * @author zlc
   */
  public interface AudioStateListenter {
    void wellPrepared();  // prepared完毕
  }

  public AudioStateListenter mListenter;

  public void setOnAudioStateListenter(AudioStateListenter audioStateListenter) {
    mListenter = audioStateListenter;
  }

  /**
   * 使用单例实现 AudioManage
   * @param dir
   * @return
   */
  public static AudioManage getInstance(String dir) {
    if (mInstance == null) {
      synchronized (AudioManage.class) {  // 同步
        if (mInstance == null) {
          mInstance = new AudioManage(dir);
        }
      }
    }
    return mInstance;
  }

  /**
   * 准备录音
   */
  public void prepareAudio() {

    try {
      isPrepared = false;
      File dir = new File(mDir);
      if (!dir.exists()) {
        dir.mkdirs();
      }
      String fileName = GenerateFileName(); // 文件名字
      File file = new File(dir, fileName); // 路径+文件名字
      //MediaRecorder可以实现录音和录像。需要严格遵守API说明中的函数调用先后顺序.
      mRecorder = new MP3Recorder(file);
      mCurrentFilePath = file.getAbsolutePath();
//     mMediaRecorder = new MediaRecorder();
//     mCurrentFilePath = file.getAbsolutePath();
//     mMediaRecorder.setOutputFile(file.getAbsolutePath());  // 设置输出文件
//     mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  // 设置MediaRecorder的音频源为麦克风
//     mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);  // 设置音频的格式
//     mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  // 设置音频的编码为AMR_NB
//     mMediaRecorder.prepare();
//     mMediaRecorder.start();
      mRecorder.start();  //开始录音
      isPrepared = true; // 准备结束
      if (mListenter != null) {
        mListenter.wellPrepared();
      }
    } catch (Exception e) {
      e.printStackTrace();
      LogUtil.e("prepareAudio",e.getMessage());
    }

  }

  /**
   * 随机生成文件名称
   * @return
   */
  private String GenerateFileName() {
    // TODO Auto-generated method stub
    return UUID.randomUUID().toString() + ".mp3"; // 音频文件格式
  }

  /**
   * 获得音量等级——通过mMediaRecorder获得振幅,然后换算成声音Level
   * maxLevel最大为7;
   * @return
   */
  public int getVoiceLevel(int maxLevel) {
    if (isPrepared) {
      try {
        mRecorder.getMaxVolume();
        return maxLevel * mRecorder.getMaxVolume() / 32768 + 1;
      } catch (Exception e) {
         e.printStackTrace();
      }
    }
    return 1;
  }

  /**
   * 释放资源
   */
  public void release() {
    if(mRecorder != null) {
      mRecorder.stop();
      mRecorder = null;
    }
  }

  /**
   * 停止录音
   */
  public void stop(){
    if(mRecorder!=null && mRecorder.isRecording()){
      mRecorder.stop();
    }
  }

  /**
   * 取消(释放资源+删除文件)
   */
  public void delete() {
    release();
    if (mCurrentFilePath != null) {
      File file = new File(mCurrentFilePath);
      file.delete();  //删除录音文件
      mCurrentFilePath = null;
    }
  }

  public String getCurrentFilePath() {
    return mCurrentFilePath;
  }

  public int getMaxVolume(){
    return mRecorder.getMaxVolume();
  }

  public int getVolume(){
    return mRecorder.getVolume();
  }
}

2. 语音播放器封装

package com.video.zlc.audioplayer.utils;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;

/**
 *
 * @author zlc
 *
 */
public class MediaManager {

  private static MediaPlayer mMediaPlayer;  //播放录音文件
  private static boolean isPause = false;

  static {
    if(mMediaPlayer==null){
      mMediaPlayer=new MediaPlayer();
      mMediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() {

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
          mMediaPlayer.reset();
          return false;
        }
      });
    }
  }

  /**
   * 播放音频
   * @param filePath
   * @param onCompletionListenter
   */
  public static void playSound(Context context,String filePath, MediaPlayer.OnCompletionListener onCompletionListenter){

    if(mMediaPlayer==null){
      mMediaPlayer = new MediaPlayer();
      mMediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
          mMediaPlayer.reset();
          return false;
        }
      });
    }else{
      mMediaPlayer.reset();
    }
    try {
      //详见“MediaPlayer”调用过程图
      mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
      mMediaPlayer.setOnCompletionListener(onCompletionListenter);
      mMediaPlayer.setDataSource(filePath);
      mMediaPlayer.prepare();
      mMediaPlayer.start();
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      LogUtil.e("语音error==",e.getMessage());
    }
  }

  /**
   * 暂停
   */
  public synchronized static void pause(){
    if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
      mMediaPlayer.pause();
      isPause=true;
    }
  }

  //停止
  public synchronized static void stop(){
    if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
      mMediaPlayer.stop();
      isPause=false;
    }
  }

  /**
   * resume继续
   */
  public synchronized static void resume(){
    if(mMediaPlayer!=null && isPause){
      mMediaPlayer.start();
      isPause=false;
    }
  }

  public static boolean isPause(){
    return isPause;
  }

  public static void setPause(boolean isPause) {
    MediaManager.isPause = isPause;
  }

  /**
   * release释放资源
   */
  public static void release(){
    if(mMediaPlayer!=null){
      isPause = false;
      mMediaPlayer.stop();
      mMediaPlayer.release();
      mMediaPlayer = null;
    }
  }

  public synchronized static void reset(){
    if(mMediaPlayer!=null) {
      mMediaPlayer.reset();
      isPause = false;
    }
  }

  /**
   * 判断是否在播放视频
   * @return
   */
  public synchronized static boolean isPlaying(){

    return mMediaPlayer != null && mMediaPlayer.isPlaying();
  }
}

3. 语音列表顺序播放

 private int lastPos = -1;
  //播放语音
 private void playVoice(final int position, String from) {

    LogUtil.e("playVoice position",position+"");
    if(position >= records.size()) {
      LogUtil.e("playVoice","全部播放完了");
      stopAnimation();
      MediaManager.reset();
      return;
    }

    String voicePath = records.get(position).getPath();
    LogUtil.e("playVoice",voicePath);
    if(TextUtils.isEmpty(voicePath) || !voicePath.contains(".mp3")){
      Toast.makeText(this,"语音文件不合法",Toast.LENGTH_LONG).show();
      return;
    }

    if(lastPos != position && "itemClick".equals(from)){
      stopAnimation();
      MediaManager.reset();
    }
    lastPos = position;

//获取listview某一个条目的图片控件
    int pos = position - id_list_voice.getFirstVisiblePosition();
    View view = id_list_voice.getChildAt(pos);
    id_iv_voice = (ImageView) view.findViewById(R.id.id_iv_voice);
    LogUtil.e("playVoice position",pos+"");

    if(MediaManager.isPlaying()){
      MediaManager.pause();
      stopAnimation();
    }else if(MediaManager.isPause()){
      startAnimation();
      MediaManager.resume();
    }else{
      startAnimation();
      MediaManager.playSound(this,voicePath, new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
          //播放完停止动画 重置MediaManager
          stopAnimation();
          MediaManager.reset();

          playVoice(position + 1, "loop");
        }
      });
    }
  }

4. 语音列表单个播放 复用问题处理

播放逻辑基本同上

private int lastPosition = -1;
  private void playVoice(FendaListInfo.ObjsEntity obj, int position) {
    String videoPath = obj.path;
    if(TextUtils.isEmpty(videoPath) || !videoPath.contains(".mp3")){
      Toast.makeText(this,"语音文件不合法",Toast.LENGTH_LONG).show();
      return;
    }
    if(position != lastPosition){ //点击不同条目先停止动画 重置音频资源
      stopAnimation();
      MediaManager.reset();
    }
    if(mAdapter!=null)
      mAdapter.selectItem(position, lastPosition);
    lastPosition = position;

    id_iv_voice.setBackgroundResource(R.drawable.animation_voice);
    animationDrawable = (AnimationDrawable) id_iv_voice.getBackground();
    if(MediaManager.isPlaying()){
      stopAnimation();
      MediaManager.pause();
    }else if(MediaManager.isPause()){
      startAnimation();
      MediaManager.resume();
    }else{
      startAnimation();
      MediaManager.playSound(this,videoPath, new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
          LogUtil.e("onCompletion","播放完成");
          stopAnimation();
          MediaManager.stop();
        }
      });
    }
  }

//核心方法
 //点击了某一个条目 这个条目isSelect=true 上一个条目isSelect需要改为false 防止滑动过程中 帧动画复用问题
  public void selectItem(int position, int lastPosition) {

    LogUtil.e("selectItem"," ;lastPosition="+lastPosition+" ;position="+position);
    if(lastPosition >= 0 && lastPosition < mDatas.size() && lastPosition != position){
      FendaListInfo.ObjsEntity bean = mDatas.get(lastPosition);
      bean.isSelect = false;
      mDatas.set(lastPosition, bean);
      notifyDataSetChanged();
    }

    if(position < mDatas.size() && position != lastPosition){
      FendaListInfo.ObjsEntity bean = mDatas.get(position);
      bean.isSelect = true;
      mDatas.set(position,bean);
    }
  }
/**
 * 适配器图片播放的动画处理
 */
private void setVoiceAnimation(ImageView iv_voice, FendaListInfo.ObjsEntity obj) {

    //处理动画复用问题
    AnimationDrawable animationDrawable;
    if(obj.isSelect){
      iv_voice.setBackgroundResource(R.drawable.animation_voice);
      animationDrawable = (AnimationDrawable) iv_voice.getBackground();
      if(MediaManager.isPlaying() && animationDrawable!=null){
        animationDrawable.start();
      }else{
        iv_voice.setBackgroundResource(R.drawable.voice_listen);
        animationDrawable.stop();
      }
    }else{
      iv_voice.setBackgroundResource(R.drawable.voice_listen);
    }
  }

5.下载地址

Android实现语音播放与录音

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

(0)

相关推荐

  • Android仿微信语音对讲录音功能

    自微信出现以来取得了很好的成绩,语音对讲的实现更加方便了人与人之间的交流.今天来实践一下微信的语音对讲的录音实现,这个也比较容易实现.在此,我将该按钮封装成为一个控件,并通过策略模式的方式实现录音和界面的解耦合,以方便我们在实际情况中对录音方法的不同需求(例如想要实现wav格式的编码时我们也就不能再使用MediaRecorder,而只能使用AudioRecord进行处理). 效果图: 实现思路: 1.在微信中我们可以看到实现语音对讲的是通过点按按钮来完成的,因此在这里我选择重新自己的控件使其继承

  • Android开发四大组件之实现电话拦截和电话录音

    一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断. 当拨打电话或电话状态发生改变时,系统就会发出有序广播,因此我们可以使用BordercastReceiver接受广播,因BordercastReceiver执行时间短不能执行耗时任务也不能使用子线程,因此我们应启动一个Service来监听电话并进行处理 二.加入AIDL文件 Android没有对外

  • Android App调用MediaRecorder实现录音功能的实例

    MediaRecorder Android的MediaRecorder包含了Audio和video的记录功能,在Android的界面上,Music和Video两个应用程序都是调用MediaRecorder实现的. MediaRecorder在底层是基于OpenCore(PacketVideo)的库实现的,为了构建一个MediaRecorder程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础是Android基本库中的Binder机制. 以开源的Android为例MediaRecorder的

  • android语音即时通讯之录音、播放功能实现代码

    在android中,实现录音与语音播放的功能算是比较简单的,但是作为参考,还是很有必要将语音相关的知识做一个简要的记录. 首先,在android中,支持录音支持两种方式.主要包括:字节流模式和文件流模式.用文件流模式进行录音操作比较简单,而且相对来说,因为其封装性比较好,录制下的文件也会比较小.但是相对于文件流模式,就没有字节流模式那么灵活,但是想要用好字节流模式还是需要下一点功夫的. 下面开始介绍文件流模式的语音操作: 文件流模式 我们来看录音部分的实现,首先我们实现开始录音的部分: 在正式编

  • Android应用开发:电话监听和录音代码示例

    在oncreate 中执行: 复制代码 代码如下: public void onCreate() {  super.onCreate();  Log.i("TAG", "服务启动了"); // 对电话的来电状态进行监听  TelephonyManager telManager = (TelephonyManager) this    .getSystemService(Context.TELEPHONY_SERVICE);  // 注册一个监听器对电话状态进行监听 

  • Android 实现电话来去自动录音的功能

    我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能. 来去电自动录音的关键在于如何监听手机电话状态的转变: 1)来电的状态的转换如下(红色标记是我们要用到的状态) 空闲(IDEL)--> 响铃(RINGING)--> 接听(ACTIVE)--> 挂断(经历DISCONNECTING--DISCONNECTED)--> 空闲(IDEL) 或者  空闲(IDEL)

  • Android实现录音功能实现实例(MediaRecorder)

    本文介绍了Android实现录音的实例代码(MediaRecorder),分享给大家,具体如下: Android提供了两个API用于录音的实现:MediaRecorder 和 AudioRecord,各有优劣. 1.MediaRecorder 已经集成了录音.编码.压缩等,支持少量的录音音频格式,大概有.aac(API = 16) .amr .3gp 优点:大部分已经集成,直接调用相关接口即可,代码量小 缺点:无法实时处理音频:输出的音频格式不是很多,例如没有输出mp3格式文件 2.AudioR

  • Android实现录音方法(仿微信语音、麦克风录音、发送语音、解决5.0以上BUG)

    先给大家展示下效果图,如果大家感觉不错,请参考使用方法, 效果图如下所示: 使用方法: 录音工具类:AudioRecoderUtils.java,代码如下: public class AudioRecoderUtils { //文件路径 private String filePath; //文件夹路径 private String FolderPath; private MediaRecorder mMediaRecorder; private final String TAG = "fan&q

  • Android简单的利用MediaRecorder进行录音的实例代码

    复制代码 代码如下: package com.ppmeet; import java.io.IOException; import android.app.Activity;  import android.graphics.PixelFormat;  import android.media.MediaRecorder;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClick

  • Android音频录制MediaRecorder之简易的录音软件实现代码

    使用MediaRecorder的步骤:1.创建MediaRecorder对象2.调用MediRecorder对象的setAudioSource()方法设置声音的来源,一般传入MediaRecorder.MIC3.调用MediaRecorder对象的setOutputFormat()设置所录制的音频文件的格式4.调用MediaRecorder对象的setAudioRncoder().setAudioEncodingBitRate(int bitRate).setAudioSamlingRate(i

随机推荐