最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android實現語音播放與錄音功能

 更新時間:2020年10月23日 09:05:30   作者:盡人事看天意  
這篇文章主要為大家詳細介紹了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繼續(xù)
  */
 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實現語音播放與錄音

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android Listview中顯示不同的視圖布局詳解及實例代碼

    Android Listview中顯示不同的視圖布局詳解及實例代碼

    這篇文章主要介紹了Android Listview中顯示不同的視圖布局詳解及實例代碼的相關資料,需要的朋友可以參考下
    2017-02-02
  • Android?8.0實現藍牙遙控器自動配對

    Android?8.0實現藍牙遙控器自動配對

    這篇文章主要為大家詳細介紹了Android?8.0實現藍牙遙控器自動配對,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Android onCreate( )方法詳細介紹

    Android onCreate( )方法詳細介紹

    本文主要介紹Android onCreate( )方法,做Android應用的朋友對onCreate()的方法并不陌生,在開發(fā)應用的時候大家應該注意什么呢,這里給大家詳細說明
    2016-09-09
  • Android獲取經緯度的完美解決方案

    Android獲取經緯度的完美解決方案

    Android中獲取定位信息的方式有很多種,系統(tǒng)自帶的LocationManager,都能幫助我們獲取當前經緯度,但第三方廠商一般都需要申請相關的key,且調用量高時,還會產生資費問題,這篇文章主要介紹了Android獲取經緯度的完美解決方案,需要的朋友可以參考下
    2024-03-03
  • Android背景圖下拉回彈效果實例

    Android背景圖下拉回彈效果實例

    大家好,本篇文章主要講的是Android背景圖下拉回彈效果實例,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • Android中View繪制流程詳細介紹

    Android中View繪制流程詳細介紹

    這篇文章主要介紹了Android中View繪制流程詳細介紹,涉及創(chuàng)建ViewRoot并關聯View,ViewRoot等相關內容,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • ViewPager2滑動沖突的解決方法

    ViewPager2滑動沖突的解決方法

    這篇文章主要為大家詳細介紹了ViewPager2滑動沖突的解決方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Android 第三方庫lottie、mmkv的使用詳解

    Android 第三方庫lottie、mmkv的使用詳解

    lottie是Airbnb開源的一個面向 iOS、Android、React Native 的動畫庫,能實現精美、復雜的動畫效果,本文通過實例代碼給大家介紹Android 第三方庫lottie、mmkv的使用,感興趣的的朋友一起看看吧
    2021-04-04
  • Android實現一個比相冊更高大上的左右滑動特效(附源碼)

    Android實現一個比相冊更高大上的左右滑動特效(附源碼)

    這篇文章主要介紹了Android實現一個比相冊更高大上的左右滑動特效(附源碼),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • Android開發(fā)手冊Button實現selector選擇器

    Android開發(fā)手冊Button實現selector選擇器

    這篇文章主要為大家介紹了Android開發(fā)手冊Button實現selector選擇器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06

最新評論

墨玉县| 平谷区| 金山区| 河东区| 崇阳县| 濉溪县| 广南县| 时尚| 嘉祥县| 高碑店市| 兴山县| 永城市| 武冈市| 夹江县| 松潘县| 莒南县| 新宁县| 胶州市| 平乡县| 遂宁市| 丽水市| 洛隆县| 伊春市| 银川市| 连江县| 白朗县| 汾西县| 济阳县| 铜川市| 凉城县| 获嘉县| 肇源县| 陆川县| 长武县| 太仆寺旗| 苗栗县| 瓮安县| 永和县| 威海市| 惠东县| 哈密市|